cp的小屋

not yet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

    用Nvidia的PerfHud剖析Direct3D程序有两个关键步骤,一是找到CreateDevice()的调用位置,二是修改传入CreateDevice()的前两个参数使之满足PerfHud的要求,在一般的系统上第一个参数传1,第二个参数传2,也可以将应用程序原来传入的前两个参数分别加一。定位CreateDevice()有两种方式,一是动态跟踪,二是静态分析。动态跟踪就是用调试器起动应用程序,在D3d9.dll中的CreateDevice()函数处下断点。动态跟踪具有速度快、定位准确的特点,是首选。但很多时候网络游戏的客户端都是通过另一个程序起动的(比如自动更新程序),无法由调试器直接起动,也就无法动态跟踪,这时可以考虑静态分析的方法,后面本文会有详细介绍。

    下面我们以《寻仙》为例看看这个破解过程。

    首先看下《寻仙》的起动过程。最先执行的是patcher.exe,完成自动更新和参数设定的工作。然后patcher.exe起动QQLogin.exe进行账号和密码的验证。接着QQLogin.exe起动《寻仙》的主程序tty3d.exe。由于patcher.exe是以独立进程方式起动QQLogin.exe,而QQLogin.exe以子进程方式起动tty3d.exe,这就导致用PerfHud起动patcher.exe无法正确挂接tty3d.exe进行分析,只有用PerfHud直接起动QQLogin.exe或者tty3d.exe才行。由于tty3d.exe可能依赖于QQLogin.exe验证账号和密码后服务器发回的登录身份证书才能正确起动,所以用PerfHud直接起动tty3d.exe的难度很大。我们将希望寄托于直接起动QQLogin.exe。双击QQLogin.exe的图标会弹出一个对话框,提示QQLogin.exe需要通过patcher.exe起动,无法独立起动。为了弄清QQLogin.exe和patcher.exe之间的关系,我们用IDA打开patcher.exe,并在反汇编窗口搜索“winexec”,定位到WinExec函数(见下图),这是windows系统用于起动另一个进程的函数。在此下断点,执行程序并在断点处停下,观察edi寄存器指向的内存块内容,可以发现这正是传给WinExec函数的参数,内容是“QQLogin.exe -g 119.147.16.146:3100,沙子洲”。这正是起动QQLogin.exe的指令,可以猜测后面的参数就是QQLogin.exe起动的必要条件。于是建立一个QQLogin.exe的快捷方式,将“-g 119.147.16.146:3100,沙子洲”作为起动参数。接着用PerfHud起动此快捷方式,发现PerfHud正确挂接了《寻仙》的主窗口。至此我们扫清正式破解前的障碍,可以跳过patcher.exe直接起动QQLogin.exe了。

    用IDA打开《寻仙》的图形模块pge_device.dll,在汇编窗口搜索“device”或者搜索“+40h]”。很快定位到地址1000503E,发现如下指令“call dword ptr [edi+40h]”(见下图)。40h是CreateDevice()函数在IDirect3D9接口中的偏移地址,结合附近的“CD3D9Device::InitDevice()”字符串,使1000503E处的这条指令成为我们的重点怀疑对象,这应该就是《寻仙》主程序调用CreateDevice()函数的地方。至此我们完成了第一个关键任务,定位到了CreateDevice()函数的调用位置,下面的任务是修改传给CreateDevice()函数的前两个参数。

    CreateDevice()调用前的三条指令如下:
    push edx
    push ecx
    push eax
    熟悉C++的朋友都知道最后一条push eax指令是压入this指针,倒数第二和第三条指令分别压入CreateDevice()的第一和第二个参数,也就是我们要修改的参数。我们的任务是将这两个参数分别加一后再压入堆栈。要修改参数必须修改附近的指令或者增加新的指令,我们考虑在将参数压栈前用inc edx和inc ecx分别将两个参数加一。要加入新的指令原位修改肯定没有足够的空间,我们需要跳转到别处,完成修改后再跳回执行CreateDevice()。我们向后找,发现地址10005193处因为内存对齐留下的一段13字节的空白区(见下图),这应该足够安排所需要的指令了。

    回到1000503E处,我们在10005038处写入指令“jmp loc_10005193”,覆盖掉下面四条指令(见下图)
    push ecx
    mov ecx, [esi]
    push edx
    push ecx


    这条指令使代码跳转到地址10005193处(之前找到的空白处),我们可以在地址10005193处重新执行被覆盖掉的指令,并在将CreateDevice()的前两个参数压入堆栈前将它们分别加一,然后再跳回1000503D处继续执行(见下图)。

    至此我们完成了对pge_device.dll的修改,别忘了把修改后的pge_device.dll存盘。

    重新用PerfHud起动QQLogin.exe进入主程序,PerfHud的Logo出现在眼前,表明我们已经成功破解了pge_device.dll,可以用PerfHud剖析《寻仙》的绘制过程了。

posted on 2008-11-21 22:23  cproom  阅读(5865)  评论(18编辑  收藏  举报