AptEdit pro 5.1.0 Build 394的破解分析

用PEid查壳显示为:Microsoft Visual C++ 7.0 [调试]
没有壳,直接用OD载入,F9运行,点击关于窗口,有未注册提示,于是查找字符串”Unregistered”,找到2处:


文本字符串参考位于 aptedit:.text,项目 10
地址=00401EF7
反汇编=push aptedit.007953B0
文本字符串=UNICODE "Unregistered trial version:
You have %d day left."

文本字符串参考位于 aptedit:.text,项目 11
地址=00401F14
反汇编=push aptedit.00795348
文本字符串=UNICODE "Unregistered trial version:
You have %d days left."

于是在两个位置下断,然后重新打开关于窗口,程序中断在:


00401EF6    |.  51               push ecx                              ; /Arg3
00401EF7    |.  68 B0537900      push aptedit.007953B0                 ; |Arg2 = 007953B0
00401EFC    |.  8D95 7CFFFFFF    lea edx,dword ptr ss:[ebp-84]         ; |
00401F02    |.  52               push edx                              ; |Arg1
00401F03    |.  E8 38D50000      call aptedit.0040F440                 ; \aptedit.0040F440
00401F08    |.  83C4 0C          add esp,0C
00401F0B    |.  EB 1B            jmp short aptedit.00401F28
00401F0D    |>  8B85 48FBFFFF    mov eax,dword ptr ss:[ebp-4B8]
00401F13    |.  50               push eax                              ; /Arg3
00401F14    |.  68 48537900      push aptedit.00795348                 ; |Arg2 = 00795348:中断在此
00401F19    |.  8D8D 7CFFFFFF    lea ecx,dword ptr ss:[ebp-84]         ; |
00401F1F    |.  51               push ecx                              ; |Arg1
00401F20    |.  E8 1BD50000      call aptedit.0040F440                 ; \aptedit.0040F440

向上找到敌我段首下断:


00401280    /.  55               push ebp
00401281    |.  8BEC             mov ebp,esp
00401283    |.  6A FF            push -1
00401285    |.  68 559B7700      push aptedit.00779B55                 ;  SE 句柄安装
0040128A    |.  64:A1 00000000   mov eax,dword ptr fs:[0]

再次来过,打开关于窗口,中断在段首后,F8来单步跟踪,很快就找到这里:


0040199D    |> \8B95 E0F5FFFF    mov edx,dword ptr ss:[ebp-A20]
004019A3    |.  8B42 70          mov eax,dword ptr ds:[edx+70]
004019A6    |.  8985 B0F8FFFF    mov dword ptr ss:[ebp-750],eax
004019AC    |.  68 B8547900      push aptedit.007954B8                 ;  UNICODE

"AE5B082B5EFA5439CD6335B578EFEEF5"
004019B1    |.  8B8D B0F8FFFF    mov ecx,dword ptr ss:[ebp-750]
004019B7    |.  51               push ecx
004019B8    |.  E8 506C3300      call aptedit.0073860D                 ;  这是一个关键CALL,多处调用
004019BD    |.  83C4 08          add esp,8                             ;  但不是注册验证的地方
004019C0    |.  F7D8             neg eax
004019C2    |.  1BC0             sbb eax,eax
004019C4    |.  40               inc eax
004019C5    |.  0FB6D0           movzx edx,al
004019C8    |.  85D2             test edx,edx
004019CA    |.  74 1F            je short aptedit.004019EB             ;  此处不跳转就会显示已注册
004019CC    |.  A1 504E8200      mov eax,dword ptr ds:[824E50]
004019D1    |.  50               push eax                              ; /Arg3 => 00000000
004019D2    |.  68 7C547900      push aptedit.0079547C                 ; |Arg2 = 0079547C
004019D7    |.  8D8D 7CFFFFFF    lea ecx,dword ptr ss:[ebp-84]         ; |
004019DD    |.  51               push ecx                              ; |Arg1
004019DE    |.  E8 5DDA0000      call aptedit.0040F440                 ; \aptedit.0040F440
004019E3    |.  83C4 0C          add esp,0C
004019E6    |.  E9 3D050000      jmp aptedit.00401F28

