首页
社区
课程
招聘
[原创]菜鸟爆破DOC2CHM
发表于: 2010-7-5 13:39 7404

[原创]菜鸟爆破DOC2CHM

2010-7-5 13:39
7404
祭祀的时候你不得不杀一只公鸡什么的,这意味着每次祭祀都得有鸡遭殃。而要加入看雪论坛,你不得不交一篇论文。通常这篇论文来自于对某个软件的破解。即使通过其他方式成为会员,要是一直没有爆破或脱壳什么的,总会觉得比较自卑。而新手一般比较菜,大软件啃不动。正好大多数小的共享软件防范都做得不够强,容易当软柿子捏。这也意味着看雪论坛差不多每添一个新丁,就又有一个无辜的共享软件惨遭蹂躏了
刚好看了几集天草破解的视频,又刚好需要把Word文档转换为CHM帮助文档,于是找到DOC2CHM这个软件。其实网上已经有这个软件的破解版,因此自己再破解一次也不觉得内疚了。
从官方网站下载DOC2CHM的最新版(2.5版),安装后先用PEiD查了一下,VC开发的,没有壳。现在试运行。程序启动后显示的是如下的“Thank you for trying DOC2CHM”对话框

如果点“Try It”按钮,则试用该软件。如果点击“Register”,则进行注册。为了看看程序是怎样验证的,这里点击“Register”,在弹出的输入框中随机输入一个字符串,如下所示:

然后点击“OK”。这时程序显示消息说需要重启验证。如下图所示:

点击确定按钮后,程序就退出了。
这说明程序将在重启后验证我刚才输入的字符串。而这串字符通常程序要么保存在文件中,要么保存在注册表中,当然可能作了加密或变换。打开DOC2CHM的安装目录,快速寻找最新修改的文件。找到名为Reg.ini的文件,打开一看,里面正是刚才输入的字符串。
程序验证的方式已经明确了,开始考虑破解方案。从程序入口开始单步执行效率太低,最好能够很快中断到验证的代码附近。一种方式是从对Reg.ini的访问入手,程序要验证Reg.ini中输入的注册码,很可能会调用CreateFile等API。另外一种方式是在创建对话框的API上断点。还有一种方式是天草讲座推荐的,在显示对话框后再中断进去。笔者采用后面一种方式。
着手调试前我们先整理一下思路。设想一下,程序应该是启动后就对Reg.ini中的注册码进行验证,如果验证码无效或没有,则显示本文前面的那个“Thank you for trying DOC2CHM”对话框,否则这个对话框不会显示,代之以程序正常工作的界面。因此,在对话框处中断的话,应该往前回溯,找到决定这个对话框是否显示的跳转。
现在用OllyDBG(我用的是看雪2010大礼包中提供的OllyICE,汉化界面),启动DOC2CHM,在OllyDBG第一次断点后继续执行。对话框出现,此时程序中断到调试器。注意堆栈视图中的返回地址。在我的OllyICE中,返回地址前有“返回到…”字样,且用红色高亮显示。我们只关注用户领空。这里有3个返回地址,分别是00440894、0043EA7C、0043BFE6。如下图:

