• 标 题:EasyBoot5.03脱壳+暴破
  • 作 者:lelfei
  • 时 间:004-11-17,09:35
  • 链 接:http://bbs.pediy.com

【破解作者】 lelfei
【作者邮箱】 lelfei#sina.com
【使用工具】 Peid0.92,FI3.01,OllyDBG1.10,LordPE,UltraEdit,...
【破解平台】 Win2000
【软件名称】 EasyBoot 5.0.3.426 , 2004年9月22日
【下载地址】 http://cn.ezbsystems.com
【软件简介】 EasyBoot是一款集成化的中文光盘启动菜单制作工具,它可以制作光盘启动菜单、自动生成启动文件、并生成可启动ISO文件。只要通过CD-R/W刻录软件即可制作完全属于自己的启动光盘。
【软件大小】 2.40M
【加壳方式】 未知
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】



一、脱壳:

观察:

用Peid和FI侦察,发现壳为“ASPack 2.12 -> Alexey Solodovnikov”,但实际并非如此。

下手:

用Fly修改的OllyDBG1.10载入程序,停在入口处:

代码:
005AB001 E>pushad                      <--程序入口点 005AB002   call EasyBoot.005AB00A 005AB007   jmp 45B7B4F7

可以单步跟,我们用最快速的方法到达伪OEP:

查找按“Ctrl+F”,输入命令“Popad”,再按三次“Ctrl+L”(继续查找),来到005AB3AF处,再“F4”到这里:
代码:
005AB3A9   mov dword ptr ss:[ebp+3A8],eax 005AB3AF   popad                             ;<--F4来到这里 005AB3B0   jnz short EasyBoot.005AB3BA 005AB3B2   mov eax,1 005AB3B7   retn 0C 005AB3BA   push EasyBoot.00401428            ;可以看见伪OEP了 005AB3BF   retn                              ;返回到 00401428 (EasyBoot.00401428) 00401428   jmp short EasyBoot.0040143A            ;<--伪OEP入口 0040142A   db 66                                  ;  CHAR 'f' 0040142B   db 62                                  ;  CHAR 'b' 0040142C   db 3A                                  ;  CHAR ':' 0040142D   db 43                                  ;  CHAR 'C' 0040142E   db 2B                                  ;  CHAR '+' 0040142F   db 2B                                  ;  CHAR '+' 00401430   db 48                                  ;  CHAR 'H' 00401431   db 4F                                  ;  CHAR 'O' 00401432   db 4F                                  ;  CHAR 'O' 00401433   db 4B                                  ;  CHAR 'K' 00401434   nop 00401435   db E9 00401436   dd offset EasyBoot.___CPPdebugHook 0040143A   mov eax,dword ptr ds:[50708B] 0040143F   shl eax,2 发现伪OEP处的代码并不像我们常见的程序入口点代码,继续往下跟: 0040143A   mov eax,dword ptr ds:[50708B] 0040143F   shl eax,2 00401442   mov dword ptr ds:[50708F],eax 00401447   push edx 00401448   push 0                               ; /pModule = NULL 0040144A   call EasyBoot.00506066               ; \GetModuleHandleA 0040144F   mov edx,eax 00401451   call EasyBoot.004E303C 00401456   pop edx 00401457   call EasyBoot.004E2FA0 0040145C   call EasyBoot.004E307C 00401461   push 0                               ; /Arg1 = 00000000 00401463   call EasyBoot.004E4690               ; \EasyBoot.004E4690 00401468   pop ecx 00401469   push EasyBoot.00507034 0040146E   push 0                               ; /pModule = NULL 00401470   call EasyBoot.00506066               ; \GetModuleHandleA 00401475   mov dword ptr ds:[507093],eax 0040147A   push 0 0040147C   jmp EasyBoot.004EE16C                ;<--这里跳向真正的OEP 00401481 E>jmp EasyBoot.004E46DC 004EE16C   push ebp                    ;<--真实的OEP,观察这里的代码 004EE16D   mov ebp,esp 004EE16F   add esp,-0C 004EE172   push ebx 004EE173   push esi 004EE174   push edi 004EE175   mov esi,dword ptr ss:[ebp+8] 004EE178   mov eax,dword ptr ds:[esi+10] 004EE17B   and eax,1 004EE17E   mov dword ptr ds:[51F1A0],eax 004EE183   call EasyBoot.004EADB4