我们将je short aptedit.004019EB给NOP掉后,显示为已注册了!但在注册窗口依然有提示.我们进call aptedit.0073860D,

在2个返回处都下上断:


00738633    |. /7D 04            jge short aptedit.00738639
00738635    |. |83C8 FF          or eax,FFFFFFFF
00738638    |. |C3               retn
00738639    |> \7E 03            jle short aptedit.0073863E
0073863B    |.  33C0             xor eax,eax
0073863D    |.  40               inc eax
0073863E    \>  C3               retn

发现程序不停的调用并经过后面一个返回,于是我们将其取消,只保留上面的一个断点,再次点击”帮助”菜单后,中断了下来,

我们F8单步一下,返回到了这里:


00425C6D    |> \8B55 EC          mov edx,dword ptr ss:[ebp-14]
00425C70    |.  8995 F4FCFFFF    mov dword ptr ss:[ebp-30C],edx
00425C76    |.  68 B8547900      push aptedit.007954B8                 ;  UNICODE

"AE5B082B5EFA5439CD6335B578EFEEF5"
00425C7B    |.  8B85 F4FCFFFF    mov eax,dword ptr ss:[ebp-30C]
00425C81    |.  50               push eax
00425C82    |.  E8 86293100      call aptedit.0073860D
00425C87    |.  83C4 08          add esp,8
00425C8A    |.  F7D8             neg eax
00425C8C    |.  1BC0             sbb eax,eax
00425C8E    |.  40               inc eax
00425C8F    |.  0FB6C8           movzx ecx,al
00425C92    |.  85C9             test ecx,ecx
00425C94    |.  74 07            je short aptedit.00425C9D

与上面的那个关于窗口的判断是何其相似???同样的的,将je short aptedit.00425C9D给NOP掉,然后取消那个返回上的断点,

再次点击”帮助”菜单,发现注册按钮就成灰色了!!
哈,成功了!保存修改,另存一下!运行一下,似乎正常了,为了测试日期,我们把系统时间后调一个月试试~!
程序提示已经过期!!只好载入,继续破解之旅了^^^

载入程序,搜索关键字符”trial period”,找到:


文本字符串参考位于 CrackEd:.text,项目 9
地址=00401ED1
反汇编=push CrackEd.00795418
文本字符串=UNICODE "Your %d-day trial period of AptEdit has expired."

文本字符串参考位于 CrackEd:.text,项目 515
地址=0042939B
反汇编=push CrackEd.0079A888
文本字符串=UNICODE "Your %d-day trial period of AptEdit Pro has expired."

在两处都下上断点后,重新载入程序,F9运行后中断在:


0042939B    |.  68 88A87900      push CrackEd.0079A888                 ; |Arg2 = 0079A888
004293A0    |.  8D4D EC          lea ecx,dword ptr ss:[ebp-14]         ; |
004293A3    |.  51               push ecx                              ; |Arg1
004293A4    |.  E8 9760FEFF      call CrackEd.0040F440                 ; \CrackEd.0040F440
004293A9    |.  83C4 0C          add esp,0C
004293AC    |.  EB 56            jmp short CrackEd.00429404

同样,我们往上找段首,然后下断,重新来过


004291B0    /.  55               push ebp
004291B1    |.  8BEC             mov ebp,esp
004291B3    |.  6A FF            push -1
004291B5    |.  68 A8B17700      push CrackEd.0077B1A8                 ;  SE 句柄安装
004291BA    |.  64:A1 00000000   mov eax,dword ptr fs:[0]

在段首中断下来后,留意堆栈:


0013B07C   0074E8D9  返回到 CrackEd.0074E8D9
0013B080   77D18734  返回到 USER32.77D18734
0013B084   003106BE
0013B088   00000110

