From 0a841e2f493c741b40aa634d0759086baae1bd17 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 30 May 2022 18:14:12 +0200 Subject: [PATCH] More arxan patches --- src/client/component/arxan.cpp | 124 ++++++++++++++++++++++++++++---- src/client/component/splash.cpp | 32 +++++---- 2 files changed, 128 insertions(+), 28 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index 7454d4b1..2ec2fdbb 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -362,22 +362,25 @@ namespace arxan uint64_t get_integrity_data_qword(const uint8_t* address) { + OutputDebugStringA(utils::string::va("8 bytes -> %p", address)); const auto og_data = utils::hook::query_original_data(address, 8); return *reinterpret_cast(og_data.data()); } uint32_t get_integrity_data_dword(const uint8_t* address) { + OutputDebugStringA(utils::string::va("4 bytes -> %p", address)); const auto og_data = utils::hook::query_original_data(address, 4); return *reinterpret_cast(og_data.data()); } uint8_t get_integrity_data_byte(const uint8_t* address) { + OutputDebugStringA(utils::string::va("1 bytes -> %p", address)); const auto og_data = utils::hook::query_original_data(address, 1); return og_data[0]; } - + void patch_check_type_1_direct() { auto patch_addr = [](uint8_t* addr) @@ -414,7 +417,7 @@ namespace arxan // mov [rbp+??h], eax auto checks = "8B 00 89 45 ??"_sig; - for(size_t i = 0; i < checks.count(); ++i) + for (size_t i = 0; i < checks.count(); ++i) { auto* addr = checks.get(i); patch_addr(addr); @@ -443,7 +446,7 @@ namespace arxan a.mov(rcx, rax); - if(rex_prefixed) + if (rex_prefixed) { a.call_aligned(get_integrity_data_dword); @@ -465,7 +468,7 @@ namespace arxan // mov rax, [rax]; jmp ... auto checks = "48 8B 00 E9"_sig; - for(size_t i = 0; i < checks.count(); ++i) + for (size_t i = 0; i < checks.count(); ++i) { auto* addr = checks.get(i); patch_addr(addr); @@ -480,9 +483,9 @@ namespace arxan } } - void patch_check_type_2() + void patch_check_type_2_direct() { - const auto checks = "0F B6 00 0F B6 C0 33 45 50 89 45 50"_sig; + const auto checks = "0F B6 00 0F B6 C0"_sig; for (size_t i = 0; i < checks.count(); ++i) { auto* addr = checks.get(i); @@ -508,7 +511,35 @@ namespace arxan } } - void patch_check_type_4() + void patch_check_type_2_indirect() + { + const auto checks = "0F B6 00 E9"_sig; + for (size_t i = 0; i < checks.count(); ++i) + { + 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) + { + a.push(rax); + a.pushad64(); + + a.mov(rcx, rax); + a.call_aligned(get_integrity_data_byte); + + a.mov(rcx, qword_ptr(rsp, 128)); + a.movzx(ecx, al); + a.mov(qword_ptr(rsp, 128), rcx); + + a.popad64(); + a.pop(rax); + + a.jmp(jump_target); + })); + } + } + + 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) @@ -534,7 +565,33 @@ namespace arxan } } - void patch_check_type_5() + void patch_check_type_4_indirect() + { + const auto checks = "48 8B 04 10 E9"_sig; + for (size_t i = 0; i < checks.count(); ++i) + { + 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) + { + a.mov(rax, qword_ptr(rax, rdx)); + a.push(rax); + a.pushad64(); + + a.mov(rcx, rax); + a.call_aligned(get_integrity_data_qword); + a.mov(qword_ptr(rsp, 128), rax); + + a.popad64(); + a.pop(rax); + + a.jmp(jump_target); + })); + } + } + + void patch_check_type_5_direct() { const auto checks = "0F B6 00 88 02"_sig; for (size_t i = 0; i < checks.count(); ++i) @@ -543,7 +600,7 @@ namespace arxan // Skip false positives // Prefixed 0x41 encodes a different instruction - if(addr[-1] == 0x41) + if (addr[-1] == 0x41) { continue; } @@ -569,6 +626,43 @@ 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) + { + auto* addr = checks.get(i); + + // Skip false positives + // Prefixed 0x41 encodes a different instruction + if (addr[-1] == 0x41) + { + continue; + } + + const auto jump_target = utils::hook::follow_branch(addr + 4); + + utils::hook::jump(addr, utils::hook::assemble([addr, jump_target](utils::hook::assembler& a) + { + a.push(rax); + a.pushad64(); + + a.mov(rcx, rax); + a.call_aligned(get_integrity_data_byte); + + a.mov(rcx, qword_ptr(rsp, 128)); + a.movzx(ecx, al); + a.mov(qword_ptr(rsp, 128), rcx); + + a.popad64(); + a.pop(rax); + + a.jmp(jump_target); + })); + } + } + class component final : public component_interface { public: @@ -608,13 +702,15 @@ namespace arxan void post_unpack() override { - /* patch_check_type_1_direct(); patch_check_type_1_indirect(); - patch_check_type_2(); - patch_check_type_4(); - patch_check_type_5(); - */ + patch_check_type_2_direct(); + patch_check_type_2_indirect(); + patch_check_type_4_direct(); + patch_check_type_4_indirect(); + patch_check_type_5_direct(); + patch_check_type_5_indirect(); + MessageBoxA(0, "done", 0, 0); } void pre_destroy() override diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp index c758fec3..85f86f5b 100644 --- a/src/client/component/splash.cpp +++ b/src/client/component/splash.cpp @@ -16,11 +16,11 @@ namespace splash void enable_dpi_awareness() { - const utils::nt::library user32{ "user32.dll" }; + const utils::nt::library user32{"user32.dll"}; const auto set_dpi = user32 - ? user32.get_proc( - "SetProcessDpiAwarenessContext") - : nullptr; + ? user32.get_proc( + "SetProcessDpiAwarenessContext") + : nullptr; if (set_dpi) { set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); @@ -40,15 +40,7 @@ namespace splash void pre_start() override { - if(this->window_) - { - MSG msg{}; - while (PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } + this->draw_frame(); } void pre_destroy() override @@ -81,6 +73,16 @@ namespace splash HWND window_{}; HANDLE image_{}; + void draw_frame() const + { + MSG msg{}; + while (this->window_ && PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + void destroy() const { if (this->window_ && IsWindow(this->window_)) @@ -144,7 +146,9 @@ namespace splash SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); - SetWindowRgn(this->window_, CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 15, 15), TRUE); + SetWindowRgn(this->window_, + CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 15, + 15), TRUE); ShowWindow(this->window_, SW_SHOW); UpdateWindow(this->window_);