在004EE16C处DUMP内存,存为“Dump.exe”。

修复IAT:

运行ImportREC1.6,选择当前的进程“EasyBoot.exe”,填入OEP:000EE16C,获取输入表,可以看到仅有Kernel32.dll中的函数调用。

不知道各位高手是怎么解决这个问题的,我摸索出一个解决办法如下:

在函数框中点鼠标右键->高级命令菜单->获取API调用信息,填入地址范围00000000-FFFFFFFF,只勾选“获取‘Call X’scheme”,确定后会发现找到一大串;

点“显示无效函数”,在函数框中点鼠标右键->删除指针数据,FixDump生成dump_.exe。

修正OEP:

用OllyDBG载入刚生成的Dump_.exe,运行出错,还是由于程序调用[ESI+XX]引起的,在壳中OEP处ESI=ESP+4=[0012FFC0]=00507034,而脱壳后ESI=ESP+4=[0012FFC8]=005616A8,需要平衡堆栈。

在代码段的空白处,我选在该段的结尾处,输入下面代码:
代码:
00506FF0 1>mov dword ptr ss:[esp+4],fix_dump.00507034   ;<--恢复堆栈数据 00506FF8   jmp fix_dump.004EE16C                        ;<--跳到真正的OEP

用LordPE修改程序的OEP为00106FF0,保存为fix_dump_.exe,试运行之,成功!





二、爆破:

观察:

未注册版有烦人的弹出窗口提示,还有功能限制,在“关于”里输入注册码,发现为重启验证,注册表里存有注册信息,用户名为明码保存,注册码为加密形式保存。

下手:

既然存到注册表里,我们就从注册表入手:

