吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12671|回复: 31
收起左侧

[原创] 初练160个CrakeMe程序之007

  [复制链接]
海天一色001 发表于 2017-6-3 13:44
本帖最后由 海天一色001 于 2017-6-3 13:53 编辑

7CM,还是先打开看看是什么情况:
01.png
仍然是用户名/注册码形式的,随意输入用户名和注册码,点Register键,没任何反应;再点Cancella键,注册码清零;继续点击Register键,出现信息框要求注册码大于0。再点About-Help,四个信息窗口出来了。大概意思是最好不爆破打补丁,要找出对应的用户名和注册码,隐藏下面的按钮。与上一个有些类似,肯定是更难了!老规矩,先查壳:
02.png
没壳,Delphi程序,还是先汉化一下吧,目的仍然是对各种软件工具的熟悉和掌握。具体过程和上一个基本一致,利用ResScopeOD基本上完成了,汉化程序另存为cm007.exe;给个界面: 03.png           06.png
点击注册按钮后见右上图,有点小问题:如果注册码输入非纯数字,如下图:
04_1.png
点击关于-帮助按钮后:
04.png

05.png
后面还有两条提示信息,和上一个CM中的提示一样,因为没什么有用信息,我没有对它们汉化,直接又练习了一次去掉弹出窗口:如下图将地址00442CDC至00442CEB处的代码全部nop掉,再保存到可执行文件后,就去除了后两个弹出信息窗口。
07.png
在保存到可执行文件时提示文件基址有变化,是否保存,我还是保存了,保存后发现文件中地址确实有了变化,但功能没有什么影响,对比图如下:
08.png

