当前位置: 代码迷 >> 综合 >> Tuts4you lena‘s 40 crackme教程[1]
  详细解决方案

Tuts4you lena‘s 40 crackme教程[1]

热度:15   发布时间:2024-02-23 06:32:00.0

资源百度云盘链接:https://pan.baidu.com/s/1Pey2Yz2-1c2C_BW2vfy3pg
提取码:c7gm

这是一个名为Lena的破解者写的40个crackme, 我准备把这40个crackme的破解教程以博客形式发出,今天是第一个。首先看一下第一个crackme里面包含的所有文件:

把这个红框所示引用程序拖入Ollydbg后显示下图:

接下去我们运行一遍,看一下效果:

这里显示出了要我们购买证书的字样,题目这里是要求我们突破这个对话框而直接转成已经购买好了证书的对话框

鉴于这个程序不大并且已经有了失败对话框的字符串提示,我们来找一下对应的字符串:

果然找到了对应的字符串,以及提示成功的字符串,接下去我们进入You really did it!.... 的字符串看一下。

这里是一个MessageBox显示成功,而上面的内容全是0,所以必定是通过跳转到达这里的,顺着红线找到跳转的地方。

成功找到那个跳转,是一个jmp,我用correct jmp注释标注了,再往上面看一看就看到了CreateFile, 提示失败的Msgbox以及ReadFile。

这个CreateFile的模式是OPEN_EXISTING的,说明是打开已存在文件,这个名为Keyfile.dat。这里面必定是存着密匙的地方,下面有ReadFile, 必定是把Keyfile.dat文件里内容读到内存的某个地方,然后进行比较。

我们在目录下创建Keyfile.dat并且随意写入一部分数据:

再把程序重新拖入Od并且观察刚刚的位置:

由于CreateFile打开文件成功所以规避了失败对话框而是跳转到了ReadFile处,继续F8运行到ReadFile执行结束,然后到对应的缓冲区查看读取的内容:

读取的对应地址是: 0x40211A, 一看果然我输入的乱码被读取到内存中,往下看0x4010B0和0x4010B2两处分别是两个跳转

其中jnz,即我框出来的那句跳转是为了避免调到jmp处的, jmp会跳转到一个失败对话框,提示无效的密匙。

实际上之前ReadFile会有一个返回值,该值会返回到eax中,如果ReadFile返回0代表失败了,否则是成功,test eax, eax就是检验eax是否为0,如果读取成功了就不会为0。

在地址0x4010B8处会对0x402173地址处的内容与0x10做对比,如果比0x10小了,那就会跳转到失败对话框处,这里是检验密匙长度的,也就是说,Keyfile.dat中的内容长度必须大于16个字符。为何我这么讲,来看一下0x402173:

这是ReadFile读取字节数的位置,所以我们的Keyfile.dat里面的内容必须大于10字节。再看一下从0x4010C1处开始的这段。这一段就是检验密匙的阶段了

#include <windows.h>
#include <cstdio>
int main() {BYTE *pBuf = (BYTE *)"password";DWORD dwEBX, dwESI;BYTE bAL;dwEBX ^= dwEBX; // xor ebx, ebxdwEBX ^= dwESI; // xor esi, esiwhile (1) {bAL = *(pBuf + dwEBX); // mov al, byte ptr ds:[ebx + 0x40211A]if (0x0 == bAL) { // cmp al, 0x0; je 0x4010D3if (0x8 > dwESI) { // cmp al, 0x8; jl 0x4010F7MessageBox(NULL, "Invalid code", "caption", MB_OK | MB_ICONERROR);ExitProcess(0);}MessageBox(NULL, "Congratulations!!", "Caption", MB_OK);break;}if ('G' == bAL) // cmp al, 0x47;  jnz 0x4010D0dwESI += 1; // inc esidwEBX += 1;		// inc ebx} // jmp 0x004010C1system("pause");return(0);
}

我用C语言编写了高等语言的转换,相对清晰,对照查看。

最后可以得出结论,至少需要16个字符,并且其中不管在什么位置,至少需要连续的8个G字符位于Keyfile.dat中便可通过!

(完)