More arxan patches

This commit is contained in:
momo5502 2022-05-30 18:14:12 +02:00
parent cda5d668ad
commit 0a841e2f49
2 changed files with 128 additions and 28 deletions

View File

@ -362,22 +362,25 @@ namespace arxan
uint64_t get_integrity_data_qword(const uint8_t* address) 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); const auto og_data = utils::hook::query_original_data(address, 8);
return *reinterpret_cast<const uint64_t*>(og_data.data()); return *reinterpret_cast<const uint64_t*>(og_data.data());
} }
uint32_t get_integrity_data_dword(const uint8_t* address) 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); const auto og_data = utils::hook::query_original_data(address, 4);
return *reinterpret_cast<const uint32_t*>(og_data.data()); return *reinterpret_cast<const uint32_t*>(og_data.data());
} }
uint8_t get_integrity_data_byte(const uint8_t* address) 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); const auto og_data = utils::hook::query_original_data(address, 1);
return og_data[0]; return og_data[0];
} }
void patch_check_type_1_direct() void patch_check_type_1_direct()
{ {
auto patch_addr = [](uint8_t* addr) auto patch_addr = [](uint8_t* addr)
@ -414,7 +417,7 @@ namespace arxan
// mov [rbp+??h], eax // mov [rbp+??h], eax
auto checks = "8B 00 89 45 ??"_sig; 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); auto* addr = checks.get(i);
patch_addr(addr); patch_addr(addr);
@ -443,7 +446,7 @@ namespace arxan
a.mov(rcx, rax); a.mov(rcx, rax);
if(rex_prefixed) if (rex_prefixed)
{ {
a.call_aligned(get_integrity_data_dword); a.call_aligned(get_integrity_data_dword);
@ -465,7 +468,7 @@ namespace arxan
// mov rax, [rax]; jmp ... // mov rax, [rax]; jmp ...
auto checks = "48 8B 00 E9"_sig; 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); auto* addr = checks.get(i);
patch_addr(addr); 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) for (size_t i = 0; i < checks.count(); ++i)
{ {
auto* addr = checks.get(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; const auto checks = "48 8B 04 10 48 89 45 20"_sig;
for (size_t i = 0; i < checks.count(); ++i) 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; const auto checks = "0F B6 00 88 02"_sig;
for (size_t i = 0; i < checks.count(); ++i) for (size_t i = 0; i < checks.count(); ++i)
@ -543,7 +600,7 @@ namespace arxan
// Skip false positives // Skip false positives
// Prefixed 0x41 encodes a different instruction // Prefixed 0x41 encodes a different instruction
if(addr[-1] == 0x41) if (addr[-1] == 0x41)
{ {
continue; 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 class component final : public component_interface
{ {
public: public:
@ -608,13 +702,15 @@ namespace arxan
void post_unpack() override void post_unpack() override
{ {
/*
patch_check_type_1_direct(); patch_check_type_1_direct();
patch_check_type_1_indirect(); patch_check_type_1_indirect();
patch_check_type_2(); patch_check_type_2_direct();
patch_check_type_4(); patch_check_type_2_indirect();
patch_check_type_5(); 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 void pre_destroy() override

View File

@ -16,11 +16,11 @@ namespace splash
void enable_dpi_awareness() void enable_dpi_awareness()
{ {
const utils::nt::library user32{ "user32.dll" }; const utils::nt::library user32{"user32.dll"};
const auto set_dpi = user32 const auto set_dpi = user32
? user32.get_proc<BOOL(WINAPI*)(DPI_AWARENESS_CONTEXT)>( ? user32.get_proc<BOOL(WINAPI*)(DPI_AWARENESS_CONTEXT)>(
"SetProcessDpiAwarenessContext") "SetProcessDpiAwarenessContext")
: nullptr; : nullptr;
if (set_dpi) if (set_dpi)
{ {
set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
@ -40,15 +40,7 @@ namespace splash
void pre_start() override void pre_start() override
{ {
if(this->window_) this->draw_frame();
{
MSG msg{};
while (PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
} }
void pre_destroy() override void pre_destroy() override
@ -81,6 +73,16 @@ namespace splash
HWND window_{}; HWND window_{};
HANDLE image_{}; 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 void destroy() const
{ {
if (this->window_ && IsWindow(this->window_)) if (this->window_ && IsWindow(this->window_))
@ -144,7 +146,9 @@ namespace splash
SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left, SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, SWP_NOZORDER); 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); ShowWindow(this->window_, SW_SHOW);
UpdateWindow(this->window_); UpdateWindow(this->window_);