吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3416|回复: 12
收起左侧

[原创] KeyFile保护CrackMe

  [复制链接]
ERFZE 发表于 2020-2-15 09:41

0x01 监视文件相关操作

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

Process Monitor添加条件如下:

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

0x02 使用IDA Pro分析

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

0x02.1 三处ReadFile()

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


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


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

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


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

0x02.2 核心验证函数

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

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


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

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

int tmp1=0;    //[ebp-2]
int tmp2;    //[ebp-1]
int ecx=0;
char String_Char_Xor[18];
char aC_0_After_C[]="C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************";
int ret;

do 
{
    tmp2=8;
    do 
    {
        tmp2-=2;
        ecx=tmp1;
        ch=String_Char_Xor[ecx];
        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代码块:

粗略转成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代码块:

粗略转成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[ecx];
        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文件。

免费评分

参与人数 5威望 +1 吾爱币 +24 热心值 +4 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
镇北看雪 + 1 用心讨论,共获提升!
$hsy + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
无名氏wyw + 1 + 1 这是真的大佬

查看全部评分

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

 楼主| ERFZE 发表于 2020-2-15 09:43
附CrackMe文件

PacMe.rar

10.35 KB, 下载次数: 6, 下载积分: 吾爱币 -1 CB

老鼠小老鼠 发表于 2020-2-15 10:37
yameng91 发表于 2020-2-15 11:10
arialyy 发表于 2020-2-15 12:20
大佬相当牛逼
hhxxhg 发表于 2020-2-15 12:23
如果从一开始就往左走跑到迷宫外会不会崩
归去来兮G 发表于 2020-2-15 12:46
向大佬学习
Li1y 发表于 2020-2-15 16:12
支持一下,学习了
wss11 发表于 2020-2-15 17:13
厉害了,学习到了,感谢。
HOW2J 发表于 2020-2-15 17:26
谢谢贴主了,值得学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-16 11:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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