zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Amlegit - amlegit.com 的逆向工程(1)

2023-03-15 22:03:15 时间

Amlegit 是与 HWID 欺骗器捆绑在一起的 Apex 传奇作弊软件,其用户群略高于三千用户。作弊本身提供了一个 2d 框 esp、无声瞄准和其他一些功能。正如您将在这篇广泛的文章中看到的那样,这个作弊只不过是公开发布的漏洞利用和源代码的粘贴。如下所示的通信方式是一个系统驱动程序的基本IOCTL钩子。

启动器


我将要谈论的发射器实际上是他们的“第二阶段”发射器。启动器的第一阶段下载并将所有 QT 文件/可执行文件放在一个随机临时文件夹中,然后启动第二个启动器。在这个临时文件夹中有三个文件,buffer.dll、inject.dll 和 mmap.dll。所有这些文件都经过 VMP 处理,但它们的导出表仍然可以解析。在 Ida 中打开它们每个都向我展示了至少两个导出(启动和 amlegit 程序员定义的另一个函数)虽然导出表是可解析的,但函数本身却不是,即使在运行时查看函数数据也无法理解。为了让我自己调用这些导出函数,我需要知道调用约定(很可能是 fastcall)、参数和返回类型。这可以通过查看调用这些导出函数的内容来实现。幸运的是,除了 GetDriver(在 inject.dll 转储中引用)之外,第二阶段启动器对所有这些函数都有外部参照。

导出连接采用零参数并返回一个布尔值。该函数在用户态进程和内核驱动程序之间建立通信。

.text:00007FF7D93BA7E1 call export_connect
.text:00007FF7D93BA7E3 test al, al

导出注入需要两个参数,第一个是磁盘上要注入到第二个参数指定的进程中的dll的名称。第二个参数采用窗口的类名。该函数用于将dll注入游戏。

.text:00007FF7D93BABFE ; ---------------------------------------------------------------------------
.text:00007FF7D93BABFE lea rdx, aRespawn001 ; "Respawn001"
.text:00007FF7D93BAC05 lea rcx, aLapexDll ; "lapex.dll"
.text:00007FF7D93BAC0C
.text:00007FF7D93BAC0C loc_7FF7D93BAC0C: ; DATA XREF: sub_7FF7D95E2D10-97C6D↓o
.text:00007FF7D93BAC0C call export_inject_addr ; ExportInject("lapex.dll", "Respawn001");
.text:00007FF7D93BAC0E test al, al

导出负载不带参数并返回一个布尔值。此函数加载 intel lan 驱动程序。(kdmapper 的一部分)。

.text:00007FF7D93BAD9E call export_loader_addr ; ExportLoad()
.text:00007FF7D93BADA0 test al, al

导出映射接受一个参数,它是一个字符指针并返回一个布尔值。此函数用于将未签名的驱动程序映射到内核中。

.text:00007FF7D93BAE03 lea rcx, aDriverSys ; "driver.sys"
.text:00007FF7D93BAE0A call export_map_addr ; ExportMap("driver.sys")
.text:00007FF7D93BAE0C test al, al

映射文件


如上图 mmap.dll 导出了两个函数(包括 dllmain 在内一共三个)。尽管这些函数是从 mmap.dll 导出的,但您将无法解析它们的作用,因为它们被高度虚拟化和混淆。话虽如此,如果我们能够解析对这些函数中任何一个的函数调用,我们很可能能够确定参数和返回类型。

那么如果我们不能解析这些函数在做什么,我们为什么要查看模块内部呢?那么简单地把 mmap.dll 实际上加载 buffer.dll 并调用 GetDriver。这将允许我们查看 GetDriver 的参数和返回类型。

.text:00000000000034FD lea rcx, aBufferDll ; "buffer.dll"
.text:0000000000003504 call cs:GetModuleHandle
.text:000000000000350A xor r12d, r12d
.text:000000000000350D test rax, rax
.text:0000000000003510 jz loc_390E
.text:0000000000003516 lea rdx, aGetdriver ; "GetDriver"
.text:000000000000351D mov rcx, rax ; hModule
.text:0000000000003520 call cs:GetProcAddress_1
.text:0000000000003526 test rax, rax
.text:0000000000003529 jz loc_390E
.text:000000000000352F mov [rsp+0A8h+driver_size], 1
.text:0000000000003537 lea rcx, [rsp+0A8h+driver_size]
.text:000000000000353C call rax
.text:000000000000353E mov r15, rax

让我们分解这个程序集。我们首先看到的是对 GetModuleHandle 的调用。您可以看到 GetModuleHandle 接受一个字符指针,因为我们将本例中的字符串地址“buffer.dll”移动到 rcx(如果您还不知道它是 fastcall 调用约定中用于传递值的第一个寄存器)高达 64 位)。接下来我们看到一个测试 rax,rax。简而言之,这条指令测试 rax 是否为零,然后将结果存储在零标志寄存器中。该测试指令还为我们提供了有关函数返回值(和大小)的非常重要的信息。在 fastcall 中,rax 是包含大小为 64 位或更小的值(字节、字、双字、qword)的返回值的寄存器。通过读取程序集,我们可以知道正在使用整个 64 位数据(这意味着它返回一个 long long)。这符合我们对 GetModuleHandle 的期望,它接受一个指向 ac 样式字符串的长指针并返回一个大小匹配 64 位的值。请记住,HMODULE 可以是 32 位或 64 位,具体取决于其运行环境。

//HMODULE GetModuleHandleA(LPCSTR lpModuleName);

.text:00000000000034FD                 lea     rcx, aBufferDll ; "buffer.dll"
.text:0000000000003504                 call    cs:GetModuleHandle
.text:000000000000350A                 ...
.text:000000000000350D                 test    rax, rax

在我们调用 GetModuleHandle 之后,我们将调用 GetProcAddress_1,它是真正的 GetProcAddress 的包装函数。首先,我们将“GetDriver”的地址移动到 rbx 中,它是用于第二个参数(整数值)的寄存器。然后我们将结果从 GetModuleHandle 移到 rcx 中,正如您现在可能知道的那样,它是第一个整数值参数的寄存器。结果将是 64 位长度,这是由测试和分支操作权推断出来的。它还与 GetProcAddress 的 MSDN 定义一致。

//FARPROC GetProcAddress(HMODULE hModule, LPCSTR  lpProcName);

.text:0000000000003516                 lea     rdx, aGetdriver ; "GetDriver"
.text:000000000000351D                 mov     rcx, rax        ; hModule
.text:0000000000003520                 call    cs:GetProcAddress_1
.text:0000000000003526                 test    rax, rax

现在我们在 rax 中有 GetDriver 的地址,我们将调用它。如果您浏览一下这个程序集,您会假设我们将 1 放入 rcx 但实际上我们正在加载 1 (lea) 的效果地址。所以这告诉 use GetDriver 将指针作为其唯一的参数。返回值也由 rax 的后续操作推断。

//std::uintptr_t GetDriver(unsigned* size);

.text:000000000000352F                 mov     [rsp+0A8h+driver_size], 1
.text:0000000000003537                 lea     rcx, [rsp+0A8h+driver_size]
.text:000000000000353C                 call    rax
.text:000000000000353E                 mov     r15, rax