吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4800|回复: 23
收起左侧

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

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

学破解第118天,《160个CrackerMe之002》分析

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

  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.打开软件,发现需要输入name和serial,然后进行验证
1.png

  2.单机OK按钮会有弹窗提示正确与否。

0x2寻找爆破点

  1.看到弹窗,我的第一反应就是MessageBOX,没断下来,不熟悉的VB程序真的是毫无办法啊。

  2.搜字符串吧,然后定位到

0040258B   . /74 58         je short Afkayas_.004025E5
0040258D   . |68 801B4000   push Afkayas_.00401B80                                    ;  UNICODE "You Get It"
00402592   . |68 9C1B4000   push Afkayas_.00401B9C                                    ;  ASCII "\r"
00402597   . |FFD7          call edi                                                  ;  msvbvm50.__vbaStrCat
00402599   . |8BD0          mov edx,eax
0040259B   . |8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
0040259E   . |FFD3          call ebx                                                  ;  msvbvm50.__vbaStrMove
004025A0   . |50            push eax
004025A1   . |68 A81B4000   push Afkayas_.00401BA8                                    ;  UNICODE "KeyGen It Now"
004025A6   . |FFD7          call edi                                                  ;  msvbvm50.__vbaStrCat
004025A8   . |8D4D 94       lea ecx,dword ptr ss:[ebp-0x6C]
004025AB   . |8945 CC       mov dword ptr ss:[ebp-0x34],eax
004025AE   . |8D55 A4       lea edx,dword ptr ss:[ebp-0x5C]
004025B1   . |51            push ecx
004025B2   . |8D45 B4       lea eax,dword ptr ss:[ebp-0x4C]
004025B5   . |52            push edx
004025B6   . |50            push eax
004025B7   . |8D4D C4       lea ecx,dword ptr ss:[ebp-0x3C]
004025BA   . |6A 00         push 0x0
004025BC   . |51            push ecx
004025BD   . |C745 C4 08000>mov dword ptr ss:[ebp-0x3C],0x8
004025C4   . |FF15 10414000 call dword ptr ds:[<&MSVBVM50.#rtcMsgBox_595>]            ;  msvbvm50.rtcMsgBox
004025CA   . |8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004025CD   . |FF15 80414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeStr>]              ;  msvbvm50.__vbaFreeStr
004025D3   . |8D55 94       lea edx,dword ptr ss:[ebp-0x6C]
004025D6   . |8D45 A4       lea eax,dword ptr ss:[ebp-0x5C]
004025D9   . |52            push edx
004025DA   . |8D4D B4       lea ecx,dword ptr ss:[ebp-0x4C]
004025DD   . |50            push eax
004025DE   . |8D55 C4       lea edx,dword ptr ss:[ebp-0x3C]
004025E1   . |51            push ecx
004025E2   . |52            push edx
004025E3   . |EB 56         jmp short Afkayas_.0040263B
004025E5   > \68 C81B4000   push Afkayas_.00401BC8                                    ;  UNICODE "You Get Wrong"

  3.接下来不用我说也知道吧,直接把0040258B这里的je nop掉即可爆破成功。

0x3分析算法

  1.messageBOX断不下你,那我就试试GetWindowTextA和GetDlgItemTextA,输入52pojie和123456,点击OK,然后定位到了

0012F14C   7404375D  /CALL 到 GetWindowTextA 来自 msvbvm50.74043757
0012F150   00010708  |hWnd = 00010708 (class='ThunderRT5TextBox',parent=00010706)
0012F154   0091BE40  |Buffer = 0091BE40
0012F158   00000007  \Count = 0x7

  2.此时还在系统领空,Alt+F9返回到用户代码,这应该是到了vb的用户代码处吧

00402458   .  FF93 A4000000 call dword ptr ds:[ebx+0xA4]                              ;  msvbvm50.74070D32
0040245E   .  85C0          test eax,eax
00402460   .  7D 12         jge short Afkayas_.00402474

  3.接下来开始单步跟,不懂的函数直接丢百度

0040246E   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultCheckObj>]      ;  msvbvm50.__vbaHresultCheckObj

00402482   .  FF15 5C414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeStrList>]          ;  msvbvm50.__vbaFreeStrList

00402499   .  FF15 F4404000 call dword ptr ds:[<&MSVBVM50.__vbaFreeObjList>]          ;  msvbvm50.__vbaFreeObjList

004024AB   .  8B1D 0C414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaObjSet>]            ;  msvbvm50.__vbaObjSet

......

vbaHresultCheckObj 检查结果对象?
vbaFreeStrList 释放一个字符串?
vbaFreeObjList 释放一个对象?
vbaObjSet 给对象赋值?
......

  4.不瞎浪费时间,一路F8看看在哪出现我们输入的字符串吧

