小菜鸟一枚 发表于 2020-7-8 19:25

学破解第113天,《CM区mcyaas坛友的简单易语言程序》分析

本帖最后由 小菜鸟一枚 于 2020-7-11 13:00 编辑

# 学破解第113天,《CM区mcyaas坛友的简单易语言程序》分析
前言:
  从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。

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

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

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

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

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

**本文视频讲解地址:[https://www.52pojie.cn/thread-1215697-1-1.html](https://www.52pojie.cn/thread-1215697-1-1.html)**

立帖为证!--------记录学习的点点滴滴

## 0x1获取CM信息
  1.看标题,菜鸟第一个CM,嗯,和我一样的菜鸟,我想应该能对付,就拿它学习一番。
   
  2.观察界面,易语言程序,没学过易语言,心里有点慌,没学过易语言,只学了点C++,再看成功居然不弹窗口了,说明messageBOX断点不能用了,更慌了。

  3.但是我最近学了一天的windows程序设计,了解了窗口程序的运行机制,我觉得还是可以试试的。

  4.接下来就带和我一样的小菜鸟们试试几种常见的易语言破解方式。

## 0x2记事本破解
  1.为什么会想到用记事本破解呢?因为论坛好多新手发的CM,都能通过记事本搜索到“编辑框1”这个字符串。

  2.按照经验,把文件后缀名改为.txt,打开后搜索字符串,唯一比较像key的就是123456,为什么呢,因为字符串没加密,肯定会在ASCII码可表示范围内,也就是我们能从键盘上输入的字符,只有123456最可疑了。


  3.验证key:输入123456,果然进度条跑满了。

## 0x3搜索字符串破解
  1.易语言会生成大量的字符串,会给一些新手朋友们一种易语言搜索不到有用的字符串的错觉。

  2.以这个程序为例,可以直接拖到顶部看见字符串“123456”,那么就可以回车过去F2下断点,以它为突破口。

  3.跑一遍,整个流程都出来了
```
004010B8|.E8 09010000   call CM_by_AA.004011C6                   ;获取输入的字符串
004010BD|.83C4 10       add esp,0x10
004010C0|.8945 FC       mov ,eax                        ;取出eax,也就是我输入的111111
004010C3|.68 701C4800   push CM_by_AA.00481C70                   ;123456
004010C8|.FF75 FC       push                            ;入栈
004010CB|.E8 34FFFFFF   call CM_by_AA.00401004                   ;比较字符串是否相等
004010D0|.83C4 08       add esp,0x8                              ;销毁局部变量
004010D3|.83F8 00       cmp eax,0x0                              ;相等返回0,小于,这里所以返回-1
004010D6|.B8 00000000   mov eax,0x0                              ;将eax置0
004010DB|.0f94c0      sete al                                  ;ZF为0,这里设置false
004010DE|.8945 F8       mov ,eax
004010E1|.8B5D FC       mov ebx,                        ;将字符串的值还给ebx
004010E4|.85DB          test ebx,ebx
004010E6|.74 09         je short CM_by_AA.004010F1               ;这里不为0,不跳转
004010E8|.53            push ebx
004010E9|.E8 D2000000   call CM_by_AA.004011C0                   ;这里可能是个释放堆上内存的函数
004010EE|.83C4 04       add esp,0x4
004010F1|>837D F8 00    cmp ,0x0
004010F5|.0F84 22000000 je CM_by_AA.0040111D                     ;这里不跳走,即可爆破
004010FB|.6A 00         push 0x0
004010FD|.68 64000000   push 0x64                              ;进度条跑满,默认为0
00401102|.6A FF         push -0x1
00401104|.6A 0D         push 0xD
00401106|.68 0A000116   push 0x1601000A
0040110B|.68 01000152   push 0x52010001
00401110|.E8 A5000000   call CM_by_AA.004011BA                   ;显示进度条
00401115|.83C4 18       add esp,0x18
00401118|.E9 1D000000   jmp CM_by_AA.0040113A
0040111D|>6A 00         push 0x0
0040111F|.68 00000000   push 0x0                                 ;这里为0,所以执行后,进度不变,还是0
00401124|.6A FF         push -0x1
00401126|.6A 0D         push 0xD
00401128|.68 0A000116   push 0x1601000A
0040112D|.68 01000152   push 0x52010001
00401132|.E8 83000000   call CM_by_AA.004011BA                   ;显示进度条
```

## 0x4通过401000破解
  1.首先搜索401000处,找到00401004F2下断
```
00401000   .33C0          xor eax,eax
00401002   .C3            retn
00401003      90            nop
00401004/$8B5424 04   mov edx,dword ptr ss:
00401008|.8B4C24 08   mov ecx,dword ptr ss:
0040100C|.85D2          test edx,edx
0040100E|.75 0D         jnz short CM_by_AA.0040101D
00401010|.33C0          xor eax,eax
00401012|.85C9          test ecx,ecx                           ;CM_by_AA.00481C70
00401014|.74 06         je short CM_by_AA.0040101C
00401016|.8039 00       cmp byte ptr ds:,0x0
00401019|.74 01         je short CM_by_AA.0040101C
```

  2.然后随便输入111111,断在了这里,F8跟着走一遍,大概意思就懂了
```
00401004/$8B5424 04   mov edx,dword ptr ss:         ;111111
00401008|.8B4C24 08   mov ecx,dword ptr ss:         ;123456
0040100C|.85D2          test edx,edx                           ;111111
0040100E|.75 0D         jnz short CM_by_AA.0040101D            ;输入的字符串不为空就会跳

0040101D|> \85C9          test ecx,ecx                           ;123456
0040101F|.75 09         jnz short CM_by_AA.0040102A            ;密文123456不为空也跳

0040102A|> \F7C2 03000000 test edx,0x3                           ;数据对齐,我也不懂,反正32位系统肯定是4字节*8对齐的,所以这里运算结果肯定为0
00401030|.75 37         jnz short CM_by_AA.00401069            ;运算结果不为0才跳转
00401032|>8B02          /mov eax,dword ptr ds:            ;然后进行循环比较
00401034|.3A01          |cmp al,byte ptr ds:
00401036|.75 2B         |jnz short CM_by_AA.00401063
00401038|.0AC0          |or al,al
0040103A|.74 24         |je short CM_by_AA.00401060
0040103C|.3A61 01       |cmp ah,byte ptr ds:
0040103F|.75 22         |jnz short CM_by_AA.00401063
00401041|.0AE4          |or ah,ah
00401043|.74 1B         |je short CM_by_AA.00401060
00401045|.C1E8 10       |shr eax,0x10
00401048|.3A41 02       |cmp al,byte ptr ds:
0040104B|.75 16         |jnz short CM_by_AA.00401063
0040104D|.0AC0          |or al,al
0040104F|.74 0F         |je short CM_by_AA.00401060
00401051|.3A61 03       |cmp ah,byte ptr ds:
00401054|.75 0D         |jnz short CM_by_AA.00401063
00401056|.83C1 04       |add ecx,0x4
00401059|.83C2 04       |add edx,0x4
0040105C|.0AE4          |or ah,ah
0040105E|.^ 75 D2         \jnz short CM_by_AA.00401032
00401060|>33C0          xor eax,eax
00401062|.C3            retn
```

  3.所以爆破思路很简单,就是进这个函数后直接跳转到00401063这一行即可。
```
00401063|>1BC0          sbb eax,eax
00401065|. |D1E0          shl eax,1            
00401067|. |40            inc eax               ; eax从0到1
00401068|. |C3            retn
```

## 0x5通过消息断点破解
  1.首先我们要明白什么是消息,消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。

  2.例如这个程序鼠标左键单机事件就是一个事件,windows通过回调函数,调用WndProc,然后在这个函数里,我们就可以对我们需要的消息进行处理了。
```
//处理消息
      switch (uMsg)
      {
      case WM_LBUTTONDOWN://按下鼠标左键
                MessageBox(hwnd, TEXT("你好啊!"), TEXT("小菜鸟一枚"), MB_OK);
                return -1;//消息处理完后返回
      }
```
详细的windows程序代码见:(https://www.52pojie.cn/thread-1213978-1-1.html)

  3.所以我们可以通过消息断点找到处理输入字符串的地方,WM\_LBUTTONDOWN是一个宏定义,为16进制常量,这个程序我们需要找到比较字符串的函数,所以应捕获使用鼠标左键单击松开后的消息,也就是WM\_LBUTTONUP事件。

  4.有了思路,接下来就可以实战了,OD直接运行程序,点击w,显示当前窗口信息,选择“提交”按钮,右键设置消息断点,如图所示!


  5.然后消息类型选择202 WM\_LBUTTONUP事件,接下来还是输入111111,单击后,断在系统领空,F2在401000处下断点,运行过去,然后F8向下走,可以看到一系列相关的windows API函数。
```
00471DCF|.50            push eax                                 ; |Buffer = 00000006
00471DD0|.FF76 1C       push dword ptr ds:             ; |hWnd = 0012077E (class='Edit',parent=00160782)
00471DD3|.FF15 34054800 call dword ptr ds:[<&USER32.GetWindowTex>; \GetWindowTextA
00471DD9|.8B4C24 08   mov ecx,dword ptr ss:         ;111111
00471DDD|.6A FF         push -0x1
00471DDF|.E8 8A2B0000   call CM_by_AA.0047496E
00471DE4|.EB 0C         jmp short CM_by_AA.00471DF2
00471DE6|>8B01          mov eax,dword ptr ds:
00471DE8|.FF7424 08   push dword ptr ss:
00471DEC|.FF90 88000000 call dword ptr ds:
00471DF2|>5E            pop esi                                  ;00A25258
00471DF3\.C2 0400       retn 0x4
```
上面这段代码调用GetWindowTextA获取输入的字符串,00471DDF这个call里面是计算输入的字符串长度,也就是windows API对应的lstrlenA函数。。
```
004010BD|.83C4 10       add esp,0x10
004010C0|.8945 FC       mov ,eax                        ;取出eax,也就是我输入的111111
004010C3|.68 701C4800   push CM_by_AA.00481C70                   ;123456
004010C8|.FF75 FC       push                            ;入栈
004010CB|.E8 34FFFFFF   call CM_by_AA.00401004                   ;比较字符串是否相等
```
一路单步最后就来到了这里,FF75 FC也就是我们常说的易语言按钮事件,因为它有固定的偏移量push dword ptr ss:,所以这里就可以作为按钮事件的特征码,下一步就是比较了。

## 0x5总结
  1.通过0x3分析的时候,可能有些朋友们想到了通过直接复制那个push和call不就可以在启动的时候,就让进度条显示满(push窗口法),大家可以试试行不行。
  2.通过搜索相关资料,终于明白了test edx,3和test edx,1分别是判断地址是否为4的倍数,2的倍数,数据对齐用,32位系统必然是4字节对齐。
  3.上面我都只写了寻找爆破点,实际分析的过程中,密文123456其实都看得到,所以没提追码这回事,跑一遍就能看到密文。
  4.我个人理解是因为上面那个push是寄存器间接寻址,指令是固定的,所以可作为易语言按钮事件特征码。

参考资料:
(https://baike.baidu.com/item/windows%E6%B6%88%E6%81%AF%E5%A4%84%E7%90%86%E6%9C%BA%E5%88%B6/9420571?fr=aladdin)
(https://bbs.pediy.com/thread-190300.htm)
《加密解密第四版》P31-33-消息断点
windows程序设计(珍藏版)
CM程序地址:(https://www.52pojie.cn/thread-1213547-1-1.html)

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

绝无神 发表于 2020-7-10 15:15

橘子改改 发表于 2020-7-10 15:12
是打你要报考的学校是吧?我问了几天了机构了,都是上万的

机构当然要挣钱啊,直接搜学校名加继续教育学院,然后进去找招生办电话,打过去问,你到底有啥不放心的{:301_1008:},就是提升个学历,怕学校不好,那就选你们当地有名气的呗。

你要嫌麻烦,那就只能多出点钱,找机构代报,让他们包了也行。


注意:千万别选野鸡学校或者民办学校,具体什么学校好,可以问问这位大佬@alittlebear

小菜鸟一枚 发表于 2020-7-10 17:51

橘子改改 发表于 2020-7-10 14:16
老铁,你专升本花费多少钱啊?因为我也想升,咨询了很多感觉都不是肯靠谱,旁边的人也没有经验,所以找你问 ...

我找的机构呢,当时学校是学分制,好像要修满90学分,一学分80块吧,学费差不多7200,考试费另算,我自己嫌麻烦,找的机构,现场注册和考试报名让他们包了,机构收了我一万,有考试他们就通知我,学习和考试主要是靠自己,我快毕业了,就差统考计算机和英语,然后就是学位英语和论文了。

注意事项:线上考试有摄像头,实名制,别想着让人替考,线下考试是你本人去学校现场考试,这个就得好好复习了,像我最近就在拼命的补英语和计算机知识呢。

最好直接选学校,找继续教育学院招生办老师报名,如果要选机构,记得别信那些什么全程托管,包拿学位证,毕业证啥的。(反正我是老老实实学习,不知道什么非法渠道)

最好找你距离近的学校,方便考试,然后就是多打听,别的我也没什么经验了。

PS:我后面说的3门考试全都是线下,其他像期末考试啥的全是线上。

吾爱丶加油 发表于 2020-7-8 19:55

你早已不是吴下阿蒙

金戈铁马 发表于 2020-7-8 21:07

你早已不是吴下阿蒙

九星辰楪 发表于 2020-7-8 21:29

这就是学了一百多天的大佬们啊{:301_977:}

xuegaoxiansen 发表于 2020-7-8 21:33

大佬就是大佬,厉害

dedegoodboy 发表于 2020-7-8 22:39

你早已不是曾今的那个他了,而我还是我,学习破解脑瓜子太疼了。

957320193 发表于 2020-7-8 23:06

厉害厉害,顶一下。

xidasheng 发表于 2020-7-9 08:19

感谢楼主分享

刀大喵 发表于 2020-7-9 08:30

学习成果显著呀

终南明月 发表于 2020-7-9 08:38

学习精神值得鼓励。
页: [1] 2 3 4 5
查看完整版本: 学破解第113天,《CM区mcyaas坛友的简单易语言程序》分析