在0013B07C上右键–>返回到反汇编窗口,返回到这里:


0074E8AB    /$  817C24 08 100100>cmp dword ptr ss:[esp+8],110
0074E8B3    |.  75 2B            jnz short CrackEd.0074E8E0
0074E8B5    |.  FF7424 04        push dword ptr ss:[esp+4]
0074E8B9    |.  E8 9D250000      call CrackEd.00750E5B
0074E8BE    |.  50               push eax
0074E8BF    |.  68 38887E00      push CrackEd.007E8838
0074E8C4    |.  E8 30720000      call CrackEd.00755AF9
0074E8C9    |.  85C0             test eax,eax
0074E8CB    |.  59               pop ecx
0074E8CC    |.  59               pop ecx
0074E8CD    |.  74 0C            je short CrackEd.0074E8DB
0074E8CF    |.  8B10             mov edx,dword ptr ds:[eax]
0074E8D1    |.  8BC8             mov ecx,eax
0074E8D3    |.  FF92 44010000    call dword ptr ds:[edx+144]           ;  返回到这里
0074E8D9    |.  EB 07            jmp short CrackEd.0074E8E2
0074E8DB    |>  33C0             xor eax,eax
0074E8DD    |.  40               inc eax
0074E8DE    |.  EB 02            jmp short CrackEd.0074E8E2
0074E8E0    |>  33C0             xor eax,eax
0074E8E2    \>  C2 1000          retn 10

然后我们选中:cmp dword ptr ss:[esp+8],110这一行,按快捷键:Ctrl+R


参考位于 CrackEd:.text 到 0074E8AB
地址       反汇编                                 注释
0074B9D9   call CrackEd.0074E8AB
0074E8AB   cmp dword ptr ss:[esp+8],110           (初始 CPU 选择)
0074EF8E   push CrackEd.0074E8AB                  入口地址
0076AB82   mov dword ptr ds:[eax+18],CrackEd.007  入口地址
00773B71   call CrackEd.0074E8AB

在找到的几个位置全部下上断点,再次重新载入程序,F9运行,先中断在了0074EF8E上,此时鼠标似乎不好用了,我们用快捷键

F2取消这个断点,再F9运行,就中断在下面的位置了:


0074EF8D     > \57               push edi                              ; /lParam
0074EF8E     .  68 ABE87400      push CrackEd.0074E8AB                 ; |pDlgProc = CrackEd.0074E8AB
0074EF93     .  50               push eax                              ; |hOwner
0074EF94     .  56               push esi                              ; |pTemplate
0074EF95     .  FF75 10          push dword ptr ss:[ebp+10]            ; |hInst
0074EF98     .  FF15 382D8200    call dword ptr ds:[822D38]            ; \CreateDialogIndirectParamW

原来0074E8AB处是一个对话框的回调函数.同样找到段首:
0074EE35     $  B8 E6007900      mov eax,CrackEd.007900E6

选中后,按Ctrl+R:


参考位于 CrackEd:.text 到 0074EE35
地址       反汇编                                         注释
0074EE35   mov eax,CrackEd.007900E6                       (初始 CPU 选择)
0074F107   call CrackEd.0074EE35
0074F1E1   call CrackEd.0074EE35
0074F229   call CrackEd.0074EE35

再次在三处调用上下断,重新载入,F9运行,中断在:


0074F103     .  50               push eax
0074F104     .  53               push ebx
0074F105     .  8BCE             mov ecx,esi
0074F107     .  E8 29FDFFFF      call CrackEd.0074EE35
0074F10C     .  33DB             xor ebx,ebx
0074F10E     .  3BC3             cmp eax,ebx
0074F110     .  74 52            je short CrackEd.0074F164
0074F112     .  F646 38 10       test byte ptr ds:[esi+38],10
0074F116     .  74 1A            je short CrackEd.0074F132

继续找段首,然后在段首下断:


