ERFZE 发表于 2020-2-15 09:41

KeyFile保护CrackMe

## 0x01 监视文件相关操作

运行程序,打开任务管理器,查看进程名称如下:

![](https://s2.ax1x.com/2020/02/10/1IeAXV.png)

Process Monitor添加条件如下:

![](https://s2.ax1x.com/2020/02/10/1Iek60.png)

只监视文件相关操作,可以看到程序要读取的文件名称如下:

![](https://s2.ax1x.com/2020/02/10/1IeFlq.png)

## 0x02 使用IDA Pro分析

程序先使用`CreateFile()`函数来打开KeyFile文件,故通过该函数定位:

![](https://s2.ax1x.com/2020/02/10/1Iee7F.png)

#### 0x02.1 三处`ReadFile()`

成功打开文件后下面有三处`ReadFile()`操作:

![](https://s2.ax1x.com/2020/02/10/1IeZ0U.png)

----

第一处`ReadFile()`操作读取1个字节到缓冲区中,笔者将其命名为`StringLength`。接下来判断该值是否为0,若为0,直接跳转到`CloseHandle()`函数处;不为0,继续下面的操作。

----

第二处`ReadFile()`操作读取`StringLength`个字节到缓冲区中,然后调用`sub_401000()`。跟进`sub_401000()`查看:

![](https://s2.ax1x.com/2020/02/10/1Ienk4.png)

`403288h`处存放的是刚刚`ReadFile()`读取内容,故该函数功能是将读取内容逐字节相加,取其低8位保存于`String_Char_Add`(由笔者命名)中。

----

第三处`ReadFile()`读取18个字节,然后调用`sub_4010C9`,跟进查看。

#### 0x02.2 核心验证函数

![](https://s2.ax1x.com/2020/02/10/1IeutJ.png)

先跟进`sub_40101D`函数查看其功能:

![](https://s2.ax1x.com/2020/02/10/1IeKh9.png)

该函数功能是将上述第三处`ReadFile()`读取出来的18字节(笔者名之为`String_Char_Xor`)逐个与`String_Char_Add`作异或运算。

----

将下面的指令粗略转成C语言形式(分析时随手写成,仅为表达程序逻辑,无法运行):

![](https://s2.ax1x.com/2020/02/10/1IeQpR.png)

注意上图红色方框中的两个向上箭头明显是`Do...While`的标志。

```
int tmp1=0;    //
int tmp2;    //
int ecx=0;
char String_Char_Xor;
char aC_0_After_C[]="C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************";
int ret;

do
{
    tmp2=8;
    do
    {
      tmp2-=2;
      ecx=tmp1;
      ch=String_Char_Xor;
      ch>>=ecx;
      ch&=3;
      sub_401033();

      if()

            ;

    }while(tmp2!=0)
    tmp1+=1;
}while(tmp1!=18)
```

由于函数`sub_401033()`功能暂不清楚,故只写下`if`框架,等待分析完函数`sub_401033()`功能后再补充。

> 注:笔者起初没有使用IDA Pro的F5,分析并写完后方才以F5验证是否正确,但发现其不靠谱...

----

跟进函数`sub_401033()`查看,首先是一处`if...else if...else`代码块:

![](https://s2.ax1x.com/2020/02/10/1Iel11.png)

粗略转成C语言形式:

```
char* loc;
    char tmp1;
    if(ch!=0)
    {
      if(ch==1)
            loc=aC_0_After_C+1;
      else if(ch==2)
            loc=aC_0_After_C+16;
      else
            loc=aC_0_After_C-1;
    }
    else
      loc=aC_0_After_C-16;
    tmp1=*loc;
```

下面是一处`if...else`代码块:

![](https://s2.ax1x.com/2020/02/10/1Ie16x.png)

粗略转成C语言形式:

```
if(tmp1!='*')
    {
      if(tmp1=='X')
            printf("Success");
      else
      {
            *loc='C';
            *aC_0_After_C=' ';
            return 1;
      }

    }
    else
      return 0;
```

----

将之前`Do...While`中的`if`补齐如下:

```
do
{
    tmp2=8;
    do
    {
      tmp2-=2;
      ecx=tmp1;
      ch=String_Char_Xor;
      ch>>=ecx;
      ch&=3;
      ret=sub_401033(ch);
      if(!ret)
            return ret;
    }while(tmp2!=0)
    tmp1+=1;
}while(tmp1!=18)
```

#### 0x02.3 验证思路

综合上述分析,可以总结出该程序的验证思路。

1. 读取KeyFile文件中第一个字节,该字节存储的是`Len(Name)`

2. 根据长度读取`Name`,将`Name`逐字节相加,取其低8位,存储于`L8`中

3. 于KeyFile文件中继续读取18个字节内容,逐个与`L8`作异或运算

关键在于第3步中读取的18个字节是何种意义。

----

将奇怪字符串以16(16是由`aC_0_After_C`起始位置得来)为单位分开,可以发现端倪:

```
****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************
```

`.`是路径,`*`是墙壁,`C`是起点,`X`是终点。由`C`沿`.`走到`X`,验证通过;其间若碰到`*`,验证失败。

那么,`sub_401033()`函数一开始的`if...else if...else`代码块的功能:

- 0:上

- 1:右

- 2:下

- 3:左

而下面的`if...else`代码块则是判断是否碰壁或者到达终点。

#### 0x02.4 路径计算

既然`sub_401033()`函数功能是移动一步并判断,那么第3步中读取的18个字节存储的应是与路径相关。那么就来走一下这个迷宫(只写出部分,后面请自行补充):

> 2 2 2 1 2 2 2 3 2 2 1 1...

外层的`Do...While`循环是18次,那么每次处理1字节。内层的`Do...While`循环是4次,1Byte=8bits,故`2 2 2 1`——>>`10 10 10 01`——>>`A9`。

`A9`是KeyFile文件于第3步中被读取出的字节与第2步`L8`异或所得,那么将路径按上述过程全部转换之后再与`L8`异或再加上`Len(Name)`及`Name`就能得到KeyFile文件。

ERFZE 发表于 2020-2-15 09:43

附CrackMe文件

老鼠小老鼠 发表于 2020-2-15 10:37

萌新冒下泡

yameng91 发表于 2020-2-15 11:10

向大佬学习经验

arialyy 发表于 2020-2-15 12:20

大佬相当牛逼

hhxxhg 发表于 2020-2-15 12:23

如果从一开始就往左走跑到迷宫外会不会崩;www

归去来兮G 发表于 2020-2-15 12:46

向大佬学习

Li1y 发表于 2020-2-15 16:12

支持一下,学习了

wss11 发表于 2020-2-15 17:13

厉害了,学习到了,感谢。

HOW2J 发表于 2020-2-15 17:26

谢谢贴主了,值得学习
页: [1] 2
查看完整版本: KeyFile保护CrackMe