作为一个web狗,前段时间在研究0day安全这本书
本实验是0day安全这本书第一章的crack小实验,对逆向新手应该还是有一些参考意义的
实验中用到的工具都可以在某破解论坛下载到
<b>工具:</b>
Visual C++ 6.0
OllyDbg
IDA
LordPE
二进制编辑器
待破解程序源码:
```c #include<stdio.h> #define PASSWORD "1234567" int verify_password(char *password) { int authenticated; authenticated = strcmp(password,PASSWORD); return authenticated; } main() { int valid_flag=0; char password[1024]; while(1) { printf("please input password: "); scanf("%s", password); valid_flag = verify_password(password); if(valid_flag) { printf("incorrect password!\n\n"); } else { printf("Congratulation! You have pass the verification!\n"); break; } } } ```
这是一个很简单的c语言程序,我们可以先将源码通读一遍了解程序的功能
首先程序定义了一个函数 verify_password 从函数名我们都可以猜出来这个是一个验证密码是否正确的函数
其中 authenticated = strcmp(password, PASSWORD); 将函数传入的值和宏定义的PASSWORD进行比较
我们知道在c语言中用strcmp来比较两个值的时候,如果相等则返回0,如果第一个参数较大返回正数,如果第一个参数较小返回负数。
然后我们再看主函数,在下面这句调用了这个函数:
```c
valid_flag = verify_password(password);
```
其中的password的值是由我们输入的,然后紧接着就是一个if......else......语句了,如果我们输入的值等于PASSWORD,就会打印出Congratulation! You.......,否则提示密码错误
在这个实验中,我们的目的就是通过逆向的方法,使得我们输入错误的password仍然能够验证成功
### 0x03:程序破解
#### 第一步:编译源码为可执行程序
用VC将代码编译为可执行的exe文件
#### 第二步:用IDA静态调试
打开IDA,点击new,然后选择我们的exe文件
然后出来的选项就选第一个,然后点击ok就可以了
然后我们在左边的窗口functions window找到我们的主函数
然后双击_main_0跳转到我们的主函数
我们知道,在我们的源代码中是通过if语句来判断是否验证成功的
```c if(valid_flag) { printf("incorrect password!\n\n"); } else { printf("Congratulation! You have pass the verification!\n"); break; } ```
现在我们要做的就是找到if语句的位置
跳转到主函数后,我们点击一下右边的代码区域,然后按一下空格键,就会出现一个程序的流程图
我们重点要关注三个地方:
第一个
我们可以看到,这里主要是在输入数据
第二个
这是验证失败输出语句
第三个
验证成功输出语句
那么我们就可以找到if语句了
执行jz这句以后,出现两条分支,很明显jz就是if语句
而且jz在win32位汇编中也是表示 为0跳转的意思
然后再按一次空格返回代码,得到if语句的位置为
004010D5
#### 第三步:Ollydbg动态调试
打开Ollydby,将exe文件拖入
然后Ctrl+G直接搜索if语句所在的位置,框内的值就填刚才IDA得到的地址
然后就成功跳转到了if语句所在的位置了
在刚才我们的源程序中,if里面为真就验证失败,如果我们现在要验证成功,可以这样做,修改 je short 004010E6 为 jne short 004010E6
je指令的意思是等于则跳转,jne是不等于则跳转,因此修改后跳转的逻辑刚好和原来相反就可以输入错误的密码仍然验证成功了。
直接双击修改
然后我们可以按F9键来运行一下我们的程序:
可以发现输入错误的密码后认证成功
### 0x04:修改程序文件
在上面的实验中,我们在Ollydbg中已经绕过来验证,但是这只是在ollydbg中的调试,是在内存中修改,我们原本的exe文件并没有改变。
如果要我们运行exe后随便输入一个错误的密码能显示验证成功的话,我们需要修改文件中相应的字节。
在第一步用IDA反汇编的时候我们得到了一个地址 004010D5 这个地址被称为虚拟内存地址(VA),而文件中的地址称为文件偏移地址
文件偏移地址和虚拟内存地址有个换算公式:
文件偏移地址 = 虚拟内存地址(VA) - 装载基址(Image Base) - 节偏移
如果我们要直接算的话,还是比较麻烦,如果借助工具的话就轻松多了。
我们这里使用LordPE来找到文件偏移地址
用LordPE打开文件
然后点击位置计算器
在VA后面的框输入我们的虚拟内存地址,然后点击执行就可以计算出文件偏移地址了
得到偏移量为10D5
然后我们用二进制编辑器编辑exe文件
Ctrl+G 搜索10D5
定位到16进制的74,74对应的就是汇编指令je,我们将其修改为jne对应的十六进制75然后保存
然后我们再来运行这个可执行程序,但是发现输入错误的密码后没有出现Congratulations......,就关闭界面了
因为if处的逻辑改为相反了,因此如果输入正确密码则会提示密码错误
然后将其放入Od中F9执行
执行结果表明程序已经被破解了
本文作者:Drac0nids
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/71510.html
恕我直言,0day这书存着就行了
@gssa 冒昧问一句,为什么这样说?
@Drac0nids 书太老了
test
改汇编语句不用这么麻烦,od里面双击直接改汇编语,然后再保存到文件。
不知道书中改汇编的方法为啥这么不专业?
@pt007 刚才问了下学二进制的同学,od是可以直接将修改保存到文件的,,,估计当时写书的时候od还不能吧????
@pt007 又或者作者是想要读者通过这一步来区分虚拟内存和文件偏移地址吧。。。