今天是第一个crackme的教程,实验程序下载地址:链接: https://pan.baidu.com/s/183HghBtTQkAkkyLHS4KKqw 提取码: 9t92
一、我们先来看看这个程序到底是什么样子的。

弹出一个窗口,窗口名为Key File ReverseMe, 内容是Evaluation period out of date. Purchase new license。
看来程序的功能就是要验证license(许可证)。
二、用ollydbg打开程序

程序入口点在401000,没有加壳。我们右键单击反汇编窗口-搜索-所有引用的字符串,可以看到很多被引用的字符串,也能找到刚刚打开程序时 弹出的窗口的字符串"Evaluation period out of date. Purchase new license"。

Alt+C回到CPU窗口。按F8开始调试,走到不远处看到 KERNEL32.CreateFile 这个Win32API

我们去MSDN上看看这个函数的原型

可以看到程序试图创建一个名为Keyfile.dat的文件,打开方式是OPEN_EXISTING。但是我们并没有名为Keyfile.dat的文件在程序目录下。
在下一行,我们看到汇编代码是CMP EAX, -1,说明CreateFile函数对返回值(函数的返回值存放于EAX中)与-1(打开失败)进行了比较。然后便是JNE跳转。我们在跳转指令处按F2下一个断点。

我们先不管他,让他正常执行,此时跳转未实现。按F8继续执行,程序弹出消息框。

三、我们应该能猜测刚刚的跳转是因为CreateFile返回值的影响。
在刚刚的断点处按 ' ; ' 键写上备注。在程序目录新建一个Keyfile.dat文件然后Ctrl+F2重新执行程序,按F9执行到断点处,按F8继续执行,程序跳转了。
我们可以看到跳转后的地址是准备调用KERNEL32.ReadFile这个API,我们猜测应该就是对刚刚的的Keyfile.dat文件进行读操作。

往下一行可以看到TEST EAX, EAX(EAX存放返回值)这条汇编指令。我们可以在这里下断点。先正常执行可以得到以下结果,许可证错误。可以知道判断的算法就在这之后了。
四、对算法进行剖析
Ctrl+F2重新执行程序,到执行完ReadFile处停下。TEST EAX, EAX 执行完后,对后一条指令JNZ SHORT 004010B4有影响。我们先看看004010F7处的程序。是我们一开始运行时弹出的对话框,应该可以猜到是ReadFile读取文件出错时跳转。

那004010B4处开始的汇编代码就是验证Keyfile.dat的算法了。按F8单步调试。
在4010B8处有条指令是 CMP DWORD PTR DS:[402173],10。从之前调用ReadFile这个API的参数可以看出,402173的数据区是存放着读取的字符串长度。通过下一条指令( JL SHORT 004010F7 )也可以看出,Keyfile.dat文件里的字符串应该至少是16个字节的长度,在此处设断点并添加备注。先正常执行,发现弹出许可证出错的消息框。
重新执行,向Keyfile.dat写入20个 '1' 继续执行,按F9跳到断点处。此时一直按F8发现进入了一个循环。

分析循环的指令,从EBX+40211A处每次读取一个字节放入AL中。从Readfile这个API的参数可以看出读取的字符串是放在数据区40211A的地方,从右边的也可以看到我们写入Keyfile.dat的字符串(4010B4处XOR EBX, EBX 将EBX置零了)。
可以发现先是对AL与0进行了比较,相等时跳出循环。因为字符串以'\0'结尾,所以应该是读取到字符串末尾后跳出循环。往下若没有到末尾,则执行CMP AL, 47指令。47H对应的ASCII码为 'G',即与将AL的值与'G'比较。不相等时跳转到INC EBX,否则INC ESI。可以看出ESI是存放字符串中'G'的个数。

结束循环后,可以看到CMP ESI, 8 与 JL SHORT 004010F7 这两条指令。如果JL跳转实现,则跳转至004010F7处(许可证错误对话框),否则跳转至401205处。所以关键就是在这两条指令里了。可以看出,Keyfile.dat中的'G'的个数应该是要大于8,同时字符串长度要大于16字节。如此,在Keyfile.dat中写入20个'G'测试一下。结果成功。

五、暴力破解
如果不在程序目录生成一个Keyfile.dat文件并满足要求的话,也可以直接爆破。我们知道00401205处便是验证成功的代码,所以直接将CreateFile之后的JNE 改成 JMP 00401205。测试成功。选取刚刚修改的地方,右键-备份-可执行文件,再右键保存即可。
六、总结
这一个CrackMe还是十分简单的,主要就是仔细和耐心,很快就能CrackIt,是一个给新手练手的好程序。
网友评论