实验目的
- 读懂并能够独立编写密码验证的小程序。
- 运行
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
,随便输入一个用户名和密码点击注册,显示注册成功