吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5974|回复: 32
收起左侧

[原创] 学破解第117天,《160个CrackerMe之001》学习

[复制链接]
小菜鸟一枚 发表于 2020-7-16 17:59

学破解第117天,《160个CrackerMe之001》学习

前言:
  从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。

  2017年12月16日,通过19元注册码注册论坛账号,开始做伸手党,潜水一年多,上来就是找软件。(拿论坛高大上的软件出去装X)

  2018年8月某一天,报名了华中科技大学网络教育本科(计算机科学与技术专业)2018级秋季。(开始提升学历)

  2019年6月17日,不愿再做小菜鸟一枚,开始零基础学习破解。(感谢小糊涂虫大哥在我刚开始学习脱壳时,录制视频解答我的问题)

  2020年7月7日,感谢H大对我的鼓励,拥有了第一篇获得优秀的文章。(接下来希望学习逆向,逆天改命)

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1208234-1-1.html
立帖为证!--------记录学习的点点滴滴

0x1分析题目

  1.打开软件出现弹窗,窗口标题,hello you have to kill me.(你好,你必须干掉我),就是说这个弹窗需要干掉。
1.png

  2.然后中间是退出按钮,右边有一个serial按钮,点击后提示:Enter the serial here !!!!!(在这输入序列号),那这个一会也要弄掉。
2.png

  3.再看看左边,是一个name+serial验证,那么这也是一个验证点,也需要干掉。
3.png

  4.这软件分析完毕,需要干掉以上三个点,接下来就开始一个个尝试了。

0x2去弹窗

  1.看到弹窗,我的第一反应就是MessageBOX,虽然有时候它断不下来,既然如此,Ctrl+G输入MessageBOX,回车过去,F2下断点,shift+F9跑起来,成功的断了下来,看堆栈窗口

0012FE08   0042A1AE  /CALL 到 MessageBoxA 来自 Acid_bur.0042A1A9
0012FE0C   00080774  |hOwner = 00080774 ('Acid burn',class='TApplication')
0012FE10   0042F7BC  |Text = "Welcome to this Newbies Crackme made by ACiD BuRN [CracKerWoRlD]"
0012FE14   0042F7A0  |Title = "hello you have to kill me!"
0012FE18   00000000  \Style = MB_OK|MB_APPLMODAL

  2.那就直接点call那一行回溯过去,来到了

0042A1A2  |.  50            push eax                                 ; /Style = MB_YESNO|70|300|MB_APPLMODAL|80400
0042A1A3  |.  57            push edi                                 ; |Title = "hello you have to kill me!"
0042A1A4  |.  56            push esi                                 ; |Text = "Welcome to this Newbies Crackme made by ACiD BuRN [CracKerWoRlD]"
0042A1A5  |.  8B43 24       mov eax,dword ptr ds:[ebx+0x24]          ; |
0042A1A8  |.  50            push eax                                 ; |hOwner = 00080774 ('Acid burn',class='TApplication')
0042A1A9  |.  E8 FAB5FDFF   call <jmp.&user32.MessageBoxA>           ; \MessageBoxA

  3.接下来不用我说也知道吧,直接把上面那一段,参数和call一起nop掉就可以了,成功去掉弹窗。

0x3验证serial

  1.然后开始尝试第二步,看看serial的验证算法,等等,怎么点击后没有弹窗了???
1)我去掉了messageBOX,全部弹窗都去掉了?
2)如果是这样那么就是我上当了,并不能这样去弹窗,这样程序里面所有的弹窗都没有了。

  2.回到第一步,有那么好的字符串搜索大法,老老实实用吧,通过搜索弹窗的字符串,定位到

0042F784      6A 00          push 0x0
0042F786   .  B9 A0F74200   mov ecx,Acid_bur.0042F7A0                ;  hello you have to kill me!
0042F78B   .  BA BCF74200   mov edx,Acid_bur.0042F7BC                ;  Welcome to this Newbies Crackme made by ACiD BuRN [CracKerWoRlD]
0042F790   .  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042F795   .  8B00          mov eax,dword ptr ds:[eax]               ;  Acid_bur.00424090
0042F797   .  E8 D4A9FFFF   call Acid_bur.0042A170
0042F79C   .  C3            retn

