小明同学 发表于 2016-2-28 10:45

【C001】小白对一个cm的分析

本帖最后由 小明同学 于 2016-2-28 15:03 编辑

前言:
cm下载地址:https://www.52hb.com/thread-20778-1-1.html
1767036460大神的cm爆破追码教程:https://www.52hb.com/thread-20788-1-1.html

文章里的追码我将一笔过,不细说
谢谢**小老虎大神(原谅我用星号代替)的机器码提醒,要不我真不想去看机器码了

后话: 为啥有去反调试这一章,只因我的od渣....{:5_118:}

虚拟机下程序运行不了,提示如图:

**图1**

百度了下,原来是用普通编译,缺少支持库。按照提示框放入三个文件,可以正常运行

**图2**

-----------------------------------------------------------------------------------------------------------------------------------------------------
一. 反调试
这程序载入od后,各种关...无语, 开搞吧

1. 程序与dll分离
在窗口启动事件前就能各种崩,咋不上天呢
直接Ctrl+B,查找二进制FF 25,来到窗口启动前,如图:

**图3**

在0x4056A8处下断,进去看看
这里说明下,这里只贴重要的代码,以下文章都采用这种方式

**图4**

从图中可以看到,读取程序中dll文件,进行解码,然后再放到虚拟内存中

2. dll脱壳
我的思路就是把dll提取出来

**图5**


**图6**

从图中可以知道dll大小:0x7800
这时用LordPE提取出来,如图所示:

**图7**


**图8**

提取出来后,查壳工具提示upx壳、脱了它吧。注意下,修复dllIAT时要选取dll,如图

**图9**

3. 写代码加载独立的dll
用工具或手动添加新区段

**图10**

从图4中的0x4026DE处开始修改代码:
004026DE   > \E8 1DC90C00   call 1_CrackM.004CF000
004026E3   .EB 26         jmp X1_CrackM.0040270B   // 跳到图4中的0x40270B
004026E5   .C3            retn

**图11**

以下是新区段中手动添加的代码与数据

**图12**

大意就是加载dll文件,保存dll基址

4. 去除各种反调试
使用工具查看导出表

**图13**

第一次见到函数名是中文的...谢谢作者
大致八个检测
1001EE18: 反单步跟踪
1001EE22: 检测调试器.返回值:1.存在调试器;0.没有调试器
1001EE2C: 判断此运行是否存在被逆向可能性
1001EE36: 判断反和谐是否被逆向
1001EE5E: 是否在虚拟机
1001EE68: 系统崩溃
1001EE72: 易语言是否安装
1001EE40: 取程序内存特征.要返回相同的值
返回值都不用管,直接return,让函数返回函数地址。如个别有问题,再改正确的返回值

找个反单步跟踪函数演示下:

**图14**

可以看到很多jmp,这些都是函数的入口
1001EE18 > $B8 D4DA0000   mov eax,0xDAD4                           ;反单步跟踪
1001EE1D   .- E9 3622FEFF   jmp UnPack.10001058
跟到jmp里的代码:
10001058    833D 10300010 0>cmp dword ptr ds:,0x0
1000105F    75 07         jnz XUnPack.10001068
10001061    60            pushad
10001062    E8 09000000   call UnPack.10001070                     ; 计算10003010的值与HOOK
10001067    61            popad
10001068    0305 10300010   add eax,dword ptr ds:      ; 计算反单步跟踪真实地址
1000106E    FFE0            jmp eax                                  ; 中到反单步跟踪函数地址

大家注意下0x10001062这个call,它是计算的值与HOOK SendMessageA,这个等下再讲
只要知道的固定值是0x10006000就可以了
后话: 0x10006000是基址+6000,但基址并不是固定的0x10000000,是我太意了,忘写代码转换下
所以反单步跟踪函数真实地址: 0x10006000 + 0xDAD4= 0x10013AD4

**图15**

5. 修复HOOK SendMessageA
反调试ret后,在启动事件断下,再运行,又出错

**图16**

