在注入的 DLL 中绕过 ASLR¶
同样,由于代码已注入,无需向游戏注入线程来获取基址。相反,你可以直接调用 GetModuleHandle(),像这样:
获取基址的更快方法是利用游戏的 FS 内存段,这是注入代码获得的另一个超能力。这个内存段指向称为线程环境块(TEB)的结构,TEB 中 0x30 字节处是指向进程环境块(PEB)结构的指针。这些结构由操作系统使用,包含大量关于当前线程和当前进程的数据,但我们只对主模块的基址感兴趣,它存储在 PEB 中 0x8 字节处。使用内联汇编,你遍历结构获取 newBase,像这样:
DWORD newBase;
__asm {
MOV EAX, DWORD PTR FS:[0x30]
MOV EAX, DWORD PTR DS:[EAX+0x8]
MOV newBase, EAX
}
第一条命令把 PEB 地址存储在 EAX 中,第二条命令读取主模块的基址并存储在 EAX 中。最后一条命令把 EAX 复制到 newBase。