09.png
上一张图是原程序的代码,先将字符串赋值给eax,再把eax作为call的参数,运行call来显示提示信息,下一张是修改汉化后的代码,可以看出是使用直接显示字符串的方法。经测试,修改后的程序能够正常运行,所以就这样保存下来了。好了,虽然程序要求找算法,但为了练习,我还是先爆破再追码:Delphi程序有IDA等软件进行反汇编,可以进行更有效的分析,可是我不会!哪位大神有中文版的使用教程啊?还是请出DeDe出场,看到了这些熟悉的过程:
10.png
AboutClick事件就不用跟踪了,其他三个事件都要进去分析。还是对照Dede中的注释在OD中去分析各个事件的代码:
11.png
第一次爆破:OD载入CM007.exeCtrl+E,粘贴入Dede中复制来的RAV(内存地址) 00442F28”,到达RegisterzClick事件段首,F2下断点:F9运行程序,输入用户名“52pojie.cn”,注册码“1111111111”,点击注册按钮,程序中断,F8单步向下:到达地址00442F60处,指令为cmp [local.1],0x0 ,下句是跳过失败的jz指令。此处的指令在Dede中反编译出来的是“cmp dword ptr [ebp-$04], +$00”,总算是知道了这个地址的由来!同时猜测[local.1]的值应该是决定按钮隐藏与否的值。
12.png
向下查看代码,有三个跳转指令跳过了隐藏注册按钮,显示Again按钮,走向失败,而本句的指令跳过了第一个走向失败的jmp指令,所以此处可以不动;此时关键call不再执行,所以要继续向下到达00442F9B地址处,因为怕上一个跳过本条指令的je指令失效,所以将这里nop掉!一直单步向下,同样将两个跳到失败的语句nop掉,一条在紧挨着第一个跳转到失败指令的00442F9F处,一条在00442FC0处。
13.png
这三个跳转失效,继续单步到段尾处,F9,程序果然将注册按钮隐藏了,不过又显出了一个“再次”的按钮!(见左下图)
14.png
其实到这里,根据上一个CM和这里的实际情况,再在00442FCF地址处将mov dl,0x1改成mov dl 0x0,就可以让再次按钮根本不显示!修改之后,将全部修改保存到可执行文件CM007_Register_nop.exe中!运行CM007_Register_nop.exe,果然点击注册按钮,自身隐藏起来了,“再次”按钮也没有出现!
15.png
第二次爆破:虽然爆破法很暴力,但在00442FCF地址处将mov dl,0x1改成mov dl 0x0也有点太粗暴了,毕竟程序还要显示出来一个“再次”按钮的,那么撤消此处的修改,继续爆破:004430BC处下断,点击再次按钮,程序断在了AgainClick事件段首。观察本段代码,与注册按钮事件很相似,那么先按照上一个思路,同样将三个跳转(0044312D处的jmp,00443134处的jle,00443159处的jenop掉。因为此时按钮已全部隐藏了,干脆将全部修改复制到可执行文件CM007_again_nop.exe中,打开CM007_again_nop.exe,如下左图:点击注册,如下中图:再点击再次,如下右图,爆破成功!有点不舒服的是隐藏再次按钮后程序标题有点小乱,其实是点击再次按钮后,标题栏要加上用户名,因为爆破不完全,使字符看起来不正确了。
16.png           17.png           18.png
这种爆破方法要修改好几个跳转语句,有点太过于直接,还是应该找到关键call和关键跳,直接修改关键call的返回值,使之符合关键跳成功的条件。这样分析起来可能要费劲些,但修改的地方就少了,可能修改一个地方或者两个地方就能爆破成功了。第三次爆破:重载程序,F9,输入用户名“52pojie.cn”,注册码“1234567890”,点击注册按钮,程序中断。F8向下,走到00442F59处,一时不注意F7跟入00402958这个call了。既然进来了,就单步看看是干什么的吧。仔细分析,发现这是对输入的注册码进行判断和处理的子程序,如果注册码字符不符合程序内含条件,则跳出失败的提示;如果首字符是“-+Xx$”等特殊值时进行新的计算,最后得到处理注册码后的数值存入eax中。再来到00442F60地址处,可以认为栈[local.1]中的值是判断注册码输入格式正确与否的,正确则跳走,不正确则跳出错误提示框
[Asm] 纯文本查看 复制代码
00442F4E  |.  E8 ED02FEFF   call CM007.00423240                      ;  controls.TControl.GetText(TControl):TCaption;得到假码和假码长度
00442F53  |.  8B45 F8       mov eax,[local.2]                        ;  mov eax, [ebp-$08],取假码
00442F56  |.  8D55 FC       lea edx,[local.1]                        ;  lea edx, [ebp-$04]
00442F59  |.  E8 FAF9FBFF   call CM007.00402958                      ;  * Reference to: system.@ValLong;判断假码第一个字符是不是空格、+、-、X、x、$等特殊字符,最后得到假码的16进制数值存入eax中
00442F5E  |.  8BF0          mov esi,eax                        ;  esi=假码的16进制数值
00442F60  |.  837D FC 00    cmp [local.1],0x0                        ;  cmp dword ptr [ebp-$04], +$00:第一个判断:此处的地址存入的值应该是判断注册码输入正误的值
00442F64      74 37         je short CM007.00442F9D                  ;  假码输入格式正确则跳,错误不跳,不用动
00442F66  |.  B8 38304400   mov eax,CM007.00443038                   ;  eax为在注册码编辑栏中输入一个有效数值的提示内容
00442F6B  |.  E8 00F6FFFF   call CM007.00442570                      ;  dialogs.ShowMessage(AnsiString);显示提示信息框
00442F70  |.  8D55 F8       lea edx,[local.2]                        ;  lea edx, [ebp-$08]
00442F73  |.  8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]         ;  * Reference to control Codice : TLabel
00442F79  |.  E8 C202FEFF   call CM007.00423240                      ;  controls.TControl.GetText(TControl):得到字符串及其长度
00442F7E  |.  8B45 F8       mov eax,[local.2]                        ;  mov eax, [ebp-$08]:eax=假码
00442F81  |.  E8 06FBFFFF   call CM007.00442A8C                      ;  * Reference to : TPrincipale._PROC_00442A8C()
00442F86  |.  A3 30584400   mov dword ptr ds:[0x445830],eax
00442F8B  |.  BA 90304400   mov edx,CM007.00443090                   ;  edx为注册码,上面判断出是错误的,所以用0代替它
00442F90  |.  8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]         ;  * Reference to control Codice : TLabel
00442F96  |.  E8 D502FEFF   call CM007.00423270                      ;  * Reference to: controls.TControl.SetText(TControl;TCaption);
00442F9B      EB 6F         jmp short CM007.0044300C                 ;  跳过了隐藏注册按钮,显示Again按钮,走向失败
00442F9D  |>  85F6          test esi,esi                             ;  第二个判断处,看假码是否小于等于0
00442F9F      7E 5A         jle short CM007.00442FFB                 ;  跳过了隐藏注册按钮,显示Again按钮,走向失败
00442FA1  |.  8D55 F8       lea edx,[local.2]                        ;  lea edx, [ebp-$08]
00442FA4  |.  8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]         ;  * Reference to control Nome : TLabel
00442FAA  |.  E8 9102FEFF   call CM007.00423240                      ;  * Reference to: controls.TControl.GetText(TControl):TCaption;
00442FAF  |.  8B4D F8       mov ecx,[local.2]                        ;  mov ecx, [ebp-$08],ecx=用户名
00442FB2  |.  8BD6          mov edx,esi
00442FB4  |.  A1 30584400   mov eax,dword ptr ds:[0x445830]
00442FB9  |.  E8 EAF9FFFF   call CM007.004429A8                      ;  关键Call,参数为eax=0?,edx=假码的16进制值,ecx=用户名
00442FBE  |.  84C0          test al,al                               ;  第三个判断
00442FC0      74 30         je short CM007.00442FF2                  ;  跳过了隐藏注册按钮,显示Again按钮,走向失败
00442FC2  |.  33D2          xor edx,edx
00442FC4  |.  8B83 CC020000 mov eax,dword ptr ds:[ebx+0x2CC]         ;  * Reference to control Registerz : TButton
00442FCA  |.  E8 6101FEFF   call CM007.00423130                      ;  * Reference to: controls.TControl.SetVisible(TControl;Boolean);
00442FCF      B2 01         mov dl,0x1
00442FD1  |.  8B83 E8020000 mov eax,dword ptr ds:[ebx+0x2E8]         ;  * Reference to control Again : TButton
00442FD7  |.  E8 5401FEFF   call CM007.00423130                      ;  * Reference to: controls.TControl.SetVisible(TControl;Boolean);
00442FDC  |.  33D2          xor edx,edx
00442FDE  |.  8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]         ;  * Reference to control Nome : TLabel
00442FE4  |.  8B08          mov ecx,dword ptr ds:[eax]
00442FE6  |.  FF51 60       call dword ptr ds:[ecx+0x60]
00442FE9  |.  33C0          xor eax,eax
00442FEB  |.  A3 30584400   mov dword ptr ds:[0x445830],eax
00442FF0  |.  EB 1A         jmp short CM007.0044300C
继续来到00442FB9处,对照Dede发现此处的call没有明确的注释,可能就是关键call了!仔细分析程序代码,第三个判断处下面是隐藏注册按钮,显示Again按钮的代码,下面是关键跳,在它上面的就是关键call了。F7跟入关键call中,004429A8处下断,F8向下:
[Asm] 纯文本查看 复制代码
004429A8  /$  55            push ebp                                 ;  关键Call,计算与判断注册码
004429A9  |.  8BEC          mov ebp,esp
004429AB  |.  83C4 F4       add esp,-0xC
004429AE  |.  53            push ebx
004429AF  |.  56            push esi
004429B0  |.  57            push edi
004429B1  |.  894D F8       mov [local.2],ecx                        ;  用户名入栈
004429B4  |.  8955 FC       mov [local.1],edx
004429B7  |.  8BF8          mov edi,eax
004429B9  |.  8B45 F8       mov eax,[local.2]                        ;  取用户名
004429BC  |.  E8 2712FCFF   call CM007.00403BE8                      ;  结果是edx=2????
004429C1  |.  33C0          xor eax,eax
004429C3  |.  55            push ebp
004429C4  |.  68 7A2A4400   push CM007.00442A7A
004429C9  |.  64:FF30       push dword ptr fs:[eax]
004429CC  |.  64:8920       mov dword ptr fs:[eax],esp
004429CF  |.  8B45 F8       mov eax,[local.2]                        ;  取用户名
004429D2  |.  E8 5D10FCFF   call CM007.00403A34                      ;  取用户名长度,返回eax中
004429D7  |.  83F8 04       cmp eax,0x4                              ;  用户名长度不能小于4位
004429DA  |.  0F8E 82000000 jle CM007.00442A62                       ;  跳则死
004429E0  |.  33DB          xor ebx,ebx                              ;  ebx=0
004429E2  |.  8B45 F8       mov eax,[local.2]                        ;  取用户名
004429E5  |.  E8 4A10FCFF   call CM007.00403A34                      ;  取用户名长度
004429EA  |.  85C0          test eax,eax
004429EC  |.  7E 38         jle short CM007.00442A26
004429EE  |.  8945 F4       mov [local.3],eax                        ;  用户名长度入栈
004429F1  |.  BE 01000000   mov esi,0x1                              ;  esi=1,循环的起始序号
004429F6  |>  8B45 F8       /mov eax,[local.2]                       ;  取用户名
004429F9  |.  E8 3610FCFF   |call CM007.00403A34                     ;  取用户名长度
004429FE  |.  83F8 01       |cmp eax,0x1                             ;  eax>1
00442A01  |.  7C 1D         |jl short CM007.00442A20
00442A03  |>  8B55 F8       |/mov edx,[local.2]                      ;  edx=用户名
00442A06  |.  0FB65432 FF   ||movzx edx,byte ptr ds:[edx+esi-0x1]    ;  取每次循环后用户名的第一个字符的16进制ASCII值
00442A0B  |.  8B4D F8       ||mov ecx,[local.2]                      ;  ecx=用户名
00442A0E  |.  0FB64C01 FF   ||movzx ecx,byte ptr ds:[ecx+eax-0x1]    ;  取每次循环后用户名的最后一个字符的16进制ASCII值
00442A13  |.  0FAFD1        ||imul edx,ecx                           ;  edx=edx*ecx;第一位乘以最后一位
00442A16  |.  0FAFD7        ||imul edx,edi                           ;  edx=edx*edi   edi为0,得edx=0
00442A19  |.  03DA          ||add ebx,edx                            ;  ebx=ebx+edx;;可是ebx也是0,结果还是0
00442A1B  |.  48            ||dec eax                                ;  eax递减
00442A1C  |.  85C0          ||test eax,eax                           ;  检测eax是否为0
00442A1E  |.^ 75 E3         |\jnz short CM007.00442A03               ;  循环结果是eax=0,ecx=用户名第一位字符的16进制ASCII值,edx=0
00442A20  |>  46            |inc esi
00442A21  |.  FF4D F4       |dec [local.3]
00442A24  |.^ 75 D0         \jnz short CM007.004429F6                ;  循环结果是eax=0,ecx=用户名第一位字符的16进制ASCII值,esi=用户名长度+1
00442A26  |>  8BC3          mov eax,ebx
00442A28  |.  99            cdq
00442A29  |.  33C2          xor eax,edx
00442A2B  |.  2BC2          sub eax,edx
00442A2D  |.  B9 2A2C0A00   mov ecx,0xA2C2A
00442A32  |.  99            cdq
00442A33  |.  F7F9          idiv ecx                                 ;  结果是eax=0!!!!!
00442A35  |.  8BDA          mov ebx,edx
00442A37  |.  8B45 FC       mov eax,[local.1]                        ;  【local.1】的值才是真正开始计算的值,是假码的16进制数值
00442A3A  |.  B9 59000000   mov ecx,0x59
00442A3F  |.  99            cdq
00442A40  |.  F7F9          idiv ecx                                 ;  eax/0x59,商入eax,余数入edx
00442A42  |.  8BC8          mov ecx,eax                              ;  ecx=eax,即上面算式结果取整
00442A44  |.  8B45 FC       mov eax,[local.1]
00442A47  |.  BE 50000000   mov esi,0x50
00442A4C  |.  99            cdq
00442A4D  |.  F7FE          idiv esi                                 ;  eax/esi,商入eax,余数入edx
00442A4F  |.  03CA          add ecx,edx                              ;  【local.1】/0x59取整后的数+【local.1】/0x50取余的数
00442A51  |.  41            inc ecx                                  ;  ecx=ecx+1
00442A52  |.  894D FC       mov [local.1],ecx                        ;  ecx就是最终的结果
00442A55  |.  3B5D FC       cmp ebx,[local.1]                        ;  ebx与注册码比较
00442A58     /75 04         jnz short CM007.00442A5E                 ;  也可以在这里nop,其他地方就不用nop了
00442A5A  |.  B3 01         mov bl,0x1                               ;  bl=1,正确
00442A5C  |.  EB 06         jmp short CM007.00442A64
00442A5E  |>  33DB          xor ebx,ebx                              ;  bl=0,错误
00442A60  |.  EB 02         jmp short CM007.00442A64
00442A62  |>  33DB          xor ebx,ebx
00442A64  |>  33C0          xor eax,eax
00442A66  |.  5A            pop edx                                  ;  0012F6A4
00442A67  |.  59            pop ecx                                  ;  0012F6A4
00442A68  |.  59            pop ecx                                  ;  0012F6A4
00442A69  |.  64:8910       mov dword ptr fs:[eax],edx
00442A6C  |.  68 812A4400   push CM007.00442A81
00442A71  |>  8D45 F8       lea eax,[local.2]
00442A74  |.  E8 3F0DFCFF   call CM007.004037B8
00442A79  \.  C3            retn
00442A7A   .^ E9 F907FCFF   jmp CM007.00403278
00442A7F   .^ EB F0         jmp short CM007.00442A71
00442A81   .  8BC3          mov eax,ebx
00442A83   .  5F            pop edi                                  ;  0012F6A4
00442A84   .  5E            pop esi                                  ;  0012F6A4
00442A85   .  5B            pop ebx                                  ;  0012F6A4
00442A86   .  8BE5          mov esp,ebp
00442A88   .  5D            pop ebp                                  ;  0012F6A4
00442A89   .  C3            retn
从整个call运行的结果看,返回值是al=1或者0,而al=0则死,那么干脆在call的第一句就赋值:mov al,0x1,第二句就retn!运行程序,果然注册按钮隐藏起来,再次按钮显示了。点击再次按钮,程序中断到AgainClick事件段首,F8继续,运行到00443152处,出现了“call CM007.004429A8”这个指令,和RegisterzClick事件调用的同一个关键Call!那么就不用再单步走了,直接F9,再次按钮也隐藏了!将这个修改保存到CM007_call_retn.exe中,试运行一下,成功!这种爆破将关键call里的运算全部屏蔽掉了,而且修改的地方很少,此时程序可以不用输入用户名;还可以在关键call00442A58地址处将跳转语句nop掉,这时bl=1,继续运行后又将ebx的值传给了eax,同样使整个call的返回值变成al=0,这样的修改保存为CM007_call_nop.exe,这样爆破掉整个程序,必须输入用户名和注册码。在我们改好以上之后,可以看到注册按钮和再次按钮都消失了。不过对照上个CMCannellaClick事件中还有很重要的算法,也不能掉以轻心!OD中给CannellaClick事件段首下断,点击清零按钮,程序中断,F8向下分析,很快来到关键call和关键跳处:
[Asm] 纯文本查看 复制代码
00442BD2  |.  8B45 F4       mov eax,[local.3]
00442BD5  |.  5A            pop edx
00442BD6  |.  E8 55FFFFFF   call aLoNg3x_.00442B30                   ;关键call
00442BDB  |.  84C0          test al,al
00442BDD  |.  0F84 86000000 je aLoNg3x_.00442C69 