这次我不nop它了,太可怕,我直接0042F784这里retn掉吧,找不到从哪个角落里跳出来了,然后在测试一下,很好打开时不弹窗,验证时可以弹窗,终于搞定了一个弹窗。

  3.赶紧进入正题了,开始serial验证了,首先还是随便输入假码52pojie,然后我不用messageBOX了,这个函数有毒,试试GetDlgItemTextA,没断下来?那我再试试GetWindowTextA,还是没断下来,玩我呢?讲道理,你能不通过windows API直接获取到文本框的值,这时候只怪自己学不好窗口编程了,都不知道下什么断点。想到春节吾爱的那道题,我没断下来是因为通过文本框内容的改变调用验证函数,这程序我猜测也有这可能,最后我只能求助于消息断点了,同样是202,鼠标左键按下松开后事件,邪门了,这个按钮事件是假的?这次消息断点我选择全部消息,然而还是没有断下来,这个按钮是个摆设?我晕,这个delphi程序怎么回事,消息断点下上去都不起作用?邪门了,看样子我这只小菜鸟也只能去搜索一下字符串了,然后下上断点,输入52pojie,来到了

0042F4D5  |. /75 1A         jnz short 1.0042F4F1
0042F4D7  |. |6A 00         push 0x0
0042F4D9  |. |B9 64F54200   mov ecx,1.0042F564                       ;  Congratz!
0042F4DE  |. |BA 70F54200   mov edx,1.0042F570                       ;  God Job dude !! =)
0042F4E3  |. |A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042F4E8  |. |8B00          mov eax,dword ptr ds:[eax]
0042F4EA  |. |E8 81ACFFFF   call 1.0042A170
0042F4EF  |. |EB 18         jmp short 1.0042F509
0042F4F1  |> \6A 00         push 0x0
0042F4F3  |.  B9 84F54200   mov ecx,1.0042F584                       ;  Failed!
0042F4F8  |.  BA 8CF54200   mov edx,1.0042F58C                       ;  Try Again!!

  4.去段首下断点吧,运行过来,然后开始分析,显然就是判断输入的字符串是否为Hello Dude!

0042F48D  |.  BA 40F54200   mov edx,1.0042F540                       ;  Hello
0042F492  |.  E8 7142FDFF   call 1.00403708
0042F497  |.  8D45 F8       lea eax,[local.2]
0042F49A  |.  BA 50F54200   mov edx,1.0042F550                       ;  Dude!
0042F49F  |.  E8 6442FDFF   call 1.00403708
0042F4A4  |.  FF75 FC       push [local.1]                           ;  local.1是字符串Hello
0042F4A7  |.  68 60F54200   push 1.0042F560
0042F4AC  |.  FF75 F8       push [local.2]                           ;  local.2是字符串Dude!
0042F4AF  |.  8D45 F4       lea eax,[local.3]
0042F4B2  |.  BA 03000000   mov edx,0x3
0042F4B7  |.  E8 F044FDFF   call 1.004039AC                          ;  把两个字符串拼接起来Hello Dude!
0042F4BC  |.  8D55 F0       lea edx,[local.4]
0042F4BF  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042F4C5  |.  E8 8EB5FEFF   call 1.0041AA58
0042F4CA  |.  8B45 F0       mov eax,[local.4]                        ;  52pojie
0042F4CD  |.  8B55 F4       mov edx,[local.3]                        ;  Hello Dude!
0042F4D0  |.  E8 2745FDFF   call 1.004039FC
0042F4D5  |.  75 1A         jnz short 1.0042F4F1                     ;  比较我输入的52pojie是否等于Hello Dude!

  5.那就输入Hello Dude!(注意感叹号是英文的)验证一下,提示God Job dude(干得好,伙计),说明验证通过了。

0x4验证serial/name

  1.接下来再试试最后这一个验证,不玩花里胡哨的,老老实实搜字符串,然后去段首下断,跑起来,输入52pojie和123456,断在这里

0042F998  /.  55            push ebp
0042F999  |.  8BEC          mov ebp,esp
0042F99B  |.  33C9          xor ecx,ecx                              ;  1.0042C7C4
0042F99D  |.  51            push ecx                                 ;  1.0042C7C4
0042F99E  |.  51            push ecx                                 ;  1.0042C7C4
0042F99F  |.  51            push ecx                                 ;  1.0042C7C4
0042F9A0  |.  51            push ecx                                 ;  1.0042C7C4
0042F9A1  |.  51            push ecx                                 ;  1.0042C7C4
0042F9A2  |.  51            push ecx                                 ;  1.0042C7C4