0074F042     $  B8 F0007900      mov eax,CrackEd.007900F0
0074F047     .  E8 60D3FEFF      call CrackEd.0073C3AC
0074F04C     .  83EC 18          sub esp,18
0074F04F     .  53               push ebx

重新载入运行,留意堆栈的值:


0013B650   0040565F  返回到 CrackEd.0040565F 来自 CrackEd.0074F042
0013B654   00822E78  CrackEd.00822E78

在0013B650上,右键–>返回到反汇编窗口,来到这里:


00405633    |.  C645 FC 0E       mov byte ptr ss:[ebp-4],0E
00405637    |.  C785 58C4FFFF 1E>mov dword ptr ss:[ebp-3BA8],1E
00405641    |.  8B8D 54D7FFFF    mov ecx,dword ptr ss:[ebp-28AC]
00405647    |.  BA 1E000000      mov edx,1E
0040564C    |.  2BD1             sub edx,ecx
0040564E    |.  8995 5CC4FFFF    mov dword ptr ss:[ebp-3BA4],edx
00405654    |.  8D8D E4C3FFFF    lea ecx,dword ptr ss:[ebp-3C1C]
0040565A    |.  E8 E3993400      call CrackEd.0074F042
0040565F    |.  C645 FC 0A       mov byte ptr ss:[ebp-4],0A            ;  返回到这里
00405663    |.  8D8D E4C3FFFF    lea ecx,dword ptr ss:[ebp-3C1C]
00405669    |.  E8 82380200      call CrackEd.00428EF0
0040566E    |>  8B85 08B8FFFF    mov eax,dword ptr ss:[ebp+FFFFB808]   ;  留意,上面有跳转直接跳转到这里

我们选中:
0040566E    |>  8B85 08B8FFFF    mov eax,dword ptr ss:[ebp+FFFFB808]
留意提示窗口,或者直接根据流程线,很快就找到这里:


00404EE0    |.  68 B8547900      push CrackEd.007954B8                 ;  UNICODE

"AE5B082B5EFA5439CD6335B578EFEEF5"
00404EE5    |.  8B85 B4B9FFFF    mov eax,dword ptr ss:[ebp+FFFFB9B4]
00404EEB    |.  50               push eax
00404EEC    |.  E8 1C373300      call CrackEd.0073860D
00404EF1    |.  83C4 08          add esp,8
00404EF4    |.  F7D8             neg eax
00404EF6    |.  1BC0             sbb eax,eax
00404EF8    |.  F7D8             neg eax
00404EFA    |.  0FB6C8           movzx ecx,al
00404EFD    |.  85C9             test ecx,ecx
00404EFF    |.  0F84 69070000    je CrackEd.0040566E

多么熟悉的代码啊,重新载入,将je CrackEd.0040566E改为jmp CrackEd.0040566E后,F9运行,几次后,程序自行退出了??自检

验???肯定如此!
再次重新载入,先修改成JMP,然后在修改的位置上下”内存访问断点”,连续几个中断后,程序停在了这里:


004056BD    |> /8B85 90D7FFFF    /mov eax,dword ptr ss:[ebp-2870]
004056C3    |. |3B85 84D7FFFF    |cmp eax,dword ptr ss:[ebp-287C]
004056C9    |. |73 41            |jnb short CrackEd.0040570C
004056CB    |. |8B8D 88D7FFFF    |mov ecx,dword ptr ss:[ebp-2878]
004056D1    |. |C1E9 08          |shr ecx,8
004056D4    |. |81E1 FFFFFF00    |and ecx,0FFFFFF
004056DA    |. |8B95 90D7FFFF    |mov edx,dword ptr ss:[ebp-2870]
004056E0    |. |0FB602           |movzx eax,byte ptr ds:[edx]    //中断在这里了
004056E3    |. |3385 88D7FFFF    |xor eax,dword ptr ss:[ebp-2878]
004056E9    |. |25 FF000000      |and eax,0FF
004056EE    |. |338C85 F4FBFFFF  |xor ecx,dword ptr ss:[ebp+eax*4-40C]
004056F5    |. |898D 88D7FFFF    |mov dword ptr ss:[ebp-2878],ecx
004056FB    |. |8B8D 90D7FFFF    |mov ecx,dword ptr ss:[ebp-2870]
00405701    |. |83C1 01          |add ecx,1
00405704    |. |898D 90D7FFFF    |mov dword ptr ss:[ebp-2870],ecx
0040570A    |.^\EB B1            \jmp short CrackEd.004056BD
0040570C    |>  8B95 88D7FFFF    mov edx,dword ptr ss:[ebp-2878]
00405712    |.  3315 584E8200    xor edx,dword ptr ds:[824E58]
00405718    |.  81FA B9758BFA    cmp edx,FA8B75B9
0040571E    |.  74 70            je short CrackEd.00405790

