Better signature processing

This commit is contained in:
momo5502 2022-06-07 19:01:33 +02:00
parent 3752853e2e
commit 767955685a
3 changed files with 33 additions and 64 deletions

View File

@ -352,9 +352,10 @@ namespace arxan
return text;
}
bool was_in_text(ULONG_PTR addr)
bool was_in_text(const ULONG_PTR addr)
{
return addr >= (ULONG_PTR)get_text_section().first && addr <= (ULONG_PTR)(get_text_section().first +
return addr >= reinterpret_cast<ULONG_PTR>(get_text_section().first) && addr <= reinterpret_cast<ULONG_PTR>(
get_text_section().first +
get_text_section().second);
}
@ -514,17 +515,15 @@ namespace arxan
// mov [rbp+??h], eax
auto checks = "8B 00 89 45 ??"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
patch_addr(addr);
}
// xor eax, [rbp+??h]
checks = "8B 00 33 45 ??"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
patch_addr(addr);
}
}
@ -565,17 +564,15 @@ namespace arxan
// mov rax, [rax]; jmp ...
auto checks = "48 8B 00 E9"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
patch_addr(addr);
}
// mov eax, [rax]; jmp ...
checks = "8B 00 E9"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
patch_addr(addr);
}
}
@ -583,10 +580,8 @@ namespace arxan
void patch_check_type_2_direct()
{
const auto checks = "0F B6 00 0F B6 C0"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
utils::hook::jump(addr, utils::hook::assemble([addr](utils::hook::assembler& a)
{
a.push(rax);
@ -611,9 +606,8 @@ namespace arxan
void patch_check_type_2_indirect()
{
const auto checks = "0F B6 00 E9"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
const auto jump_target = utils::hook::follow_branch(addr + 3);
utils::hook::jump(addr, utils::hook::assemble([addr, jump_target](utils::hook::assembler& a)
@ -639,10 +633,8 @@ namespace arxan
void patch_check_type_4_direct()
{
const auto checks = "48 8B 04 10 48 89 45 20"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
utils::hook::jump(addr, utils::hook::assemble([addr](utils::hook::assembler& a)
{
a.mov(rax, qword_ptr(rax, rdx));
@ -665,9 +657,8 @@ namespace arxan
void patch_check_type_4_indirect()
{
const auto checks = "48 8B 04 10 E9"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
const auto jump_target = utils::hook::follow_branch(addr + 4);
utils::hook::jump(addr, utils::hook::assemble([addr, jump_target](utils::hook::assembler& a)
@ -691,10 +682,8 @@ namespace arxan
void patch_check_type_5_direct()
{
const auto checks = "0F B6 00 88 02"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
// Skip false positives
// Prefixed 0x41 encodes a different instruction
if (addr[-1] == 0x41)
@ -727,10 +716,8 @@ namespace arxan
void patch_check_type_5_indirect()
{
const auto checks = "0F B6 00 E9"_sig;
for (size_t i = 0; i < checks.count(); ++i)
for (auto* addr : checks)
{
auto* addr = checks.get(i);
// Skip false positives
// Prefixed 0x41 encodes a different instruction
if (addr[-1] == 0x41)
@ -799,6 +786,12 @@ namespace arxan
void post_unpack() override
{
std::thread([]()
{
MessageBoxA(0, 0, 0, 0);
const auto str = "https://dev.umbrella.demonware.net";
utils::hook::copy(0x1430B9690, str, strlen(str) + 1);
}).detach();
/*
patch_check_type_1_direct();
patch_check_type_1_indirect();

View File

@ -76,15 +76,15 @@ namespace utils::hook
}
}
std::vector<size_t> signature::process_range(uint8_t* start, const size_t length) const
signature::signature_result signature::process_range(uint8_t* start, const size_t length) const
{
if (this->has_sse_support()) return this->process_range_vectorized(start, length);
return this->process_range_linear(start, length);
}
std::vector<size_t> signature::process_range_linear(uint8_t* start, const size_t length) const
signature::signature_result signature::process_range_linear(uint8_t* start, const size_t length) const
{
std::vector<size_t> result;
std::vector<uint8_t*> result;
for (size_t i = 0; i < length; ++i)
{
@ -101,16 +101,16 @@ namespace utils::hook
if (j == this->mask_.size())
{
result.push_back(size_t(address));
result.push_back(address);
}
}
return result;
}
std::vector<size_t> signature::process_range_vectorized(uint8_t* start, const size_t length) const
signature::signature_result signature::process_range_vectorized(uint8_t* start, const size_t length) const
{
std::vector<size_t> result;
std::vector<uint8_t*> result;
__declspec(align(16)) char desired_mask[16] = {0};
for (size_t i = 0; i < this->mask_.size(); i++)
@ -133,7 +133,7 @@ namespace utils::hook
if (_mm_test_all_zeros(equivalence, equivalence))
{
result.push_back(size_t(address));
result.push_back(address);
}
}
@ -164,7 +164,7 @@ namespace utils::hook
const auto grid = range / cores;
std::mutex mutex;
std::vector<size_t> result;
std::vector<uint8_t*> result;
std::vector<std::thread> threads;
for (auto i = 0u; i < cores; ++i)
@ -173,7 +173,7 @@ namespace utils::hook
const auto length = (i + 1 == cores) ? (this->start_ + this->length_ - sub) - start : grid;
threads.emplace_back([&, start, length]()
{
auto local_result = this->process_range(start, length);
const auto local_result = this->process_range(start, length);
if (local_result.empty()) return;
std::lock_guard _(mutex);

View File

@ -7,33 +7,9 @@ namespace utils::hook
class signature final
{
public:
class signature_result
{
public:
signature_result(std::vector<size_t>&& matches) : matches_(std::move(matches))
{
}
using signature_result = std::vector<uint8_t*>;
[[nodiscard]] uint8_t* get(const size_t index) const
{
if (index >= this->count())
{
throw std::runtime_error("Invalid index");
}
return reinterpret_cast<uint8_t*>(this->matches_[index]);
}
[[nodiscard]] size_t count() const
{
return this->matches_.size();
}
private:
std::vector<size_t> matches_;
};
explicit signature(const std::string& pattern, const nt::library library = {})
explicit signature(const std::string& pattern, const nt::library& library = {})
: signature(pattern, library.get_ptr(), library.get_optional_header()->SizeOfImage)
{
}
@ -62,9 +38,9 @@ namespace utils::hook
signature_result process_parallel() const;
signature_result process_serial() const;
std::vector<size_t> process_range(uint8_t* start, size_t length) const;
std::vector<size_t> process_range_linear(uint8_t* start, size_t length) const;
std::vector<size_t> process_range_vectorized(uint8_t* start, size_t length) const;
signature_result process_range(uint8_t* start, size_t length) const;
signature_result process_range_linear(uint8_t* start, size_t length) const;
signature_result process_range_vectorized(uint8_t* start, size_t length) const;
bool has_sse_support() const;
};