关键跳00442BD6处的call追入查看,得知仍是利用用户名和注册码计算后,然后返回al是否为0,不为0则完成破解,为0时则将注册码清零。所以在这里仍然可以将00442BDDnop掉,
26.png
或者进入00442B30call中,用retn大法或者nop00442B66处的跳,也可以将00442B6C处的指令改为“mov bl,0x1”,最终达到的效果是点击清零按钮,出现GREATLAMER两个信息框,完全爆破程序!此处爆破后我是nop00442B66处的跳,最终保存为CM007_end_nop.exe。其他几种请大家自行测试吧。在爆破过程中发现,第二个信息框的字符“LAMER”是利用“GREAT”变换而来的,大家也可以试着改改,不过用途不是很大。爆破成功,接下来是追码,尽量编写出注册机吧!重新载入CM007.exeF9运行,因为注册和再次按钮都调用了同一个关键call,所以先禁用其他断点,激活关键call的段首处断点,输入用户名和注册码,点注册按钮,程序中断到004429A8处。单步运行了好几次,一遍遍地分析代码,唯恐看错了哪里。但是不得不说,这段代码有点莫名其妙的! 00442A35地址以前的计算,看上去很热闹,循环处理用户名的每一个字符,又是乘法又是加法,结果是0!很怀疑是不是作者哪个地方弄错了。从00442A37地址开始才是有效的判断注册码正误的算法!只是利用了注册码然后就判断了吗?具体的算法是:先取假码的16进制值,除以0x59,商取整,再加上假码的16进制值除以0x50的余数,最后加上0x1,结果=0!!!!程序到00442A55处指令是“cmp ebx,[local.1]”,应该是ebx中的值与注册码算出的结果比较,问题是在004429E0“xor ebx,ebx”指令将ebx清零后下面的指令就没有给ebx赋值的语句了,所以ebx=0!我猜测可能是上面用户名算出的结果应该不为0,并存入ebx中,此时再与注册码计算出的结果比较才对呀。那么ebx清零之前又是多少?向上查看何处给ebx赋值:地址00442A35处是指令“mov ebx,edx”,再来找这个edx的值从何而来:在00442A29处和00442A2B处又有两条指令中有edx,但这不是赋值;
[Asm] 纯文本查看 复制代码
00442A29  |.  33C2          xor eax,edx
00442A2B  |.  2BC2          sub eax,edx
继续向上找,到00442A16处,这里是带符号数的乘法,“imul edx,edi”,在这一句的上一条指令中,edx的值是用户名第一个字符与最后一个字符的16进制ASCII值的积,已有了具体的值,但在这一句中因为edi=0所以edx结果始终为0
19.png
问题又转到了edi0从何而来了:继续向上查看:到地址004429B7处,“mov edi,eax”指令又将问题交给了eax!(反复查找了几次,此处注释为:“edi=ds:[0x445830]的值”!) 20.png
再向上看,就到了关键call的段首,还没有其他的给eax赋值语句,说明要回溯到关键call外面去找了!
21.png
在调用这个关键call的地方,请看后面的注释,eax=ds:[0x445830],再去找这个堆栈被赋值的地方!向上再向上,肯定在调用关键call前面有被赋值的地址,这次很快就找到了地方:00442F86处。但这是注册码输入错误格式后才能来到这里的啊!如果注册码格式正确,不可能来到这里。
22.png
不信邪地在程序中Ctrl+F查找“mov dword ptr ds:[0x445830],eax”这条指令,Ctrl+L下一个,每找到一处都进行注释:
23.png