留意提示窗口,很快就会明白这里对上面的代码进行检验,校验的范围是:
起始位置:0404ED4
结束位置:0040566E
按位取值,进行运算,将结果与FA8B75B9相比,不等则会退出,所以我们这里把je short CrackEd.00405790改成无条件跳转:
jmp short CrackEd.00405790

然后保存一份,运行OK,没有提示过期的窗口了,哈!
修改原主程序名,然后再把破解版的主程序名修改过来,运行,NO,程序直接退出.看来还有检验存在!
应该是验证主程序本身的完善的,下bp CreateFileW断点,留意堆栈窗口,一路经过

006D7A50
006C4573
006C46F0

我们重新载入后,直接Ctrl+G来到:


006D7A31     > \6A 00            push 0                                ; /hTemplateFile = NULL
006D7A33     .  68 80000000      push 80                               ; |Attributes = NORMAL
006D7A38     .  6A 03            push 3                                ; |Mode = OPEN_EXISTING
006D7A3A     .  6A 00            push 0                                ; |pSecurity = NULL
006D7A3C     .  6A 01            push 1                                ; |ShareMode = FILE_SHARE_READ
006D7A3E     .  68 00000080      push 80000000                         ; |Access = GENERIC_READ
006D7A43     .  8D85 78FDFFFF    lea eax,dword ptr ss:[ebp-288]        ; |
006D7A49     .  50               push eax                              ; |FileName
006D7A4A     .  FF15 0C2C8200    call dword ptr ds:[822C0C]            ; \CreateFileW
006D7A50     .  8985 64FDFFFF    mov dword ptr ss:[ebp-29C],eax

单步F8,很快就找到:


006D7CC3     .  81BD 74FDFFFF 9A>cmp dword ptr ss:[ebp-28C],C277A69A
006D7CCD     .  74 04            je short aptedit.006D7CD3
006D7CCF     .  33C0             xor eax,eax
006D7CD1     .  EB 05            jmp short aptedit.006D7CD8
006D7CD3     >  B8 01000000      mov eax,1

很明显的一个置标志位代码,我们把je short aptedit.006D7CD3直接修改成无条件的跳转:
jmp short aptedit.006D7CD3
运行后,依然自动退出,应该是同上面的一样,对代码本身有检验以防止修改.依着感觉,觉得检验的地方应该不会太远,所以直

接从006D7CC3开始单步跟踪!


00403E95    |.  50               push eax
00403E96    |.  E8 254B3300      call aptedit.007389C0
00403E9B    |.  83C4 0C          add esp,0C
00403E9E    |.  85C0             test eax,eax
00403EA0    |.  74 61            je short aptedit.00403F03             ;  此处不跳转则会退出,改成JMP

顺着跳转,往下看,多么熟悉的代码啊