天啊,我被惊呆了,这么多push ecx在干嘛???

  2.开始单步走起,发现第一个错误被跳过去了,而eax就是name的长度,如果小于4就会提示序列号是错误的。

0042F9CD  |.  8B45 F0       mov eax,[local.4]                        ;  取出我输入的52pojie
0042F9D0  |.  E8 DB40FDFF   call 1.00403AB0                          ;  

0042F9E3  |.  E8 70B0FEFF   call 1.0041AA58

0042F9FE  |.  E8 55B0FEFF   call 1.0041AA58

0042FA1E  |.  E8 35B0FEFF   call 1.0041AA58

0042FA36  |.  E8 1DB0FEFF   call 1.0041AA58

0042FA52  |.  E8 D96EFDFF   call 1.00406930
0042FA57  |.  83F8 04       cmp eax,0x4
0042FA5A  |.  7D 1D         jge short 1.0042FA79
0042FA5C  |.  6A 00         push 0x0
0042FA5E  |.  B9 74FB4200   mov ecx,1.0042FB74                       ;  Try Again!
0042FA63  |.  BA 80FB4200   mov edx,1.0042FB80                       ;  Sorry , The serial is incorect !

call 1.0041AA58这个函数不知道是干什么用的,好像调用了多次

  3.上面一段分析完了,继续分析下面一段,最终密文的生成在0042FAE5这个call里面

0042FA79  |> \8D55 F0       lea edx,[local.4]
0042FA7C  |.  8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82  |.  E8 D1AFFEFF   call 1.0041AA58
0042FA87  |.  8B45 F0       mov eax,[local.4]                        ;  计算出name长度等于7
0042FA8A  |.  0FB600        movzx eax,byte ptr ds:[eax]              ;  取第一个字符5,也就是0x35
0042FA8D  |.  F72D 50174300 imul dword ptr ds:[0x431750]             ;  0x35*0x29=0x87D
0042FA93  |.  A3 50174300   mov dword ptr ds:[0x431750],eax          ;  再将eax给0x431750
0042FA98  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]          ;  ???
0042FA9D  |.  0105 50174300 add dword ptr ds:[0x431750],eax          ;  自己加自己,得到0x10FA,给0x431750
0042FAA3  |.  8D45 FC       lea eax,[local.1]                        ;  12FF9A4
0042FAA6  |.  BA ACFB4200   mov edx,1.0042FBAC                       ;  CW
0042FAAB  |.  E8 583CFDFF   call 1.00403708
0042FAB0  |.  8D45 F8       lea eax,[local.2]
0042FAB3  |.  BA B8FB4200   mov edx,1.0042FBB8                       ;  CRACKED
0042FAB8  |.  E8 4B3CFDFF   call 1.00403708
0042FABD  |.  FF75 FC       push [local.1]                           ;  1.0042FBAC
0042FAC0  |.  68 C8FB4200   push 1.0042FBC8                          ;  -
0042FAC5  |.  8D55 E8       lea edx,[local.6]
0042FAC8  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]          ;  0012F990
0042FACD  |.  E8 466CFDFF   call 1.00406718
0042FAD2  |.  FF75 E8       push [local.6]
0042FAD5  |.  68 C8FB4200   push 1.0042FBC8                          ;  -
0042FADA  |.  FF75 F8       push [local.2]                           ;  1.0042FBB8
0042FADD  |.  8D45 F4       lea eax,[local.3]
0042FAE0  |.  BA 05000000   mov edx,0x5
0042FAE5  |.  E8 C23EFDFF   call 1.004039AC                          ;  经过这个call里出现可疑字符串CW-4346-CRACKED
0042FAEA  |.  8D55 F0       lea edx,[local.4]
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3  |.  E8 60AFFEFF   call 1.0041AA58
0042FAF8  |.  8B55 F0       mov edx,[local.4]                        ;  123456
0042FAFB  |.  8B45 F4       mov eax,[local.3]                        ;  CW-4346-CRACKED
0042FAFE  |.  E8 F93EFDFF   call 1.004039FC                          ;  比较两个字符串是否相等
0042FB03  |.  75 1A         jnz short 1.0042FB1F
0042FB05  |.  6A 00         push 0x0
0042FB07  |.  B9 CCFB4200   mov ecx,1.0042FBCC                       ;  Congratz !!
0042FB0C  |.  BA D8FB4200   mov edx,1.0042FBD8                       ;  Good job dude =)
0042FB11  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042FB16  |.  8B00          mov eax,dword ptr ds:[eax]
0042FB18  |.  E8 53A6FFFF   call 1.0042A170
0042FB1D  |.  EB 18         jmp short 1.0042FB37
0042FB1F  |>  6A 00         push 0x0
0042FB21  |.  B9 74FB4200   mov ecx,1.0042FB74                       ;  Try Again!
0042FB26  |.  BA 80FB4200   mov edx,1.0042FB80                       ;  Sorry , The serial is incorect !

  4.接下来那就没什么好说的,重新再跑一遍程序,进去0042FAE5这个call看看,然而在这个call里,好像字符串已经生成了,既然如此,说明我找错了call,退出去,反复调试,定位到了