00402510   > \8B45 E8       mov eax,dword ptr ss:[ebp-0x18]                           ;  输入的serial123456
00402513   .  8B4D E4       mov ecx,dword ptr ss:[ebp-0x1C]                           ;  682770
00402516   .  8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaStrCat>]            ;  msvbvm50.__vbaStrCat
0040251C   .  50            push eax                                                  ;  123456入栈
0040251D   .  68 701B4000   push Afkayas_.00401B70                                    ;  UNICODE "AKA-"
00402522   .  51            push ecx                                                  ; /String = "溆"
00402523   .  FFD7          call edi                                                  ; \__vbaStrCat
00402525   .  8B1D 70414000 mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrMove>]           ;  拼接字符串AKA-682770
0040252B   .  8BD0          mov edx,eax
0040252D   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]
00402530   .  FFD3          call ebx                                                  ;  msvbvm50.__vbaStrMove; <&MSVBVM50.__vbaStrMove>
00402532   .  50            push eax                                                  ;  比较两个字符串是否相等
00402533   .  FF15 28414000 call dword ptr ds:[<&MSVBVM50.__vbaStrCmp>]               ;  msvbvm50.__vbaStrCmp

  5.虽然找到了真码,可是算法在哪呢?根据一路走过来的流程,可以看到真码由AKA-拼接682770构成,那么682770从哪来的?为什么没有看到获取52pojie的地方呢?是不是还是不能用Windows API断点?算了,不要紧,反正已经定位到了关键比较函数了,在往上回溯就行了,去段首F2下断点,然后单步开始跟,看看有没有线索

00402403   .  FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultCheckObj>]      ;  msvbvm50.__vbaHresultCheckObj
00402409   >  8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0]
0040240F   .  8B45 E4       mov eax,dword ptr ss:[ebp-0x1C]                           ;  经过上面那个call,52pojie就出来了
00402412   .  50            push eax                                                  ; /String = "682770"
00402413   .  8B1A          mov ebx,dword ptr ds:[edx]                                ; |计算长度
00402415   .  FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>]              ; \__vbaLenBstr
0040241B   .  8BF8          mov edi,eax                                               ;  此时eax是7,赋值给edi
0040241D   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]                           ;  将52pojie赋值给ecx
00402420   .  69FF FB7C0100 imul edi,edi,0x17CFB                                      ;  name的长度7*0x17CFB=0xA6ADD
00402426   .  51            push ecx                                                  ; /String = 0000104A ???
00402427   .  0F80 91020000 jo Afkayas_.004026BE                                      ; |如果溢出就跳转
0040242D   .  FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBstr_516>]     ; \rtcAnsiValueBstr
00402433   .  0FBFD0        movsx edx,ax                                              ;  取第一个字符的值0x35给edx
00402436   .  03FA          add edi,edx                                               ;  0xA6ADD+0x35=0XA6B12
00402438   .  0F80 80020000 jo Afkayas_.004026BE                                      ;  如果溢出就跳转
0040243E   .  57            push edi                                                  ;  edi入栈
0040243F   .  FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>]                ;  msvbvm50.__vbaStrI4
00402445   .  8BD0          mov edx,eax                                               ;  出栈后eax=682770

不懂的地方百度一下:
imul三操作数格式
32 位模式下的三操作数格式将乘积保存在第一个操作数中。第二个操作数可以是 16 位寄存器或内存操作数,它与第三个操作数相乘,该操作数是一个8位或16 位立即数。
IMUL 执行时,若乘积有效位被丢弃,则溢出标志位和进位标志位置 1。因此,在执行了有三个操作数的 IMUL 操作后,必须检查这些标志位中的一个。

  6.0XA6B12经过0040243F这个call就变成了682770,经历过上一个CM的大坑,我这次0XA6B12直接丢电脑自带的计算器转换一下,果然就是682770,到了这里算法也就分析完毕了。

0x4注册机的编写

  1.算法部分:输入的字符串长度*0x17CFB+字符串的第一个字符,然后如果没有溢出,就将结果转换成10进制数对应的字符串。

  2.代码实现:

package cpyutil.xiao.cai.niao.com;

import java.util.Scanner;

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

        String name;
        String str1 = "AKA-";
        String str2 = null;
        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);

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

        //计算注册码后半部分
        code = name.length() * 0x17CFB;
        if(code < 0)//发生溢出
        {
            System.out.println("很抱歉,您输入的name没有对应的序列号");
        }

        code += name.charAt(0);
        if(code < 0)//发生溢出
        {
            System.out.println("很抱歉,您输入的name没有对应的序列号");
        }

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

        serial = str1 + str2;//拼接字符串

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

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

  3.当然了,这个程序其实并没有限制name不少于4个字符,别被误导了哦。

0x5总结

  1.只会一点C++的皮毛,做起论坛的CM果然是好大的压力啊。

  2.幸运的是VB程序可以使用GetWindowTextA,不至于又逼得我去搜索字符串了。

  3.上个程序弄懂了,这个CM其实并不难,都是一样的套路,取name,计算注册码,然后把数值转换十进制,然后再转换成字符串类型。

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

免费评分

参与人数 7吾爱币 +13 热心值 +6 收起 理由
wait_for_you + 1 我很赞同!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
万里绿枫叶 + 1 + 1 用心讨论,共获提升!
szjzxm4321 + 1 + 1 热心回复!
amovokiss + 1 + 1 我很赞同!
solly + 1 + 1 用心讨论,共获提升!
a1257206962 + 1 + 1 加油!

查看全部评分

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

acsecqb 发表于 2020-7-17 17:57
加油!楼主已经很棒了!
garen 发表于 2020-7-17 18:39
多余呀 发表于 2020-7-17 18:59
gms 发表于 2020-7-17 19:27
加油,绝不放弃!
sifan785622020 发表于 2020-7-17 21:09
虽然看不懂,加油
查无此凡 发表于 2020-7-17 21:51
太欣赏楼主了,继续加油啊
咕咚陛下 发表于 2020-7-18 08:39
只要还有希望,就决不放弃
pp125109139 发表于 2020-7-18 09:59
谢谢分享~~
tpeiewjkdw4 发表于 2020-7-18 13:45
看不太懂,不过加油。比我牛掰多了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-16 08:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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