00403F03    |> \8B85 98DAFFFF    mov eax,dword ptr ss:[ebp-2568]
00403F09    |.  8985 9CDAFFFF    mov dword ptr ss:[ebp-2564],eax
00403F0F    |.  8B8D 8CDAFFFF    mov ecx,dword ptr ss:[ebp-2574]
00403F15    |.  2B8D 98DAFFFF    sub ecx,dword ptr ss:[ebp-2568]
00403F1B    |.  038D 9CDAFFFF    add ecx,dword ptr ss:[ebp-2564]
00403F21    |.  898D 90DAFFFF    mov dword ptr ss:[ebp-2570],ecx
00403F27    |.  C785 94DAFFFF FF>mov dword ptr ss:[ebp-256C],-1
00403F31    |>  8B95 9CDAFFFF    /mov edx,dword ptr ss:[ebp-2564]  //又一个自校验代码段
00403F37    |.  3B95 90DAFFFF    |cmp edx,dword ptr ss:[ebp-2570]
00403F3D    |.  73 41            |jnb short aptedit.00403F80
00403F3F    |.  8B85 94DAFFFF    |mov eax,dword ptr ss:[ebp-256C]
00403F45    |.  C1E8 08          |shr eax,8
00403F48    |.  25 FFFFFF00      |and eax,0FFFFFF
00403F4D    |.  8B8D 9CDAFFFF    |mov ecx,dword ptr ss:[ebp-2564]
00403F53    |.  0FB611           |movzx edx,byte ptr ds:[ecx]
00403F56    |.  3395 94DAFFFF    |xor edx,dword ptr ss:[ebp-256C]
00403F5C    |.  81E2 FF000000    |and edx,0FF
00403F62    |.  338495 F4FBFFFF  |xor eax,dword ptr ss:[ebp+edx*4-40C]
00403F69    |.  8985 94DAFFFF    |mov dword ptr ss:[ebp-256C],eax
00403F6F    |.  8B85 9CDAFFFF    |mov eax,dword ptr ss:[ebp-2564]
00403F75    |.  83C0 01          |add eax,1
00403F78    |.  8985 9CDAFFFF    |mov dword ptr ss:[ebp-2564],eax
00403F7E    |.^ EB B1            \jmp short aptedit.00403F31
00403F80    |>  8B8D 94DAFFFF    mov ecx,dword ptr ss:[ebp-256C]
00403F86    |.  330D 584E8200    xor ecx,dword ptr ds:[824E58]
00403F8C    |.  81F9 953B962D    cmp ecx,2D963B95
00403F92    |.  74 61            je short aptedit.00403FF5

依旧把je short aptedit.00403FF5改成无条件的跳转,然后保存,运行OK!
终于大功告成!!!


00403F31    |>  8B?? ????FFFF    /mov edx,dword ptr ss:[ebp-2564]  //又一个自校验代码段
00403F37    |.  3B?? ????FFFF    |cmp edx,dword ptr ss:[ebp-2570]
00403F3D    |.  73 41            |jnb short aptedit.00403F80

004056BD    |> /8B85 90D7FFFF    /mov eax,dword ptr ss:[ebp-2870]
004056C3    |. |3B85 84D7FFFF    |cmp eax,dword ptr ss:[ebp-287C]
004056C9    |. |73 41            |jnb short CrackEd.0040570C

比较一下自校验代码的特征,然后在OD直接搜索:
8B ?? ?? ?? FF FF 3B ?? ?? ?? FF FF 73 41

又找到三处似是检验的代码:


00403A74    |.  81F9 78E5D0B5    cmp ecx,B5D0E578
00403A7A    |.  74 32            je short aptedit.00403AAE

004048E2    |.  81FA BB4F914C    cmp edx,4C914FBB
004048E8    |.  74 61            je short aptedit.0040494B

004255E1    |.  81FA F8D4FDD1    cmp edx,D1FDD4F8
004255E7    |.  74 5B            je short aptedit.00425644

我在程序验证中没碰到,大家有兴趣的可以自己看看!既然是验证,肯定是用来保护关键的代码段的!

“AptEdit pro 5.1.0 Build 394的破解分析”的一个回复

发表评论