在命令行里输入:bp RegOpenKeyExA,按F9运行程序,中断后观察ESP+4和ESP+8处的字符,直到分别为“hKey = HKEY_CURRENT_USER”和“Subkey = "SOFTWARE\EasyBoot Systems\EasyBoot\3.0"”为止,(在我的电脑上是按了5次F9),关闭断点,然后按“Alt+F9”返回程序,来到:
代码:
00402630   push ecx                          ; /pHandle 00402631   push fix_dump.0050A3A5            ; |Subkey = "SOFTWARE\EasyBoot Systems\EasyBoot\3.0" 00402636   push 80000001                     ; |hKey = HKEY_CURRENT_USER 0040263B   call <jmp.&advapi32.RegOpenKeyA>  ; \RegOpenKeyA 00402640   test eax,eax                      ;<--返回到这里 00402642   jnz fix_dump.004026C9             ;判断是否有注册表信息 00402648   mov dword ptr ss:[ebp-40],400 0040264F   lea eax,dword ptr ss:[ebp-40] 00402652   push eax                          ; /pBufSize 00402653   lea edx,dword ptr ss:[ebp-648]    ; | 00402659   push edx                          ; |Buffer 0040265A   lea ecx,dword ptr ss:[ebp-3C]     ; | 0040265D   push ecx                          ; |pValueType 0040265E   push 0                            ; |Reserved = NULL 00402660   push fix_dump.0050A3CC            ; |ValueName = "" 00402665   push dword ptr ss:[ebp-38]        ; |hKey 00402668   call <jmp.&advapi32.RegQueryValue>; \RegQueryValueExA 0040266D   test eax,eax 0040266F   jnz short fix_dump.004026C1 ··· 0040272A   lea edx,dword ptr ss:[ebp-248] 00402730   push edx                          ; /Arg2 00402731   lea ecx,dword ptr ss:[ebp-148]    ; | 00402737   push ecx                          ; |Arg1 00402738   call fix_dump.004397F8            ; \fix_dump.004397F8读注册信息 0040273D   add esp,8                         ;<--到这里可以看到注册信息 00402740  mov dword ptr ds:[50A5AC],eax      ;置注册标志位1 00402745  mov eax,dword ptr ds:[50A5AC] 0040274A  test eax,eax                       ;判断注册信息是否存在 0040274C  je short fix_dump.0040276B 0040274E  lea edx,dword ptr ss:[ebp-248] 00402754  push edx 00402755  lea ecx,dword ptr ss:[ebp-148] 0040275B  push ecx 0040275C  call fix_dump.004017D3             ;关键CALL,比较注册码,跟进 00402761  add esp,8 00402764  mov dword ptr ds:[50A5AC],eax      ;保存注册标志位1 00402769  jmp short fix_dump.00402772 0040276B  xor eax,eax                        ;清除注册标志位1 0040276D  mov dword ptr ds:[50A5AC],eax 跟进0040275C处的关键CALL: 004017D3   $  55  push ebp 004017D4   .  8BE>mov ebp,esp 004017D6   .  81C>add esp,-4C0 004017DC   .  33C>xor eax,eax ···注册码计算过程,有兴趣的同志可以慢慢跟:) 00401A93  xor ecx,ecx 00401A95  mov dword ptr ss:[ebp-2C],ecx 00401A98  lea eax,dword ptr ss:[ebp-468] 00401A9E  mov edx,dword ptr ds:[eax] 00401AA0  mov ecx,dword ptr ss:[ebp-34] 00401AA3  mov eax,dword ptr ds:[ecx] 00401AA5  cmp edx,eax 00401AA7  jnz short fix_dump.00401B13       ;关键比较1,跳则完完 00401AA9  lea edx,dword ptr ss:[ebp-468] 00401AAF  mov dword ptr ss:[ebp-3C],edx 00401AB2  dec dword ptr ds:[5145C0] 00401AB8  mov ecx,dword ptr ss:[ebp-34] 00401ABB  mov dword ptr ss:[ebp-40],ecx 00401ABE  mov eax,dword ptr ss:[ebp-3C] 00401AC1  mov edx,dword ptr ds:[eax] 00401AC3  mov ecx,dword ptr ss:[ebp-40] 00401AC6  mov eax,dword ptr ds:[ecx] 00401AC8  cmp edx,eax 00401ACA  jnz short fix_dump.00401B13       ;关键比较2,跳则完完 00401ACC  mov edx,dword ptr ss:[ebp-3C] 00401ACF  mov ecx,dword ptr ds:[edx+C] 00401AD2  mov eax,dword ptr ss:[ebp-40] 00401AD5  mov edx,dword ptr ds:[eax+4] 00401AD8  cmp ecx,edx 00401ADA  jnz short fix_dump.00401B13       ;关键比较3,跳则完完 00401ADC  dec dword ptr ds:[5145C0] 00401AE2  mov ecx,dword ptr ss:[ebp-28] 00401AE5  add ecx,46 00401AE8  mov dword ptr ds:[5083D8],ecx 00401AEE  mov eax,dword ptr ss:[ebp-28] 00401AF1  not eax 00401AF3  mov edx,dword ptr ds:[5145C0] 00401AF9  cmp eax,edx 00401AFB  jnz short fix_dump.00401B29       ;关键比较4,跳则完完 00401AFD  mov dword ptr ds:[5145C0],5000    ;置注册标志位2 00401B07  mov dword ptr ds:[50B5F4],5500    ;置注册标志位3 00401B11  jmp short fix_dump.00401B29 00401B13  add dword ptr ss:[ebp-34],8 00401B17  inc dword ptr ss:[ebp-2C] 00401B1A  mov ecx,dword ptr ss:[ebp-2C] 00401B1D  cmp ecx,1D0 00401B23  jl fix_dump.00401A98 00401B29  mov eax,dword ptr ss:[ebp-28] 00401B2C  add eax,46 00401B2F  mov edx,dword ptr ds:[5083D8] 00401B35  cmp eax,edx 00401B37  je short fix_dump.00401B3F 00401B39  dec dword ptr ds:[5145C0] 00401B3F  lea ecx,dword ptr ss:[ebp-10] 00401B42  push ecx                          ; /Arg2 00401B43  push dword ptr ss:[ebp+8]         ; |Arg1 00401B46  call fix_dump.00445CDC            ; \fix_dump.00445CDC 00401B4B  add esp,8 00401B4E  push dword ptr ss:[ebp-14]        ; /Arg2 00401B51  push dword ptr ss:[ebp-10]        ; |Arg1 00401B54  call fix_dump.00442538            ; \fix_dump.00442538  再次判断 00401B59  add esp,8 00401B5C  test eax,eax 00401B5E  je short fix_dump.00401B64        ;关键比较5,不跳则影响注册标志位1 00401B60  xor eax,eax 00401B62  jmp short fix_dump.00401B69 00401B64  mov eax,1 00401B69  mov esp,ebp 00401B6B  pop ebp 00401B6C  retn