0042FABD  |.  FF75 FC       push [local.1]                           ;  1.0042FBAC
0042FAC0  |.  68 C8FB4200   push 1.0042FBC8                          ;  -
0042FAC5  |.  8D55 E8       lea edx,[local.6]
0042FAC8  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]          ;  10FA
0042FACD  |.  E8 466CFDFF   call 1.00406718                          ;  经过这个call,出现4346
0042FAD2  |.  FF75 E8       push [local.6]

  5.那么就进0042FACD这个call里面去跟吧,发现还没看到关键字符串的计算

00406718  /$  83C4 F8       add esp,-0x8                             ;  分配局部变量空间
0040671B  |.  6A 00         push 0x0
0040671D  |.  894424 04     mov dword ptr ss:[esp+0x4],eax           ;  将eax的值给变量1,0x10FA
00406721  |.  C64424 08 00  mov byte ptr ss:[esp+0x8],0x0            ;  将0赋值给变量2
00406726  |.  8D4C24 04     lea ecx,dword ptr ss:[esp+0x4]           ;  将变量1的地址传递给eax
0040672A  |.  8BC2          mov eax,edx                              ;  将0012F990赋值给eax
0040672C  |.  BA 44674000   mov edx,1.00406744                       ;  %d
00406731  |.  E8 8A080000   call 1.00406FC0
00406736  |.  59            pop ecx
00406737  |.  5A            pop edx                                  ;  1.00406744
00406738  \.  C3            retn

  6.那么就进00406731这个call继续往里面跟,看看有没有线索,越跟越深,陷进去了,有什么好办法呢,注意堆栈(0012F990),看看经过哪个call弹出4346这个字符串

0040375F  |.  E8 CCFFFFFF   call 1.00403730                          ;  取前四个字母52po
00403764  |.  89F9          mov ecx,edi
00403766  |.  89C7          mov edi,eax
00403768  |.  85F6          test esi,esi
0040376A  |.  74 09         je short 1.00403775
0040376C  |.  89C2          mov edx,eax
0040376E  |.  89F0          mov eax,esi
00403770  |.  E8 CFEFFFFF   call 1.00402744                          ;  经过这里出现了4346
00403775  |>  89D8          mov eax,ebx
00403777  |.  E8 F4FEFFFF   call 1.00403670
0040377C  |.  893B          mov dword ptr ds:[ebx],edi               ;  把4346存到0012F990中
0040377E  |.  5F            pop edi                                  ;  0012F968

  7.然后越跟越深,已经不知道自己人在何处了,这个4346从哪冒出来的,进去后发现这里突然出现了4346

00402763  |> \8D740E FC     lea esi,dword ptr ds:[esi+ecx-0x4]       ;  4346
00402767  |.  8D7C0F FC     lea edi,dword ptr ds:[edi+ecx-0x4]       ;  52po
0040276B  |.  C1F9 02       sar ecx,0x2                              ;  4右移2位等于1

  8.经过阅读论坛大佬们的学习记录,发现自己其实很早就看到了算法,看第3小段,那其实就是4346的计算过程,是不是很懵,明明计算出来的是0x10FA啊,我默默的把它丢到了在线进制转换网站,转换后的结果就是4346,所以我这后面纯属瞎折腾两小时。

0x5注册机的编写

  1.CW-加上我输入的name第一个字符转换成数字,乘以0x29然后乘以0x2,得到的十进制数在转换成字符串,在拼接上-CRACKED即可得到正确的注册码。(name长度必须大于4)

  2.最终的注册机代码编写如下:

package cpyutil.xiao.cai.niao.com;

import java.util.Scanner;