24.png

25.png
总共找到了八处,前四处在RegisterzClick事件中,后四处在AgainClick事件中,而且代码位置十分相似,只分析RegisterzClick事件的代码就行了。看过来看过去,反复运行程序验证,终于得出了程序流程:程序共分三步,第一步先输入用户名和非标准格式(非纯数字形式)的注册码,点击注册按钮,程序弹出注册码错误提示信息后继续向下运行,此时经call CM007.00442A8C算出结果给ds:[0x445830]赋值,跳过隐藏注册按钮和显示再次按钮;第二步保持用户名不动,重新输入一个格式正确(纯数字形式的)的注册码,点击注册按钮,此时关键call中的eax-edi-edx-ebx-eax终于都不再为0了,可以计算出一个正确的结果使注册按钮隐藏,再次按钮出现;第三步,保持用户名不变,再输入第一步的非标准的注册码,点击再次按钮,程序又弹出错误信息,继续运行,再将第二步的注册码输入到注册码编辑框中,再点再次按钮,再次按钮消失!最后再看CannellaClick事件,关键call00442B30,里面的关键代码竟然是直接比较用户名和注册码,相等则弹出信息框,不等则清零!
27.png
但是不管CannellaClick事件也完全能够达到隐藏按钮的目的,不明白这个东东有什么用!
VB编出了一个注册机,取输入的用户名和第一次的注册码,通过穷举法得出第二个注册码来。由于初学,很多问题都是一知半解的,特别是关于数值溢出的问题,困住了将近一周的时间!即使最终生成了注册机,也还可能存在溢出或是数据类型不匹配的问题,希望得到大家的帮助,共同学习提高。
最后,强迫症发作,自认为完美的程序流程是:先输入用户名(只要不是纯数字的就行),再将这个用户名作为第一次的注册码输入到注册码编辑框中,点击“清零”按钮,出现两个弹出窗;点掉后,点击“注册按钮”,再点掉错误提示,输入注册机中算出的第二次的注册码,再点击“注册”按钮;然后将用户名重新输入到注册码编辑框中,点击“再次”按钮,再点掉错误提示,再次输入第二次的注册码,点击“再次”按钮,程序破解全部完成!
自己的007练习附件: 007-1.7z (587.62 KB, 下载次数: 69) 包括原程序、汉化后的程序及爆破后的程序、注册机及源码均在内。
百度链接是:http://pan.baidu.com/s/1skMkJY9 密码: 86pm160CM、个人学习过的前7crackme程序都在里面。

