天邈汉化组技术
- UID
- 2212282
- 主题
- 3
- 阅读权限
- 40
- 帖子
- 27
- 精华
- 2
- 积分
- 694
- 金钱
- 629
- 荣誉
- 28
- 人气
- 0
- 在线时间
- 4 小时
- 评议
- 0
- 帖子
- 27
- 精华
- 2
- 积分
- 694
- 金钱
- 629
- 荣誉
- 28
- 人气
- 0
- 评议
- 0
|
想来大家应该知道如何脱这种loader了吧。可是这个游戏里面Loader还有一个功能,就是用来判断是否注册的。那么我们来简单的思考Loader判断是否注册的几种可能情况。
1,上面提到了,loader是通过写入进程内存恢复入口点代码的。那么有可能注册后和未注册写入正确的代码是不一样的。
2,还记得CreateProcessA有个CommandLine的参数么?所以程序可能在判断注册以后,使用命令行参数来启动游戏。当然这种方式比较容易被攻破。
3,注册前后向进程写入的其他数据不同。
上面就是几种可能的情况。在验证之前,我们先来跳过注册验证,即让loader认为我们已经注册了游戏。注册游戏的部分我是分析老李给的破解补丁知道的。下面是补丁代码。分析如下:
GetProcAddress这个函数需要的参数有两个,一个是函数名称字符串,另一个是所在DLL的句柄。如果成功就返回函数的实际地址。
00441039 > B8 B4804200 MOV EAX,<&KERNEL32.GetProcAddress> 把IAT中GetProcAddress这个函数的地址传递给eax
0044103E 8B18 MOV EBX,DWORD PTR DS:[EAX];传递GetProcAddress函数地址给EBX
00441040 8138 5A104400 CMP DWORD PTR DS:[EAX],EvilInva.0044105A 比较GetProcAddress的函数地址是不是0044105A
00441046 74 0C JE SHORT EvilInva.00441054 是就跳到00441054
00441048 891D 35104400 MOV DWORD PTR DS:[441035],EBX 不是的话,保存GetProcAddress函数原来的地址到441035中
0044104E C700 5A104400 MOV DWORD PTR DS:[EAX],EvilInva.0044105A;把0044105A放到GetProcAddress的IAT中
00441054 68 6FCE4100 PUSH EvilInva.0041CE6F 程序原来的OEP压栈
00441059 C3 RETN 返回到OEP开始执行程序。
从上面可以看出,这部分的代码就是Hookz住GetProcAddress这个函数。替换为补丁代码中的函数。下面就是替换的函数:
0044105A 60 PUSHAD 保存寄存器环境
0044105B B9 20000000 MOV ECX,20 初始化计数器为20H,32D
00441060 8D3D 00104400 LEA EDI,DWORD PTR DS:[441000] 把函数名称radll_HasTheProductBeenPurchased的地址传递给EDI
00441066 8B7424 28 MOV ESI,DWORD PTR SS:[ESP+28] 把原来的GetProcAddress的函数名称的地址传递给ESI
0044106A F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:> 循环比较是否相同
0044106C 74 1A JE SHORT EvilInva.00441088 相等就跳到00441088,这就数HOOK的函数。
0044106E B9 0C000000 MOV ECX,0C 不相等的话继续比较,初始化计数器为0CH,12D
00441073 8D3D 21104400 LEA EDI,DWORD PTR DS:[441021] 把函数名称radll_GetUnlockCode的地址传递给EDI
00441079 8B7424 28 MOV ESI,DWORD PTR SS:[ESP+28] 把原来的GetProcAddress的函数名称的地址传递给ESI
0044107D F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:> 循环比较是否相同
0044107F 74 07 JE SHORT EvilInva.00441088 相等就跳到00441088,这就是HOOK的函数。
00441081 61 POPAD 如果都不是的话就恢复寄存器和堆栈,然后跳回GetProcAddress函数,正常执行
00441082 FF25 35104400 JMP DWORD PTR DS:[441035] 还记得这里面保存的是GetProcAddress的函数地址么
上面的代码就是来判断是不是需要处理的函数。如果不是的话就跳回正常的GetProcAddress执行。如果是的话,就返回00441091这个函数地址。
00441088 61 POPAD 恢复堆栈和寄存器。
00441089 B8 91104400 MOV EAX,EvilInva.00441091 返回函数地址为00441091
0044108E C2 0800 RETN 8
00441091 33C0 XOR EAX,EAX EAX清零
00441093 40 INC EAX EAX+1
00441094 C3 RETN 返回
看完的所有的代码大家应该明白了,radll_HasTheProductBeenPurchased 和radll_GetUnlockCode这两个函数是用来判断注册的。上面的代码就是用来HOOK这两个函数,程序一旦调用这两个函数,始终返回1.
这段代码补上去以后游戏就显示注册了。那么现在我们就要验证上面的猜想。
1,大家可以用前面的方法,比较两种情况下的代码。发现并没有什么不同。
2,第二种可能性也容易排除。
那就剩第三种可能了。
Loader通过WriteProcessMemory函数写完数据以后,通过ResumeThread函数来恢复被挂起的进程。这样的话程序就运行了。程序运行的时候会初始化一些变量,这样就回导致我们从程序虚拟内存中拿出的数据不是原始的。所以为了方式程序运行初始化,我们需要做些手脚。
运行补丁过的Loader,下Bp WriteProcessMemory 中断后,找到要写入的数据所在的位置。
下图显示的就是这个地方。之前提到过,补丁数据是从文件的入口点处开始补丁的,那么也就是说图中所示的6A 74应该就是EP处的头两个字节。我们把这两个自己改成EB FE.这样的话,在恢复进程后,程序会在入口点处于死循环状态。这样我们就能从内存中DUMP处原始的数据了。
DUMP出来的文件不用修正,用LordPE保存里面的.data和.data1两个区段。并替换把上节修复过的游戏程序中的相应的区段替换掉。 然后重建下PE。果然不再提示未注册了。这样就把程序完全从Loader中解放出来并破解了!
附加破解补丁。稍后贴出完整的网盘下载地址!
[ 本帖最后由 ghgzhilian 于 2009-1-8 19:10 编辑 ] |
附件: 你需要登录才可以下载或查看附件。没有帐号?注册
-
总评分: 金钱 + 30
+ 5
查看全部评分
|