识别和拦截函数调用

我正在开发一款游戏的发射器。 要拦截游戏的打印文本function。

我不知道包含这个函数的代码是dynamic链接的还是静态的。 所以我甚至不知道函数名称。

我通过微软Detours,Ninject和其他一些人拦截了这个游戏的一些windows-api调用。

但是这个也不在导入表中。

我该怎么做才能赶上这个函数调用? 应该使用哪个分析器? IDA? 这可以怎么做?


编辑:

最后find函数地址。 谢谢,Skino!

试图钩住Detours,注入DLL。 注入DllMain:

typedef int (WINAPI *PrintTextType)(char *, int, float , int); static PrintTextType PrintText_Origin = NULL; int WINAPI PrintText_Hooked(char * a, int b, float c, int d) { return PrintText_Origin(a, b, c , d); } HMODULE game_dll_base; /* game_dll_base initialization goes here */ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(fdwReason==DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hinstDLL); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); PrintText_Origin = (PrintTextType)((DWORD)game_dll_base + 0x6049B0); DetourAttach((PVOID *)&PrintText_Origin , PrintText_Hooked); DetourTransactionCommit(); } } 

它按预期挂钩。 参数a有应该显示的文本。 但是当调用原函数时return PrintText_Origin (a, b, c , d); 应用程序崩溃( http://img.zgserver.com/windows/ohabm.png,http://img.zgserver.com/windows/dfeh4.png )

原始function拆卸:

http://pastebin.com/1Ydg7NED

绕道后:

http://pastebin.com/eM3L8EJh

EDIT2:

绕道后:

http://pastebin.com/GuJXtyad

PrintText_Hooked反汇编http://pastebin.com/FPRMK5qt w3_loader.dll是注入的DLL

我在ASM不好,请告诉什么可能是错的?

要拦截游戏的打印文本功能。

您可以使用调试器进行调查阶段 。 无论是IDA,还是Visual Studio(结合​​HxD)都应该这样做。 使用以下步骤确定功能应该相对容易:

  1. 确定要跟踪其打印的文本的特定片段(例如Hello World!
  2. 在游戏正常打印上面确定的片段之前 ,在任何时候中断游戏执行
  3. 搜索游戏内存中的文本片段查找Unicode或ANSI )。 IDA将允许你做IIRC,就像免费的HxD ( Extras > Open RAM...
  4. 一旦片段地址被识别, 设置一个访问/读取数据断点,这样调试器就可以控制游戏试图读取片段的时间(在显示片段的同时或之前)
  5. 恢复执行,等待数据断点触发
  6. 检查堆栈跟踪并寻找合适的挂钩候选者
  7. 从内存中读取片段直到它被打印,如果你想探索更多的潜在的钩点

†提供的文本不会保持压缩(或者,不管什么原因,加密),直到最后一刻

一旦你完成了调查阶段,你已经确定了你想要注入你的钩子,你有两个选择,当你写你的启动程序

  1. 如果基于上述练习,毕竟您能够识别导出/导入,然后使用任何API挂钩技术
  2. 编辑使用Microsoft Detours,确保您第一次正确识别您正在尝试绕行的函数的调用约定 (cdecl,fastcall,stdcall) ,并使用该调用约定为原始的原型,以及为假人。 看例子 。
  3. 如果没有,你将不得不
    • 使用调试API以编程方式加载游戏
    • 根据您的调查阶段计算钩子地址(或者作为从模块基址的硬编码偏移量,或者通过查找钩子站点周围的指令字节)
    • 设置一个断点
    • 恢复过程
    • 等待断点触发,做任何你必须做的事情
    • 恢复执行, 再次等待下一个触发器,所有这些都是由启动器通过调试API以编程方式完成的

‡能够继续使用游戏的最终补丁版本

在这个阶段,这听起来像你没有什么库函数你试图挂钩的概念,并且你已经声明它不是(至少)导入表中的一个导入的外部函数,这可能意味着函数负责生成文本的内容很可能位于应用程序的.text文件中,您直接拆分或动态加载,文本生成(特别是在游戏中)可能是应用程序的一部分。

根据我的经验,找到难以追踪的代码的最简单的方法是通过在文本显示期间或之前/之后立即停止应用程序,并使用IDA的神话般的调用图函数来确定将其写出的责任大量使用手表和断点!)

仔细查看调用CreateRemoteThread或任何其他常用的动态加载机制,如果你有理由相信这个功能可能是由导入表中没有显示的导出函数提供的。

我强烈建议反对它,但为了完整起见,还可以在系统服务调度表中挂接NtSetInformationThread。 这里是不同Windows版本的表格的好转储。 如果你想自己得到表中的索引,你可以反汇编ntdll.dll中的NtSetInformationThread导出。