免费评分

参与人数 15威望 +2 吾爱币 +24 热心值 +14 收起 理由
小婊砸 + 1 + 1 我很赞同!
SomnusXZY + 1 + 1 谢谢@Thanks!
a5606495 + 1 + 1 谢谢@Thanks!
pk8900 + 1 + 1 我很赞同!
xiaozhou2017 + 1 + 1 热心回复!
thisis + 1 + 1 我很赞同!
Lbf + 1 + 1 谢谢@Thanks!
Sound + 2 + 9 + 1 已经处理,感谢您对吾爱破解论坛的支持!
lumou + 1 + 1 用心讨论,共获提升!
夏雨微凉 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zhenyan + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
灰太狼大王 + 1 + 1 先收藏了
pwp + 1 用心讨论,共获提升!
WYWZ + 1 用心讨论,共获提升!
KaQqi + 3 + 1 涛个贴留个名

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

肥牛 发表于 2017-6-5 07:00
其实楼主在分析DeDe的时候就能看出来,有一个叫Again的按钮是隐藏状态:
[Delphi] 纯文本查看 复制代码
    object Registerz: TButton
      Left = 24
      Top = 16
      Width = 113
      Height = 41
      Caption = 'Register...'
      TabOrder = 0
      OnClick = RegisterzClick
    end
    object Again: TButton
      Left = 160
      Top = 16
      Width = 113
      Height = 41
      Caption = '...again !!! :p'
      TabOrder = 1
      Visible = False
      OnClick = AgainClick
    end