注册过程总结:

把经过处理的注册码与真注册码分4段比较,(即4个关键比较),有一段出错立即跳出;如果全部都正确则置2个标志位,(即注册标志位2和注册标志位3),再经过一次计算,将结果返回时放到注册标志位1。

于是爆破如下:修改关键比较1、关键比较2、关键比较3、关键比较4为9090(即两个NOP),修改关键比较5为JMP,试运行之,显示为“本产品授权给:asdf”,成功!

去暗桩:

程序还有暗桩,在预览界面中点鼠标右键会直接退出。

如何拦截退出程序的代码呢?我有一个笨方法:回溯找CALL法。办法很笨,但还是比较有效的。

重新载入程序,下断:“bp ExitProcess”,在预览界面中点鼠标右键,果然断下,看堆栈:
代码:
0012F580    004EDFEC   /CALL 到 ExitProcess 来自 fix_dump.004EDFE7 是004EDFE7处调用ExitProcess的。回溯查看004EDFE7处的代码: 004EDFE0  /$>push ebp                          ;Local Call from 004ED390 004EDFE1  |.>mov ebp,esp 004EDFE3  |.>mov eax,dword ptr ss:[ebp+8] 004EDFE6  |.>push eax                          ; /ExitCode 004EDFE7  \.>call <jmp.&kernel32.ExitProcess>  ; \ExitProcess 向上看004EDFE0处,有一个CALL入口“Local Call from 004ED390”。再回溯到004ED390处: 004ED334  /$  5>push ebp                       ;Local Calls from 004ED3AB, 004ED3C3, 004ED3D6, 004ED3E6 004ED335  |.  8>mov ebp,esp 004ED337  |.  5>push ebx 004ED338  |.  8>mov ebx,dword ptr ss:[ebp+8] 004ED33B  |.  E>call fix_dump.004EE138 004ED340  |.  8>test ebx,ebx 004ED342  |.  7>jnz short fix_dump.004ED360 004ED344  |.  8>cmp dword ptr ds:[51EFEC],0 004ED34B  |.  7>je short fix_dump.004ED353 004ED34D  |.  F>call dword ptr ds:[51EFEC] 004ED353  |>  E>call fix_dump.004EE0CC 004ED358  |.  F>call dword ptr ds:[51EFF0]    ;  fix_dump.004ED330 004ED35E  |.  E>jmp short fix_dump.004ED367 004ED360  |>  3>xor eax,eax 004ED362  |.  A>mov dword ptr ds:[51EFEC],eax 004ED367  |>  8>cmp dword ptr ss:[ebp+C],0 004ED36B  |.  7>jnz short fix_dump.004ED396 004ED36D  |.  8>test ebx,ebx 004ED36F  |.  7>jnz short fix_dump.004ED37D 004ED371  |.  F>call dword ptr ds:[51EFF4]    ;  fix_dump.004ED330 004ED377  |.  F>call dword ptr ds:[51EFF8]    ;  fix_dump.004ED330 004ED37D  |>  E>call fix_dump.004EE148 004ED382  |.  E>call fix_dump.004E5EEC 004ED387  |.  E>call fix_dump.004E76EC 004ED38C  |.  8>mov edx,dword ptr ss:[ebp+10] 004ED38F  |.  5>push edx 004ED390  |.  E>call fix_dump.004EDFE0        ;调用退出程序CALL 004ED395  |.  5>pop ecx 004ED396  |>  E>call fix_dump.004EE148 004ED39B  |.  5>pop ebx 004ED39C  |.  5>pop ebp 004ED39D  \.  C>retn

