实验目的
- 读懂并能够独立编写密码验证的小程序。
- 运行
Ollydbg,并学习用其调试密码验证小程序。 - 通过修改汇编语句来修改程序的判断条件,改变程序的运行路线。
理解程序
阅读并理解代码
1 |
|
- 在主函数内输入密码
password; - 跳转到子函数
verify_password()判断输入的密码是否正确即判断输入的密码password与正确的密码PASSWORD是否相等,如果相等则子函数返回0,否则返回非0; - 主函数在判断子函数
verify_password()返回值:如果是0,则输出Congratulation! You have passed the verification!,结束程序,否则输出incorrect password!,继续输入密码password重复上述过程。

调试程序
使用
Ollydbg打开程序
同时按下
Alt和F9执行到用户代码如下图:在地址为00401614处CALL test.00401014
找到地址
00401014处JMP test.main,即此处向下为用户代码
分析用户代码,发现
00401030至0040106F为子函数verify_password()反汇编代码,00401080至0040111C为main函数的反汇编代码

分析反汇编代码,发现在
004010E1处,出现指令CMP比较子函数的返回值与0,如果等于0,则执行接下来的004010E5处JE SHORT test.00401105处的指令,即打印Congratulation! You have passed the verification!;否则打印incorrect password!
程序运行的结构图如下

修改程序
已知:
| 编码 | 功能 |
|---|---|
JE |
等于则跳转 |
JNZ |
不等于则跳转 |
地址004010E5处指令JE SHORT test.00401105表示CMP指令比较的两个数相同则跳转到地址00401105处,即打印Congratulation! You have passed the verification!,否则按地址顺序执行,即打印incorrect password!
为此,我们将JE修改为JNZ并执行程序
右键点击
JE、找到二进制、点击编辑,或直接Ctrl+E,编辑代码,将74改成75,因为74代表JE,75代表JNZ,或直接双击JE更改该汇编语言由JE至JNZ

再次运行,当输入密码为
1234567时显示incorrect password!,输入其它内容时直接退出程序。
修改成功,即把结构中的选择语句中的N和Y调换位置

思考题
破解crackme.exe程序,要求通过修改程序代码的方式绕过crackme.exe的密码验证逻辑,至少采用2种破解方式方法。
用
Ollydbg打开crackme.exe文件
右键→查找→所有参考文本字串


双击
ASCII ‘crackmepassword’,跳转到文件汇编语言crackmepassword处找到四个条件选择语句利用
IDA打开crackme.exe文件,搜索字符串同样双击ASCII ‘crackmepassword’得到如下结果



分析汇编指令可知必须让程序执行
00401616处的指令而不能执行00401637处的指令。而在不知道密码的情况下会执行0040161E处的指令进行跳转,故要实现绕过密码登录就有需要不进行跳转,可以将0040161E处JNZ指令改为JE指令实现不跳转,该方法为方法一。通过分析四条选择语句,得到结论如下
地址 是否跳转 004015F1 JE不跳转 004015F5 JE不跳转 00401601 JNZ跳转 0040160B JNZ跳转 再次分析该部分程序只有程序在
004015F1处不跳转、在004015F5跳转时,根据寄存器的值才能判断出程序在0040161E处不跳转即不执行00401637处指令,故方法二是将004015F1处JNZ指令改为JE指令,将004015F5处JE指令改为JNZ指令。执行结果
方法一
将
JNZ指令改为JE指令
右键单击→复制到可执行文件→所有修改→全部复制→右键单击→保存文件→选择文件路径,将更改后的文件保存为crackme1.exe
打开
crackme1.exe,随便输入一个用户名和密码点击注册,显示注册成功

方法二
将
004015F1处JNZ指令改为JE指令,将004015F5处JE指令改为JNZ指令
与方法一相同,将更改后的文件保存为
crackme2.exe
打开
crackme1.exe,随便输入一个用户名和密码点击注册,显示注册成功