再去分析Registerz中的代码,应该是先把隐藏按钮显示出来。再分析Registerz按钮和Again按钮,基本功能都是一样的。所以只需要分析一个按钮的功能就可以了。
[Asm] 纯文本查看 复制代码
* Reference to control Codice : TLabel
|
00443105   8B83DC020000           mov     eax, [ebx+$02DC]

* Reference to: controls.TControl.GetText(TControl):TCaption;
|
0044310B   E83001FEFF             call    00423240
00443110   8B45F4                 mov     eax, [ebp-$0C]

* Reference to : TPrincipale._PROC_00442A8C()				//这是第一个关键点
|
00443113   E874F9FFFF             call    00442A8C
00443118   A330584400             mov     dword ptr [$00445830], eax
0044311D   BA9C324400             mov     edx, $0044329C

* Reference to control Codice : TLabel
|
00443122   8B83DC020000           mov     eax, [ebx+$02DC]

* Reference to: controls.TControl.SetText(TControl;TCaption);
|
00443128   E84301FEFF             call    00423270
0044312D   E9DD000000             jmp     0044320F
00443132   85F6                   test    esi, esi
00443134   0F8EC4000000           jle     004431FE
0044313A   8D55F4                 lea     edx, [ebp-$0C]

* Reference to control Nome : TLabel
|
0044313D   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;
|
00443143   E8F800FEFF             call    00423240
00443148   8B4DF4                 mov     ecx, [ebp-$0C]
0044314B   8BD6                   mov     edx, esi
0044314D   A130584400             mov     eax, dword ptr [$00445830]