只好再次从窗口启动前跟踪,所以就有了前面说到的地方:(我代码再贴下,与上面一样)
10001058    833D 10300010 0>cmp dword ptr ds:,0x0
1000105F    75 07         jnz XUnPack.10001068
10001061    60            pushad
10001062    E8 09000000   call UnPack.10001070                     ; 解码,计算10003010的值与HOOK
10001067    61            popad
10001068    0305 10300010   add eax,dword ptr ds:      ; 计算反单步跟踪真实地址
1000106E    FFE0            jmp eax                                  ; 中到反单步跟踪函数地址

从0x10001062的call跟进后,发现是这个函数计算并修改了SendMessageA的地址,所以要把这个call删除然后修改代码使传入

正确的值

**图17**

6. 修改安全调用
再次运行下,无错误提示,但程序会自动关闭,跟了下是绑定安全call地址这个命令在搞鬼
绑定安全call地址与安全调用call这二个命令是相对应的,所以我们要修改这二个函数
(1).绑定安全call地址

**图18**

修改成:
10009449    55         push ebp
1000944A    8BEC       mov ebp,esp
1000944C    81EC 04000>sub esp,0x4
10009452    8B45 08    mov eax,dword ptr ss:
10009455    A3 30004D0>mov dword ptr ds:,eax                ; 保存到自已的数据段中
1000945A    90         nop                                    ; 方便调用call时读取
1000945B    90         nop
1000945C    90         nop
1000945D    90         nop
1000945E    90         nop
1000945F    8BE5       mov esp,ebp
10009461    5D         pop ebp
10009462    C2 0400    retn 0x4

(2).安全调用call

**图19**

修改成:
1000CDC6    FF15 30004>call dword ptr ds:                  ; 2_修改七.00402664
1000CDCC    C3         retn

反调试到此结束


-----------------------------------------------------------------------------------------------------------------------------------------------------
二. 算法
1. 机器码算法
其实在去掉反调试后比较兴奋,机器码以为就是固定的,经小老虎大神的贴子,我再次看了下机器码的算法:
机器码在界而出来就来了,说明在启动事件中(0x401519),我们进去看看,只有这二行代码:
0040156E|.68 64264000       push 2_修改七.00402664
00401573|.E8 54000000       call 2_修改七.004015CC
这二行是不是很眼熟,这个就是绑定安全call地址的命令..
这下我们就要到窗口启动前去看看了,前面有说过,窗口启动前查找的方法FF25:

**图20**


跟进后,看到:

**图21**


在窗口启动call的下一行下断
下来就是单步之旅了
幸运的是在断下后的第一行call就是算法了...
第一小段算法:

**图22**


第二小段算法:

**图23**


第三小段:

**图24**


第四小段:

**图25**


机器码算法小结: 取cpuid的eax,edx值,合并成文本并转大写md5


2. 注册码算法
其实注册码还不如机器码,一个比一个弱. 反调试->机器码->注册码....
注册码不多说,一大堆调用dll检测,函数套函数...
反调试去掉后,大家可以自己跟,不难的


注册码算法小结:
(1).取机器码的md5
(2). (常量文本(0x124位) + 机器码)转md5
(3). (常量文本(0x10位) + 机器码)转md5
(4).前面3个结果合并组成注册码

-----------------------------------------------------------------------------------------------------------------------------------------------------
附件:
1. 注册机源码
2. 去除反调试的纯净版cm

















三千亿少女的梦 发表于 2016-2-28 10:52

沙发我的吗~

1767036460 发表于 2016-2-28 11:26

{:6_213:}我是板凳

蓝色贝雷帽 发表于 2016-2-28 11:30

小白还要继续学习

Shark恒 发表于 2016-2-28 13:07

小明的教程真不错,讲的真挺好的,代表全体感谢小明!

zby03772015 发表于 2016-2-28 13:58

完了。。。我以为我是小白。。。现在才知道我不是。。

ExplorerWord 发表于 2016-2-28 14:29

楼主写的很是详细

superfeng 发表于 2016-2-28 14:54

看看是啥东西

superfeng 发表于 2016-2-28 14:56

这个什么玩意儿啊

mincelia 发表于 2016-7-16 14:37

看起来很详细 先支持下楼主 后来操作
页: [1]
查看完整版本: 【C001】小白对一个cm的分析