目前还不清楚哪个地址与决定“Thank you for trying DOC2CHM”对话框是否显示。我们需要在这几个地方都下断点。这3个地址是返回地址,断点应下在前一个指令上面。为了确定前一指令的地址,我们分别选择这3行,按回车(对应的菜单项是“反汇编窗口中跟随”),在反汇编窗口中稍微往前滚动,就可看到前一条指令,得到的3个地址分别为0044088E、0043EA79、0043BFE1,按F2在上面设置断点。如我们所料,这3处都是CALL指令。
我们在调试器中重新运行程序,同样忽略调试器在程序入口处的断点继续运行。程序在0043BFE1处断下来。不过断点前好像有个窗口一闪而过,这说明我们的断点还不够靠前(如果没看清,可以通过Windows任务栏或SPY++确认窗口是否显示)。我们采用前面同样的方法,在堆栈视图找用户领空的返回地址。这次找到0040E4DF,在其前一个指令地址0040E4DA处下断点(这时原来的3个断点可以去除)。然后重新运行程序直到在0040E4DA处中断。
这次对话框没有显示,说明是否显示“Thank you for trying DOC2CHM”对话框的判断有可能在0040E4DA处调用的函数中(也有可能还需要回溯)。按F7步入这个函数,当前指令地址为该函数的起始地址0043BF05。现在我们分析从0043BF05到上回断点位置0043BFE1的这部分代码。
CPU Disasm
Address   Hex dump          Command                                  Comments
0043BF05  /$  B8 F4D34400   MOV EAX,doc2chm.0044D3F4                 ; doc2chm.0043BF05(guessed void)
0043BF0A  |.  E8 9906FFFF   CALL 0042C5A8
0043BF0F  |.  83EC 18       SUB ESP,18
0043BF12  |.  53            PUSH EBX
0043BF13  |.  56            PUSH ESI
0043BF14  |.  8BF1          MOV ESI,ECX
0043BF16  |.  57            PUSH EDI
0043BF17  |.  8965 F0       MOV DWORD PTR SS:[EBP-10],ESP
0043BF1A  |.  8975 E4       MOV DWORD PTR SS:[EBP-1C],ESI
0043BF1D  |.  8B46 48       MOV EAX,DWORD PTR DS:[ESI+48]
0043BF20  |.  8B7E 44       MOV EDI,DWORD PTR DS:[ESI+44]
0043BF23  |.  8945 E8       MOV DWORD PTR SS:[EBP-18],EAX
0043BF26  |.  E8 57970000   CALL 00445682
0043BF2B  |.  837E 40 00    CMP DWORD PTR DS:[ESI+40],0
0043BF2F  |.  8B58 0C       MOV EBX,DWORD PTR DS:[EAX+0C]
0043BF32  |.  74 1E         JE SHORT 0043BF52
0043BF34  |.  E8 49970000   CALL 00445682
0043BF39  |.  8B58 0C       MOV EBX,DWORD PTR DS:[EAX+0C]
0043BF3C  |.  6A 05         PUSH 5                                   ; /Type = RT_DIALOG
0043BF3E  |.  FF76 40       PUSH DWORD PTR DS:[ESI+40]               ; |Name
0043BF41  |.  53            PUSH EBX                                 ; |hModule
0043BF42  |.  FF15 90F24400 CALL DWORD PTR DS:[<&kernel32.FindResour ; \KERNEL32.FindResourceA
0043BF48  |.  50            PUSH EAX                                 ; /hResource
0043BF49  |.  53            PUSH EBX                                 ; |hModule
0043BF4A  |.  FF15 94F24400 CALL DWORD PTR DS:[<&kernel32.LoadResour ; \KERNEL32.LoadResource
0043BF50  |.  8BF8          MOV EDI,EAX
0043BF52  |>  85FF          TEST EDI,EDI
0043BF54  |.  74 0A         JE SHORT 0043BF60
0043BF56  |.  57            PUSH EDI                                 ; /Arg1
0043BF57  |.  FF15 8CF24400 CALL DWORD PTR DS:[<&kernel32.LockResour ; \kernel32.LockResource
0043BF5D  |.  8945 E8       MOV DWORD PTR SS:[EBP-18],EAX
0043BF60  |>  837D E8 00    CMP DWORD PTR SS:[EBP-18],0
0043BF64  |.  75 08         JNE SHORT 0043BF6E
0043BF66  |.  83C8 FF       OR EAX,FFFFFFFF
0043BF69  |.  E9 E8000000   JMP 0043C056
0043BF6E  |>  8BCE          MOV ECX,ESI
0043BF70  |.  E8 14FFFFFF   CALL 0043BE89                            ; [doc2chm.0043BE89
0043BF75  |.  8945 EC       MOV DWORD PTR SS:[EBP-14],EAX
0043BF78  |.  E8 A20D0000   CALL 0043CD1F                            ; [doc2chm.0043CD1F
0043BF7D  |.  33FF          XOR EDI,EDI
0043BF7F  |.  397D EC       CMP DWORD PTR SS:[EBP-14],EDI
0043BF82  |.  897D E0       MOV DWORD PTR SS:[EBP-20],EDI
0043BF85  |.  74 1E         JE SHORT 0043BFA5
0043BF87  |.  FF75 EC       PUSH DWORD PTR SS:[EBP-14]               ; /hWnd => [ARG.EBP-14]
0043BF8A  |.  FF15 F4F34400 CALL DWORD PTR DS:[<&USER32.IsWindowEnab ; \USER32.IsWindowEnabled
0043BF90  |.  85C0          TEST EAX,EAX
0043BF92  |.  74 11         JE SHORT 0043BFA5
0043BF94  |.  57            PUSH EDI                                 ; /Enable => FALSE
0043BF95  |.  FF75 EC       PUSH DWORD PTR SS:[EBP-14]               ; |hWnd => [ARG.EBP-14]
0043BF98  |.  FF15 CCF44400 CALL DWORD PTR DS:[<&USER32.EnableWindow ; \USER32.EnableWindow
0043BF9E  |.  C745 E0 01000 MOV DWORD PTR SS:[EBP-20],1
0043BFA5  |>  56            PUSH ESI                                 ; /Arg1
0043BFA6  |.  897D FC       MOV DWORD PTR SS:[EBP-4],EDI             ; |
0043BFA9  |.  E8 250D0000   CALL 0043CCD3                            ; \doc2chm.0043CCD3
0043BFAE  |.  FF75 EC       PUSH DWORD PTR SS:[EBP-14]               ; /Arg1 => [ARG.EBP-14]
0043BFB1  |.  E8 6B080000   CALL 0043C821                            ; \doc2chm.0043C821
0043BFB6  |.  53            PUSH EBX                                 ; /Arg3
0043BFB7  |.  50            PUSH EAX                                 ; |Arg2
0043BFB8  |.  FF75 E8       PUSH DWORD PTR SS:[EBP-18]               ; |Arg1 => [ARG.EBP-18]
0043BFBB  |.  8BCE          MOV ECX,ESI                              ; |
0043BFBD  |.  E8 54FCFFFF   CALL 0043BC16                            ; \doc2chm.0043BC16
0043BFC2  |.  3BC7          CMP EAX,EDI
0043BFC4  |.  74 52         JE SHORT 0043C018
0043BFC6  |.  F646 24 10    TEST BYTE PTR DS:[ESI+24],10
0043BFCA  |.  74 1A         JE SHORT 0043BFE6
0043BFCC  |.  6A 04         PUSH 4
0043BFCE  |.  8BCE          MOV ECX,ESI
0043BFD0  |.  5B            POP EBX
0043BFD1  |.  E8 00300000   CALL 0043EFD6                            ; [doc2chm.0043EFD6
0043BFD6  |.  F6C4 01       TEST AH,01
0043BFD9  |.  74 03         JE SHORT 0043BFDE
0043BFDB  |.  6A 05         PUSH 5
0043BFDD  |.  5B            POP EBX
0043BFDE  |>  53            PUSH EBX                                 ; /Arg1
0043BFDF  |.  8BCE          MOV ECX,ESI                              ; |
0043BFE1  |.  E8 BC290000   CALL 0043E9A2                            ; \doc2chm.0043E9A2

这段代码调用多个与窗口资源相关的API,几个条件跳转指令也与资源相关。看上去更像是创建“Thank you for trying DOC2CHM”对话框的代码。事实上,按F8单步执行到0043BFC2处时,任务栏上已经出现“DOC2CHM 2.5”的对话框。CALL 0043BC16调用的正是创建对话框的子过程。
我们还需要回溯。再次运行程序中断到0040E4DA处。可郁闷的是堆栈视图再也给不出有效的返回地址了。现在我们只有硬着头皮从0040E4DA往回找,看看附近有什么跳转指令。还好,没几步就有一个jnz。代码如下所示:
CPU Disasm
Address   Hex dump          Command                                  Comments
0040E4B5  |.  E8 A6370000   CALL 00411C60
0040E4BA  |.  83CE FF       OR ESI,FFFFFFFF
0040E4BD  |.  85C0          TEST EAX,EAX
0040E4BF  |.  0F85 44020000 JNE 0040E709
0040E4C5  |.  55            PUSH EBP                                 ; /Arg1 => 0
0040E4C6  |.  8D4C24 74     LEA ECX,[LOCAL.177]                      ; |
0040E4CA  |.  E8 11910000   CALL 004175E0                            ; \doc2chm.004175E0
0040E4CF  |.  8D4C24 70     LEA ECX,[LOCAL.177]
0040E4D3  |.  89AC24 340300 MOV DWORD PTR SS:[LOCAL.0],EBP
0040E4DA  |.  E8 26DA0200   CALL 0043BF05                            ; [doc2chm.0043BF05

JNE 0040E709一句值得我们留意。该指令跳转的跨度比较大,如果跳转成功,则程序不会执行到0040E4DA处,“Thank you for trying DOC2CHM”对话框也就不会显示。JNE是否跳转是由EAX是否不为0确定的。而EAX是CALL 00411C60的返回值。
我们在0040E4BF处设置断点,重启程序执行到该处。把EAX由0改为1,继续执行。呵,“Thank you for trying DOC2CHM”对话框跳过了!这正是我们要找的关键跳转。
现在我们可以修改PE文件了。去除所有断点,重启DOC2CHM.exe,程序在WinMain处断下来。在反汇编窗口按下热键CTRL+G(对应的右键菜单为“转到表达式”),输入0040E4B5,确定后反汇编窗口显示0040E4B5附近的代码。双击JNE 0040E709一句,在弹出的对话框中把该句改为JMP 0040E709,然后关闭窗口。这时修改后的代码以红色高亮显示。现在,我们就可以用OllyDump插件转储修改后的可执行文件了。由于这个文件没有加壳,以默认方式转储即可。
我们也可以把0040E4B5处的CALL 00411C60修改为MOV EAX,1。事实上,00411C60正是验证注册码的子过程。如果您希望为DOC2CHM做一个算号器,则可进一步分析00411C60中的代码。像我这种比较懒的人,软件能用就满足了。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
  • 1.JPG (31.29kb,160次下载)
  • 2.JPG (17.92kb,159次下载)
  • 3.JPG (8.39kb,159次下载)
  • 4.JPG (52.62kb,158次下载)
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
参考LZ的思路,学习了

改了一个字节,去除启动的注册要求,只是程序上显示是未注册版,不知道有没有功能限制,自己不用这类软件

断点是用的 Bpx ReadFile 下断后来到下面

0040E4B3   > \8BCF          mov     ecx, edi
0040E4B5   .  E8 A6370000   call    00411C60
0040E4BA   .  83CE FF       or      esi, FFFFFFFF
0040E4BD   .  85C0          test    eax, eax
0040E4BF >    0F84 44020000 je      0040E709                         ;  启动时的检测对比,跳过则成功,原JNE,直接改为JE,或JMP都行
0040E4C5   .  55            push    ebp
0040E4C6   .  8D4C24 74     lea     ecx, dword ptr [esp+74]
0040E4CA   .  E8 11910000   call    004175E0
0040E4CF   .  8D4C24 70     lea     ecx, dword ptr [esp+70]
0040E4D3   .  89AC24 340300>mov     dword ptr [esp+334], ebp
0040E4DA   .  E8 26DA0200   call    0043BF05                         ;  启动时要求注册的窗口
0040E4DF   .  83F8 02       cmp     eax, 2
0040E4E2   .  0F85 0C010000 jnz     0040E5F4
0040E4E8   .  899C24 340300>mov     dword ptr [esp+334], ebx
0040E4EF   .  8D9424 240300>lea     edx, dword ptr [esp+324]
0040E4F6   .  C78424 240300>mov     dword ptr [esp+324], 004537E0    ;  jrd
0040E501   .  895424 10     mov     dword ptr [esp+10], edx
0040E505   .  8D8C24 240300>lea     ecx, dword ptr [esp+324]
0040E50C   .  C68424 340300>mov     byte ptr [esp+334], 0C
2010-10-8 23:41
0
游客
登录 | 注册 方可回帖
返回
//