From 767955685a551b0daca5af6c653fc53d3a181736 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 7 Jun 2022 19:01:33 +0200 Subject: [PATCH] Better signature processing --- src/client/component/arxan.cpp | 45 ++++++++++++++-------------------- src/common/utils/signature.cpp | 18 +++++++------- src/common/utils/signature.hpp | 34 ++++--------------------- 3 files changed, 33 insertions(+), 64 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index 409a229b..1a73f996 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -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(get_text_section().first) && addr <= reinterpret_cast( + 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(); diff --git a/src/common/utils/signature.cpp b/src/common/utils/signature.cpp index 28c2a1d1..90cf7d15 100644 --- a/src/common/utils/signature.cpp +++ b/src/common/utils/signature.cpp @@ -76,15 +76,15 @@ namespace utils::hook } } - std::vector 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 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 result; + std::vector 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 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 result; + std::vector 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 result; + std::vector result; std::vector 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); diff --git a/src/common/utils/signature.hpp b/src/common/utils/signature.hpp index a3728327..054e6b45 100644 --- a/src/common/utils/signature.hpp +++ b/src/common/utils/signature.hpp @@ -7,33 +7,9 @@ namespace utils::hook class signature final { public: - class signature_result - { - public: - signature_result(std::vector&& matches) : matches_(std::move(matches)) - { - } + using signature_result = std::vector; - [[nodiscard]] uint8_t* get(const size_t index) const - { - if (index >= this->count()) - { - throw std::runtime_error("Invalid index"); - } - - return reinterpret_cast(this->matches_[index]); - } - - [[nodiscard]] size_t count() const - { - return this->matches_.size(); - } - - private: - std::vector 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 process_range(uint8_t* start, size_t length) const; - std::vector process_range_linear(uint8_t* start, size_t length) const; - std::vector 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; };