|
00443152   E851F8FFFF             call    004429A8			//这是第二个关键点
00443157   84C0                   test    al, al
00443159   7473                   jz      004431CE
0044315B   33D2                   xor     edx, edx

* Reference to control Again : TButton

很显然,第一个函数是判断有没有特殊字符的,也就是说要报错的。第二个函数是计算注册码的。
而且,从代码中可以看到,第一个函数与第二个函数是互斥的,执行第一个就不会执行第二个了,执行第二个就不会执行第一个。
但是,第一个函数的结果会影响到第二个函数的注册码的计算。
那么思路就是先输入一个带有特殊字符的注册码,让程序报错,然后再输入正确的注册码。
于是,按照这个思路写注册机就行了。
注意看,我输入的第一个注册码是带空格的,这个注册码不同,最终生成的真正的注册码也不同。
另外,再和楼主说一下,生成最终的注册码时,不需要用穷举法。
只需要把前面阶段生成的(EBX-1)*0x59,然后再去与0x50的余数找平就可以了。
[Delphi] 纯文本查看 复制代码
  EAX := (EBX-1) * $59;
  EDX := EAX mod $50;
  EAX := EAX - EDX +1;


1.png
2.png
3.png
llto521 发表于 2017-6-3 14:04
pwp 发表于 2017-6-3 15:17
 楼主| 海天一色001 发表于 2017-6-3 15:42

谢谢你的评分和回复!不过我还只是初学者,目标是专家,现在还远远达不到标准呢!希望能在论坛中共同学习提高!!
pwp 发表于 2017-6-3 15:44
海天一色001 发表于 2017-6-3 15:42
谢谢你的评分和回复!不过我还只是初学者,目标是专家,现在还远远达不到标准呢!希望能在论坛中共同学习 ...

你学过汇编的对吧?看着你分析的好透彻
夏雨微凉 发表于 2017-6-3 15:50
多谢楼主分享教程
我爱小豆丁3.29 发表于 2017-6-3 17:21
我也想学,楼主能否加个联系方式把用到的工具发下。也想有个老司机带这学下
byh3025 发表于 2017-6-3 20:27
能把CM分析地这么透彻,将来必定是大牛,先膜拜下
肥牛 发表于 2017-6-3 20:58
明天我也研究一下这个007
渴望自来 发表于 2017-6-3 21:04
看到论坛里一个个厉害的程序员,真的好羡慕啊……
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 18:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表