public class Register {
    public static void main(String[] args) {

        String name;
        String str1 = "CW-";
        String str2 = null;
        String str3 = "-CRACKED";

        int code;
        String serial;

        System.out.println("请输入name(不小于4个字符):");
        Scanner sc = new Scanner(System.in);//初始化一个输入流

        name = sc.nextLine();//从控制台读取输入的字符串

        if(name == null || name.length() < 4)//如果输入的长度小于4退出程序
            System.exit(0);

        code = name.charAt(0);//获取字符串中的第一个字符

        sc.close();//关闭输入流

        //计算密文
        code *= 0x29;
        code *= 0x2;

        //将其转换成字符串
        str2 = String.valueOf(code);

        serial = str1+ str2 + str3;//拼接成真正的serial

        //输出正确的serial
        System.out.println("生成的serial:");
        System.out.println(serial);
    }
}

输出结果:
请输入name(不小于4个字符):
52pojie
生成的serial:
CW-4346-CRACKED

  3.丢到程序里面去,验证成功,至此这个crackMe算是破解完成。

0x6总结

  1.Delphi程序好像不怎么吃windows消息断点,而且API断点,GetDlgItemTextA和GetWindowTextA也都不能断下来。

  2.碰到处理我们输入的字符串的时候,一定要看仔细了,它是16进制表示,觉得可疑转换成10进制也许会有发现

  3.分析name/serial的时候,第三步算法就出来了,只看正确流程的话,可以直接跳到最后一步看,如果想看一看我爬的坑,可以照着我跌下去的地方继续看看。

  4.这才第一个CM就把我绕晕了,基础不扎实,我还是小菜鸟一枚,加油,继续努力。

  PS:善于总结,善于发现,找到分析问题的思路和解决问题的办法。虽然我现在还是零基础的小菜鸟一枚,也许学习逆向逆天改命我会失败,但也有着成功的可能,只要还有希望,就决不放弃!

免费评分

参与人数 5吾爱币 +11 热心值 +5 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
夏碟语冰 + 1 + 1 我很赞同!
聚惠网络 + 1 + 1 我很赞同!
Da-ker + 1 + 1 我很赞同!
万里绿枫叶 + 1 + 1 用心讨论,共获提升!

查看全部评分

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

冥界3大法王 发表于 2020-7-17 08:24
小菜鸟一枚 发表于 2020-7-16 21:49
好难过,DEDE,IDR我都不会用,只能拿刚学一点的C++知识,在OD里面乱折腾。

Delphi程序它的调用是怎么 ...

@小菜鸟一枚
你说的最后一句话“学会总结” 我很赞成。
最好的办法,就是自己用Delphi编个程序,不同的程序里来查看对比
什么易语言,Delphi特征码,那些都是前人总结的老套子
新的定位方法和技巧,总结,我编了好多本平常的汇编笔记了。
最后把这些东西做成了软件,点击几下,半自动化完成。
破解就像是解读美女,从不同的方面看到的结果是不一样的。
所以得学会多角度思考与分析。 但凡软件被针对,就必然完蛋。
你得判断吧? 你得对比吧?这些汇编命令就都是可以参考的定位点。
不过茫茫代码之海中学会淘金才是王道。我有25种以上的方法来瞄点定位。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
小菜鸟一枚 + 1 + 1 用心讨论,共获提升!

查看全部评分

 楼主| 小菜鸟一枚 发表于 2020-7-16 21:49
冥界3大法王 发表于 2020-7-16 20:43
@小菜鸟一枚
其实Delphi程序除了使用DEDE,IDR之外,可以自己发现定位技巧
一般一个Form对应一个Unit

好难过,DEDE,IDR我都不会用,只能拿刚学一点的C++知识,在OD里面乱折腾。

Delphi程序它的调用是怎么回事的,是一个一个窗口调用吗,一个窗口末尾返回到另一个窗口,还是咋回事啊?

PS:谢谢大法王的指导!
额微粒波地 发表于 2020-7-16 18:06
一人之下123456 发表于 2020-7-16 18:27
感谢楼主分享学习经验,受教了
zl2437917 发表于 2020-7-16 18:34
看着很有难度
xyz1598753 发表于 2020-7-16 19:01
向楼主学习
dr-pan 发表于 2020-7-16 19:15
菜鸟来学习,可是您所访问的页面不存在或者已删除
dsfive 发表于 2020-7-16 19:21
努力学习中
cs8880 发表于 2020-7-16 19:50

学习学习
冷淘 发表于 2020-7-16 20:13
学习了, 楼主加油
mymppp 发表于 2020-7-16 20:19
活到老,学到老。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-16 11:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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