qinyuanchi 发表于 2020-3-31 21:28

一个简单的CM详细分析过程

本帖最后由 qinyuanchi 于 2020-3-31 22:50 编辑

# 0x00 前言
---
这个CM是《加密与解密》里的例题 书上也有讲解 我也是刚开始学逆向 第一次分析没看讲解想尝试自己把它分析出来 分析过程有什么不对也请大牛指正。

# 0x01 分析过程

---



先用od载入运行程序,点击Check发现没有任何提示。这里我对check下消息断点然后点击Check断到系统领空,然后对模块.text(00401000)处下访问断点并运行,来到程序领空后继续单步又会进入系统领空 ,接着再对.text下内存访问断点再按f9继续单步来到下图的按钮事件代码。



看到这里有个CreateFile函数 打开程序文件名是KWAZYWEB.BIT 此时程序并没有创建这个文件 需要我们自己创建一个,这里我用winhex对KWAZYWEB.BIT进行编辑写了一串简单的数字



然后用OD重新载入运行来到我们刚刚分析的地方往下走发现有三个ReadFile函数


一个一个单步可以从堆栈窗口发现第一个ReadFile是读取文件的第一个字符的编码,
第二个ReadFile根据第一个ReadFile读取的编码数作为读取个数往下读取,它的下面又有一个call我们跟进看一下



这里它将后面的字符编码累加并取累加的低位字节,循环次数为第一个字符“1”的编码
也就是31次(但我这里并没有输入这么多的字符,也不要紧我们继续分析)


出来后来到第三个ReadFile函数call这里发现它要接着第二个ReadFile读取位置往后再读
取18个字符,到这里我想应该把KWAZYWEB.BIT的内容改一下



把第一个字符的编码改为01 从第二个编码开始增加18个字符。再重新载入OD。来到最后一个ReadFile后面的call处跟进看下。


这个call将之前累加的编码低位字节与第三个ReadFile读取的18个字符依次异或存在004034EA中。返回后继续往下看。


这里分析一下可以看出是两个循环,内部小循环循环4次,外部大循环循环18次(刚好对应第三次ReadFile读取的个数)。
而小循环是每次将送入的单个字节(8位)分成4份(al)依次送入中间的call里,接下来就是分析这个call了。



这里是个case语句,判断al的值,并将所指地址004031CC的值(也就是数据窗口C的位置)进行修改
al为00B(0)则地址减0x10、为01B(1)则地址加0x1、为10B(2)则地址加0x10、为11B(3)则地址减0x1
继续往下分析


下面有两个判断,到这里我们应该就能知道要跳到成功解密的地方需要要从地址004031CC位置(C的位置)
走到下面的X处期间不能碰到” * “也就是只能顺着” · “走。这里每走4步对应一个字节该字节为之前异或得到的。
一共要走4×18次(之前的大小循环)。这里根据走的方向和判断条件可以推算出异或得到的正确Key:

                                                                                                                                 0xA9,0xAB,0xA5,0x10,
                                                                                                                                 0x54,0x3F,0x30,0x55,
                                                                                                                                 0x65,0x16,0x56,0xBE,
                                                                                                                                 0xF3,0xEA,0xE9,0x50,
                                                                                                                                 0x55,0xAF



# 0x02 写逆算法

---

```c
#include<iostream>
#include<iomanip>

using namespace std;
int flag = { 0xA9,0xAB,0xA5,0x10,
                                  0x54,0x3F,0x30,0x55,
                                  0x65,0x16,0x56,0xBE,
                                  0xF3,0xEA,0xE9,0x50,
                                  0x55,0xAF };
int main() {
      int i, len, sum = 0;
      char name;
      cin.getline(name, 100);
      len = strlen(name);
      cout << setw(2)<<setfill('0')<<hex << len<<" ";
      for (i = 0; name != 0; i++) {
                cout << hex << int(name)<<" " ;
                sum += name;
      }
      sum = sum & 0xFF;//取sum第一字节;
      for (i = 0; flag != 0; i++) {
                flag = flag ^ sum;
                cout << hex << flag << " ";
      }
      system("pause");
}
```




# 0x03 附上文件

---

bdrdc 发表于 2020-3-31 21:39

这个不错,好好研究研究.......

skm415889471109 发表于 2020-3-31 21:44

这教程很入门,学习了

qinyuanchi 发表于 2020-3-31 21:47

这个导入md后字体大小怎么改变不了呀 改了好久。。。{:301_1008:}

fattyjin 发表于 2020-3-31 21:56

哇哦支持一下

OO2OO 发表于 2020-4-1 08:01

学习了,谢谢楼主分享

jjf7978 发表于 2020-4-1 20:19

感谢楼主分享,学习了

从农菜菜籽 发表于 2020-4-1 21:11

感谢楼主分享.下载来学习一下.
页: [1]
查看完整版本: 一个简单的CM详细分析过程