Abex’crackme是一个简单的绝著名小程序,国内外都有许多网站都对它进行了详细的讲解与说明.将自己的破解方法与其他人作为比较,能够提供自己的计算水平.
1. abex’crackme #1
调试前先运行程序,显示”Make me think your HD is a CD-ROM”消息.
消息的最后部分出现了”CD-Rom”这个词,由于我们没有太多的选择,只能继续点击消息窗口的”确定”按钮.
程序弹出ERROR消息窗口后就结束了运行.
1.1 开始调试
首先运行OllyDbg软件载入小程序,代码窗口可以看到程序的汇编代码.
EP代码非常短,是因为采用了汇编语言写出来的可执行文件,如果是使用了VC++/VC/Delphi等开发工具编写程序时,除了自己编写的代码外,还有一部分启动函数是由编译器添加的,经过反编译后,代码看上去就变得非常复杂.但是如果直接使用了汇编语言编写程序,汇编代码会直接变为反汇编代码.main()
直接出现在EP中,简单直观.
1.2 分析代码
重点看部分关于 Win32 API 调用的内容.
在消息窗口按”确定”后,程序会调用GetDriveTyppe()
API,获取C驱动器的类型(大部分返回的是HDD类型),然后操作它,使之被识别为CD-ROM类型,再在消息窗口输出”OK,I really think that your HD is a CD-ROM !”.下面逐行分析crackme的代码.
若两值相等,则跳转到40103D
,否则从401028
继续执行!
提示
指令 | 说明 |
---|---|
PUSH | 入栈指令 |
CALL | 调用指定的函数 |
INC | 值加1 |
DEC | 值减1 |
JMP | 跳转到制定地址 |
CMP | 比较给定的两个操作数与SUB命令类似,但操作数的值不会改变,仅改变EFLAGS寄存器. (若2个操作数的值一致,SUB结果为0,ZF设置为1) |
JE | 条件跳转指令 (若ZF为1,则跳转) |
2. 破解
首先移动光标到401026地址处,按空格键,在打开的汇编窗口中将汇编指令JE SHORT 0040130D
更改为JMP 0040103D
,如图所示:
意思就是将条件分支语句(JE)替换为无条件跳转语句(JMP).
3. 将参数压入栈
首先,请看地址00401000~0040100E之间的命令,可以发现调用MessageBoxA()函数之前使用了4个PUSH命令,把函数需要的参数逆序压入栈.
将上述汇编代码转换为C语言函数调用代码,如下所示.
|
|
比较C语言代码与汇编代码可以看到,函数调用时的参数顺序(正序)与参数入栈时的顺序(逆序)相反.那么参数入栈时,为什么采用逆序的方式?我们可以从内存结构(FILO,Firts In Last Out)即可.
栈的结构是FILO (先进后出),所以把参数压入栈时,只有按照逆序的方式压入,MessageBoxA()函数才能以正确的顺序接收到该参数!
利用调试器执行到EIP=0040100E
地址处,观察右下角的栈窗口.
MessageBoxA()函数从栈中获取需要的参数时,存储在栈中的参数会按照先进后出的规则依次弹出.