这个CALL入口有多个调用,于是重新运行程序,在004ED334下断,看堆栈调用:

0012F59C    004ED3B0   返回到 fix_dump.004ED3B0 来自 fix_dump.004ED334

再回溯到004ED334处。。。。

···

经过几次回溯后来到这里:
代码:
00435773  mov edx,dword ptr ds:[50A5AC]  ;取注册标志位1 00435779  test edx,edx 0043577B  je short fix_dump.004357BE     ;未注册时跳走 0043577D  push fix_dump.0052D668         ; /Arg2 = 0052D668 ASCII "1111111111111111" 00435782  push fix_dump.0052D564         ; |Arg1 = 0052D564 ASCII "asdf" 00435787  call fix_dump.0043425F         ; \fix_dump.0043425F  判断注册码 0043578C  add esp,8 0043578F  mov ecx,dword ptr ds:[5145C0]  ;取注册标志位2 00435795  cmp ecx,5000 0043579B  je short fix_dump.004357BE     ;未注册时执行退出命令 0043579D  push 0                         ; /Arg1 = 00000000 0043579F  call fix_dump.004ED3A0         ; \fix_dump.004ED3A0  <--退出程序的Call 004357A4  pop ecx 004357A5  jmp short fix_dump.004357BE 004357A7  push dword ptr ds:[521748]     ; /Arg1 = 00000000; Case 2E of switch 0043527D

又找到一个比较注册码的CALL:00435787。跟进后发现与程序启动时的比较过程完全一样,同样修改5处,可突破右键退出的限制。

那么如何找到其他判断注册码的地方呢?我找了一投机取巧的办法:

因为程序在判断注册码后都有一个置注册标志位的命令:

C705 C0455100 00500000    mov dword ptr ds:[5145C0],5000  ;置注册标志位2
C705 F4B55000 00550000    mov dword ptr ds:[50B5F4],5500  ;置注册标志位3

而这二句的十六进制代码与所在程序的位置无关,都是C705C045510000500000C705F4B5500000550000,

在UltraEdit中搜索该代码,根据找到的物理地址再转换到程序的偏移地址,一共可以找到4处,分别修改即可。

--------------------------------------------------------------------------------
【爆破地址】


爆破修改如下:
代码:
查找地址|物理偏移|原值|修改 00001AFD:00001AA7:756A->9090    ;启动时检查,己修改           00001ACA:7547->9090           00001ADA:7537->9090           00001AFB:752C->9090           00004B6E:7404->EB04 00004B0D:00004AB7:756A->9090    ;右键检查           00004ADA:7547->9090           00004AEA:7537->9090           00004B0B:752C->9090           00004B6E:7404->EB04 00034589:00034533:756A->9090           00034556:7547->9090           00034566:7537->9090           00034587:752C->9090           000345EA:7404->EB04 00035D31:00035CDB:756A->9090           00035CFE:7547->9090           00035D0E:7537->9090           00035D2F:752C->9090           00035D92:7404->EB04

至此该程序己完美爆破!!!


--------------------------------------------------------------------------------

【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!





感谢看完!因环境限制,无人交流,上网也不方便,破解该程序所用的方法几乎全靠我自己摸索,用了三天时间才跟出来~~累啊!小弟语言表达能力太差,不知各位看官有没有看出我表达的意思,欢迎与我交流!!