首页 > 代码库 > [反汇编练习] 160个CrackMe之004

[反汇编练习] 160个CrackMe之004

[反汇编练习] 160个CrackMe之004.

本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。

其中,文章中按照如下逻辑编排(解决如下问题):

1、使用什么环境和工具

2、程序分析

3、思路分析和破解流程

4、注册机的探索

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

提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大,只要你跟踪了,不用怎么看代码就理解了!

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

1、工具和环境:

WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。

160个CrackMe的打包文件。

下载地址: http://pan.baidu.com/s/1xUWOY  密码: jbnq

注:

1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。

2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。

wps_clip_image-23705

2、程序分析:

想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。

和上一节一样,打开CHM,选择第4个ajj,保存下来。运行程序,程序界面如下:

wps_clip_image-6672

这似乎是一个标准的Name/Serial注册码方式,二话不说,来个伪码测试:

Name: 3333     Serial: 44445555

但是,但是什么提示也没有,只有一个鼠标提示,我点,我点,编辑框,灰色的小框框,我单击,我双击,KAO,啥提示也没有。

还是看看说明书吧:

前两天我和[CCG]的大哥Sun Bird兄闲聊时引出一个话题,
我要想想办法难为一下Sun Bird兄。
因此就用了两个半天的时间,作了一个小东东。
这个CKme与一般的软件注册过程不一样,它没有"确定"键,
当然CK这样的软件其实一点也不麻烦,没遇到过的朋友可要动动脑子了。     8)
另外这个CKme还作了一点别的手脚,不多说了,自己看着办吧。
这个软件是用Delphi编的,由于我刚学了一星期的Delphi,
有很多想法在这个小程序里没有实现,因此这个CKme应该算是比较简单的了。
如果你成功的注册了,请给我来封信好吗?谢谢!!!
还有你千万不要告诉我你只用了2分钟就搞定了,如果是这样我就。。8~~~(

                            ajj
                            2000/08/30

好吧,这位大哥再给我们玩猜谜呢!

 

3、思路分析和破解流程:

这个程序就像作者说的,诡异的不知道到底是那里出发判断,无论点什么地方都没有任何提示。查一下壳:Delphi的,没有加壳。对Delphi不了解,没关系,我们先尝试熟悉的程序的方式看看是否能行。

个人比较擅长VC,先按照VC思路思考一下程序可能会通过什么方式触发检测序列号动作:

1、要进行序列号检测,必须的获取Name/Serial的文本,在VC中WM_GETTEXT消息用来获取文本使用,我们可以通过对Edit控件下消息断点,然后看看是否能得到一些信息。操作:菜单->View->Windows,很容易就看到了标题,Class名称为TForm1,右键Message Breakpoint on callproc,找到WM_GetText消息,确定。这时无论我们怎么尝试都无法断下。没办法,对delphi不了解,再试试别的。

2、在第一个的基础上尝试WM_KEYDOWN/WM_KEYUP消息,API断点(GetWindowTextW/A),发现都无法获得任何信息。

尝试到这里,只说明了一个问题,Delphi并不是简单地封装了API函数,所以我们无法通过这方面来进行筛选和拦截。

退一步,我们的目的是破解这个程序,所以只要能够找到和关键跳转相关的东西就行。进论坛,搜了一大桶,原来除了堆栈找法,还有很多看起来很小白的方法,比如最碰运气的【字符串查找】,如果程序中有很多和流程相关的字符串,我们就可以根据字符串的意思猜测程序的流程。Ctrl+E(E图标),选中CKme.exe模块,右键->Follow entry,这样我们就在主程序模块,然后右键->中文搜索引擎->智能搜索,哈哈哈,终于露出狐狸的小尾巴了!我们发现有一个很明显的中文字符串【恭喜恭喜!注册成功】,二话不说,跟进去。

0045803B     /75 76         jnz short 004580B3                       ;  // 关键跳,爆破这里就可以了0045803D  |. |33DB          xor ebx,ebx0045803F  |> |8D55 E4       /lea edx,[local.7]00458042  |. |8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]00458048  |. |E8 FBB2FCFF   |call 004233480045804D  |. |8B45 E4       |mov eax,[local.7]00458050  |. |E8 27BBFAFF   |call 00403B7C00458055  |. |83C0 03       |add eax,0x300458058  |. |8D55 E8       |lea edx,[local.6]0045805B  |. |E8 A4FAFAFF   |call 00407B0400458060  |. |FF75 E8       |push [local.6]00458063  |. |8D55 E0       |lea edx,[local.8]00458066  |. |8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]0045806C  |. |E8 D7B2FCFF   |call 0042334800458071  |. |FF75 E0       |push [local.8]00458074  |. |8D55 DC       |lea edx,[local.9]00458077  |. |8BC3          |mov eax,ebx00458079  |. |E8 86FAFAFF   |call 00407B040045807E  |. |FF75 DC       |push [local.9]00458081  |. |8D45 FC       |lea eax,[local.1]00458084  |. |BA 03000000   |mov edx,0x300458089  |. |E8 AEBBFAFF   |call 00403C3C0045808E  |. |43            |inc ebx0045808F  |. |83FB 13       |cmp ebx,0x1300458092  |.^|75 AB         \jnz short 0045803F00458094  |. |33D2          xor edx,edx00458096  |. |8B86 F0020000 mov eax,dword ptr ds:[esi+0x2F0]0045809C  |. |E8 BFB1FCFF   call 00423260004580A1  |. |A1 20B84500   mov eax,dword ptr ds:[0x45B820]004580A6  |. |83C0 70       add eax,0x70004580A9  |. |BA 14814500   mov edx,00458114                         ;  恭喜恭喜!注册成功004580AE  |. |E8 9DB8FAFF   call 00403950

到CALL的地方后,向上查看代码,很容易就找到了两个JNZ,最近的那个一直在循环,不会跳过中文的提示,而最上面的那个jnz short 004580B3 一眼就能看到它会跳出正确提示,SO,爆破很easy啦!选中这个JNZ,右键->Binary->Fill with NOPs. 随意输入Name/Serial试试,OK,非常完美,收工!

4、注册机的探索:

我们的目的不单单是爆破他,尽量算出注册码,SO,找到代码头,输入伪码:

Name: 112233   Serial: 44445555

下断,F8分析:

00457FB8  /.  55            push ebp                                   ;  00A053D800457FB9  |.  8BEC          mov ebp,esp00457FBB  |.  B9 04000000   mov ecx,0x400457FC0  |>  6A 00         /push 0x000457FC2  |.  6A 00         |push 0x000457FC4  |.  49            |dec ecx00457FC5  |.^ 75 F9         \jnz short 00457FC0                        ;  // 毫无意义地循环了4次00457FC7  |.  51            push ecx00457FC8  |.  53            push ebx00457FC9  |.  56            push esi                                   ;  //00A053D800457FCA  |.  8BF0          mov esi,eax                                ;  // esi=00A019CC=纹E00457FCC  |.  33C0          xor eax,eax00457FCE  |.  55            push ebp00457FCF  |.  68 FD804500   push 004580FD00457FD4  |.  64:FF30       push dword ptr fs:[eax]00457FD7  |.  64:8920       mov dword ptr fs:[eax],esp00457FDA  |.  33DB          xor ebx,ebx00457FDC  |>  8D55 F4       /lea edx,[local.3]00457FDF  |.  8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]00457FE5  |.  E8 5EB3FCFF   |call 0042334800457FEA  |.  8B45 F4       |mov eax,[local.3]                         ;  // eax=112233 字符串地址00457FED  |.  E8 8ABBFAFF   |call 00403B7C00457FF2  |.  83C0 1E       |add eax,0x1E                              ;  // eax=6+1E=0x2400457FF5  |.  8D55 F8       |lea edx,[local.2]00457FF8  |.  E8 07FBFAFF   |call 00407B04                             ;  // 修改了edx地址处的值为3600457FFD  |.  FF75 F8       |push [local.2]                            ;  // ecx=0x2400458000  |.  8D55 F0       |lea edx,[local.4]00458003  |.  8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]00458009  |.  E8 3AB3FCFF   |call 004233480045800E  |.  FF75 F0       |push [local.4]                            ;  // ss=11223300458011  |.  8D55 EC       |lea edx,[local.5]00458014  |.  8BC3          |mov eax,ebx00458016  |.  E8 E9FAFAFF   |call 00407B040045801B  |.  FF75 EC       |push [local.5]0045801E  |.  8D45 FC       |lea eax,[local.1]00458021  |.  BA 03000000   |mov edx,0x300458026  |.  E8 11BCFAFF   |call 00403C3C0045802B  |.  43            |inc ebx                                   ;  ebx=0++0045802C  |.  83FB 13       |cmp ebx,0x13                              ;  // 不知道为什么比较了0x13次0045802F  |.^ 75 AB         \jnz short 00457FDC                        ;  // 这个形成了一个xxName18的字符串,361122331800458031  |.  81BE 0C030000>cmp dword ptr ds:[esi+0x30C],0x85          ;  // esi是关键点0045803B      75 76         jnz short 004580B3                         ;  // 关键跳,爆破这里就可以了0045803D  |.  33DB          xor ebx,ebx0045803F  |>  8D55 E4       /lea edx,[local.7]00458042  |.  8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]00458048  |.  E8 FBB2FCFF   |call 004233480045804D  |.  8B45 E4       |mov eax,[local.7]00458050  |.  E8 27BBFAFF   |call 00403B7C00458055  |.  83C0 03       |add eax,0x300458058  |.  8D55 E8       |lea edx,[local.6]0045805B  |.  E8 A4FAFAFF   |call 00407B0400458060  |.  FF75 E8       |push [local.6]00458063  |.  8D55 E0       |lea edx,[local.8]00458066  |.  8B86 D4020000 |mov eax,dword ptr ds:[esi+0x2D4]0045806C  |.  E8 D7B2FCFF   |call 0042334800458071  |.  FF75 E0       |push [local.8]00458074  |.  8D55 DC       |lea edx,[local.9]00458077  |.  8BC3          |mov eax,ebx00458079  |.  E8 86FAFAFF   |call 00407B040045807E  |.  FF75 DC       |push [local.9]00458081  |.  8D45 FC       |lea eax,[local.1]00458084  |.  BA 03000000   |mov edx,0x300458089  |.  E8 AEBBFAFF   |call 00403C3C0045808E  |.  43            |inc ebx0045808F  |.  83FB 13       |cmp ebx,0x1300458092  |.^ 75 AB         \jnz short 0045803F00458094  |.  33D2          xor edx,edx00458096  |.  8B86 F0020000 mov eax,dword ptr ds:[esi+0x2F0]0045809C  |.  E8 BFB1FCFF   call 00423260004580A1  |.  A1 20B84500   mov eax,dword ptr ds:[0x45B820]004580A6  |.  83C0 70       add eax,0x70004580A9  |.  BA 14814500   mov edx,00458114                           ;  恭喜恭喜!注册成功004580AE  |.  E8 9DB8FAFF   call 00403950004580B3  |>  33C0          xor eax,eax

这段代码对Name进行了处理,在堆栈中得到了一个类似3611223318的字符串,但是比较的时候使用的是cmp dword ptr ds:[esi+0x30C],0x85,esi+0x30C地址处的值才是真正影响结果的,翻看代码发现,没有任何地方修改了这个值,没办法,重新断在循环头部,db [esi+0x30C],对内容下内容写入断点,取消其他断点,F9运行,尝试。。。

悲剧了,什么也找不到。

多次尝试此代码段的上层代码和跟踪内部CALL代码,无法找到有用的信息。实在没办法了,继续求救大神吧!

搜索发现了两点有用的信息:

1、看雪论坛找到了一个正确的Name/Serial。Name: findlakes   Serial: 黑头Sun Bird14dseloffc-012-OKfindlakes

2、OD对于Delphi程序确实有些乏力,反汇编Delphi有更好的软件Dede。

 

下面我们尝试使用Dede反编译它(工具下载链接里有):

如图,在窗体选项中发现注册码编辑框TEdit2有OnKeyUp事件chkcode。

wps_clip_image-15819

在过程选项中,双击chkcode查看代码:

wps_clip_image-13929

代码如下:

00457C40   55                     push    ebp00457C41   8BEC                   mov     ebp, esp00457C43   51                     push    ecx00457C44   B905000000             mov     ecx, $0000000500457C49   6A00                   push    $0000457C4B   6A00                   push    $0000457C4D   49                     dec     ecx00457C4E   75F9                   jnz     00457C4900457C50   51                     push    ecx00457C51   874DFC                 xchg    [ebp-$04], ecx00457C54   53                     push    ebx00457C55   56                     push    esi00457C56   8BD8                   mov     ebx, eax00457C58   33C0                   xor     eax, eax00457C5A   55                     push    ebp00457C5B   683D7E4500             push    $00457E3D...

OK,关闭Dede,我们在OD中加载它:

Ctrl+G 转到开头地址: 00457C40,向上找到段头,开始F8分析:

00457C1C   .  53 75 6E 20 4>ascii "Sun Bird",000457C25      00            db 0000457C26      00            db 0000457C27      00            db 0000457C28   .  FFFFFFFF      dd FFFFFFFF00457C2C   .  0F000000      dd 0000000F00457C30   .  64 73 65 6C 6>ascii "dseloffc-012-OK",000457C40  /.  55            push ebp                                 ;  // 这里是头部,下断00457C41  |.  8BEC          mov ebp,esp00457C43  |.  51            push ecx00457C44  |.  B9 05000000   mov ecx,0x500457C49  |>  6A 00         /push 0x000457C4B  |.  6A 00         |push 0x000457C4D  |.  49            |dec ecx00457C4E  |.^ 75 F9         \jnz short 00457C49                      ;  // 无意义的循环00457C50  |.  51            push ecx00457C51  |.  874D FC       xchg [local.1],ecx00457C54  |.  53            push ebx00457C55  |.  56            push esi00457C56  |.  8BD8          mov ebx,eax00457C58  |.  33C0          xor eax,eax00457C5A  |.  55            push ebp00457C5B  |.  68 3D7E4500   push 00457E3D00457C60  |.  64:FF30       push dword ptr fs:[eax]00457C63  |.  64:8920       mov dword ptr fs:[eax],esp00457C66  |.  8BB3 F8020000 mov esi,dword ptr ds:[ebx+0x2F8]00457C6C  |.  83C6 05       add esi,0x500457C6F  |.  FFB3 10030000 push dword ptr ds:[ebx+0x310]            ;  // (ASCII "黑头Sun Bird")00457C75  |.  8D55 F8       lea edx,[local.2]00457C78  |.  8BC6          mov eax,esi00457C7A  |.  E8 85FEFAFF   call 00407B0400457C7F  |.  FF75 F8       push [local.2]                           ;  // 1000457C82  |.  FFB3 14030000 push dword ptr ds:[ebx+0x314]            ;  //  (ASCII "dseloffc-012-OK")00457C88  |.  8D55 F4       lea edx,[local.3]00457C8B  |.  8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4]00457C91  |.  E8 B2B6FCFF   call 0042334800457C96  |.  FF75 F4       push [local.3]                           ;  // ASCII bbdxf00457C99  |.  8D83 18030000 lea eax,dword ptr ds:[ebx+0x318]00457C9F  |.  BA 04000000   mov edx,0x400457CA4  |.  E8 93BFFAFF   call 00403C3C00457CA9  |.  33D2          xor edx,edx00457CAB  |.  8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]00457CB1  |.  E8 AAB5FCFF   call 0042326000457CB6  |.  8B93 18030000 mov edx,dword ptr ds:[ebx+0x318]         ;  //(ASCII "黑头Sun Bird10dseloffc-012-OKbbdxf")00457CBC  |.  8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]00457CC2  |.  E8 B1B6FCFF   call 00423378                            ;  // 根据我们之前查找的资料,上面的字符串其实就是注册码了00457CC7  |.  33F6          xor esi,esi00457CC9  |>  8D55 EC       /lea edx,[local.5]                       ;  // 0x13 次不知道干什么的循环00457CCC  |.  8B83 D4020000 |mov eax,dword ptr ds:[ebx+0x2D4]00457CD2  |.  E8 71B6FCFF   |call 0042334800457CD7  |.  8B45 EC       |mov eax,[local.5]00457CDA  |.  E8 9DBEFAFF   |call 00403B7C00457CDF  |.  83C0 03       |add eax,0x300457CE2  |.  8D55 F0       |lea edx,[local.4]00457CE5  |.  E8 1AFEFAFF   |call 00407B0400457CEA  |.  FF75 F0       |push [local.4]00457CED  |.  8D55 E8       |lea edx,[local.6]00457CF0  |.  8B83 D4020000 |mov eax,dword ptr ds:[ebx+0x2D4]00457CF6  |.  E8 4DB6FCFF   |call 0042334800457CFB  |.  FF75 E8       |push [local.6]00457CFE  |.  8D55 E4       |lea edx,[local.7]00457D01  |.  8BC6          |mov eax,esi00457D03  |.  E8 FCFDFAFF   |call 00407B0400457D08  |.  FF75 E4       |push [local.7]00457D0B  |.  8D45 FC       |lea eax,[local.1]00457D0E  |.  BA 03000000   |mov edx,0x300457D13  |.  E8 24BFFAFF   |call 00403C3C00457D18  |.  46            |inc esi00457D19  |.  83FE 13       |cmp esi,0x1300457D1C  |.^ 75 AB         \jnz short 00457CC900457D1E  |.  8D55 E0       lea edx,[local.8]00457D21  |.  8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]00457D27  |.  E8 1CB6FCFF   call 00423348

实在是被Delphi折磨的不能行了,注册码很简单,特别是根据开头的几个ANSI能够看出来,他就是固定的字符串加上我们的Name,即"黑头Sun Bird10dseloffc-012-OK"+Name。随便怎么搞都没问题。

总结一下:这个CrackMe就像作者说的,更多的算是一个小游戏,再加上Delphi不熟,做完之后实在感到有些鸡肋,不过,相信,所有的付出都会有收获的,只是时间的问题。加油!

 

BY  笨笨D幸福