作者:溟晨
对一款名叫 QQ第六感的软件,进行破解,这款软件可以找出局域网内在线的主机正在使用的QQ,功能还是挺不错的,但是这个软件的作者很。。。居然要把钱。。正好,我最近也在学习脱壳和破解,于是拿它练练手
++++++++++++++++++++++++++++++++++++++++++++++++
未破解前的情况,后面几位被隐藏了。。相当操蛋。。
+++++++++++++++++++++++++++++++++++++++++++++++
首先脱壳,用PEID查壳为UPX,这个壳很简单,用一个ESP定律(堆栈平衡)就可以来到入口点了
===================================================================
外壳入口情况
0047AE50 > $ 60 pushad
0047AE51 . BE 00B04400 mov esi, SixthSen.0044B000
0047AE56 . 8DBE 0060FBFF lea edi, dword ptr [esi+FFFB6000]
对外壳程序操作的第一次堆栈,下断点,如下
hr 0x12ffc0
然后让程序跑起来,会在0047AFF7 地址停下来
0047AFF6 . 61 popad
0047AFF7 . 8D4424 80 lea eax, dword ptr [esp-80]
0047AFFB > 6A 00 push 0
0047AFFD . 39C4 cmp esp, eax
0047AFFF .^ 75 FA jnz short SixthSen.0047AFFB
0047B001 . 83EC 80 sub esp, -80
0047B004 .- E9 29D1FAFF jmp SixthSen.00428132 这里有一个大跳,入口地址就是这个,然后用内存dump程序,进行dump,但是我遇到一个问题,后来虽然解决了,但是还是感觉不太明白。。。疑问在看雪论坛,发了求助。。。http://bbs.pediy.com/showthread.php?t=148147
好了,壳已经脱了,下面开始破解
我想到的切入点,在点击IP进行监听QQ号的时候,会弹出一个消息框
所以我程序运行后,下断点 bp MessageBoxA
在这函数下断点后,当在按下那个IP,进行监听QQ号的时候,就会停在MessageBoxA函数体内,按CTRL+F9返回上层调用
00411ED5 3BC3 cmp eax, ebx
00411ED7 75 04 jnz short 脱壳后.00411EDD
00411ED9 33C0 xor eax, eax
00411EDB EB 27 jmp short 脱壳后.00411F04
00411EDD 895D FC mov dword ptr [ebp-4], ebx
00411EE0 FF75 14 push dword ptr [ebp+14]
00411EE3 FF75 10 push dword ptr [ebp+10]
00411EE6 FF75 0C push dword ptr [ebp+C]
00411EE9 FF75 08 push dword ptr [ebp+8]
00411EEC FF15 F4B34300 call near dword ptr [<&USER32.Message>; USER32.MessageBoxA
+++++++++++
注意一般的一个函数体反汇编后都有
push ebp
mov ebp,esp
sub esp,50 之类的
------- <--esp栈顶
.......
........开辟的临时空间
......
------- <--ebp
原ebp的值
-------
调用函数的地址
-------
参数1
------
参数2
-------
.......
.....
所以这些红色的堆栈取值,都是上层函数传递来的参数,也就是说,还要按ctrl+F9返回上一层
00413838 /EB 03 jmp short 脱壳后.0041383D
0041383A |8B4E 20 mov ecx, dword ptr [esi+20]
0041383D \FF7424 10 push dword ptr [esp+10]
00413841 50 push eax
00413842 FF7424 10 push dword ptr [esp+10]
00413846 51 push ecx
00413847 E8 5EE6FFFF call 脱壳后.00411EAA
这层代码,我也觉得没有必须分析,因为,我感觉一般用户调用的函数接口,都会压入一个常量地址做参数。。。(接触破解时间才几天,经验可能有误)
所以,我觉得,这个还是接口层,不用用户层,于是我继续ctrl+F9返回
+++++
004057FA 39BE 600C0000 cmp dword ptr [esi+C60], edi
00405800 75 0E jnz short 脱壳后.00405810
00405802 57 push edi
00405803 57 push edi
00405804 68 48D24300 push 脱壳后.0043D248
00405809 8BCE mov ecx, esi
0040580B E8 0FE00000 call 脱壳后.0041381F
我看到一个push 0043D248 后,感觉需要开始分析了,然后查看数据段0043D248,发现了
0043D248 C4 E3 CA B9 D3 C3 B5 C4 CA C7 CE B4 D7 A2 B2 E1 你使用的是未注册
0043D258 B0 E6 B1 BE A3 A1 D4 DA BC E0 CC FD CA B1 D6 BB 版本!在监听时只
0043D268 C4 DC B5 C3 B5 BD 51 51 BA C5 B5 C4 C7 B0 CE E5 能得到QQ号的前五
0043D278 CE BB 00 00 B4 ED CE F3 A3 BA B4 CB CA CA C5 E4 位..错误:此适配
0043D288 C6 F7 B2 BB BF C9 D3 C3 2C C7 EB D1 A1 D4 F1 C6 器不可用,请选择
0043D298 E4 CB FC CA CA C5 E4 C6 F7 A3 A1 00 7D 00 00 00 渌逝淦鳎?}...
所以,开始分析这一层,
看了一圈,我就觉得这个cmp dword ptr [esi+C60], edi
比较可疑,感觉[esi+C60]是一个flag标志位,事实上就是如此,我在jnz short 脱壳后.00405810,修改标志位 Z=0,结果就不弹出显示对话框了,然后,我试着直接置位[esi+C60],然后跑起程序,结果未注册的功能限制就拿掉了。还是比较幸运的。。。
但是我发现一个问题,ESI里的值,是不断变化着的,不可能每次打开程序,都要自己重新找一次那个地址,我必须要找到一个不变的量
然后我靠着以前搜索内存的经验,得到了 [[0x404832]+c60],这个表达式可以得到需要置位的内存地址
转为汇编代码为
mov eax, dword ptr [0x404832]
inc dword ptr [eax+0xC60]
然后,我就开始想如何把这个思想应用起来,一开始我把这段代码嵌入到程序的代码段空白部分,OEP指向这段新代码,在代码尾部在加入一个JMP OEP,然后,我发现不行,因为程序在随后得到控制权后会初始化那段地址。。随后我发现程序每次启动的时候,会弹出一个对话框
于是,我就想把显示这段对话框的代码,换成我自己的代码。。。。移花接木。。
在程序开始前,下断点,bp MessageBoxA,断下来后,返回2次,出现如下
00406C91 6A 40 push 40
00406C93 68 BCDF4300 push haha.0043DFBC
00406C98 68 A8DE4300 push haha.0043DEA8
00406C9D 8BCE mov ecx, esi
00406C9F E8 7BCB0000 call haha.0041381F
由于有一个寄存器的操作,我担心直接拿掉有影响,于是替换如下
00406C91 8BCE mov ecx, esi
00406C93 A1 32484000 mov eax, dword ptr [404832]
00406C98 FF80 600C0000 inc dword ptr [eax+C60]
00406C9E 90 nop
00406C9F 90 nop
00406CA0 90 nop
00406CA1 90 nop
00406CA2 90 nop
00406CA3 90 nop
注意代码的修改,必须在程序,还没运行前修改,要么直接修改文件,或者在OD载入后,转到那个地址修改,在dump
所有的工作都做完了了,呵呵,功能限制已经拿掉了。。。。每次使用的时候直接打开就是破解好的。。。
_____________________________________
8楼,还有我另一个更简单的方法
——————————————————————————
另外7楼sierra也有一个更好的办法
互相学习,互相成长
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课