前言
今天刚写完一篇第一篇逆向工程的文章,但是那个只是通过逆向工程获得信息,于是思考了一下,肯定有办法通过逆向工程修改程序吧。
虽然已经在文章《[安全] 记一次简单的逆向工程》中,实现了,但是还是在这里正规的说一下是如何去做的吧!
正文
1. CrackMe介绍
这个CrackMe,假设我们已经知道其密码是1997,具体行为如下:
- 当未输入正确密码
1997
时,输出Invalid.
- 当输入正确密码
1997
时,输出Valid.
具体入下图所示:
我们需要做的就是,寻找是否能够直接跳过输入可以的方法,直接得到Valid.
。
2. 逆向工程
2.1 打开文件
2.2 初看文件
其实,我觉得看到汇编代码的一瞬间,其实就挺明显的了,这基本属于一个简单到不能再简单的CrackMe小程序,如下图:
主要可以关注一下scanf,这个函数下面的内容,scanf在C中是接受外部参数的函数,其下面的运算对于我们而言至关重要。
call ___isoc99_scanf
mov eax, [rbp+var_C]
cmp eax, 7CDh
jnz short loc_1229
其中在scanf函数之后,我们首先mov eax, [rbp+var_C]
,rbp是栈指针,var_C是一个12位大小的指针,这个地方应该是将输入的值放入eax中,然后下一步cmp eax, 7CDh
,将输入的值与7CDh进行比较,这个地方IDA并没有给我们显示出来7CDh是什么来的,其实我们可以搜一下这个十六进制数,7CDh后面的h表示hex。
我们其实可以知道,是eax在和1997这个数字在比较。然后接下来的jnz short loc_1229
,决定了,是会去往call valid
还是 call fail
。
那么这个时候我们的方法也很清晰了,我们至少有两种方法:
- 更改
cmp eax, 7CDh
- 更改
jnz short loc_1229
- 直接添加
call valid
- 将
call invalid
改为call valid
2.3 更改cmp eax, 7CDh
这个方法比较简单,我们这里直接对cmp进行更改,这里点击IDA中的Edit > Patch program > Assemble an instruction
。将cmp eax, 7CDh
直接改为 cmp eax, eax
即可。
改完之后,发现把后面的jnz结构都给改变了,思考了一下,这应该是由于7CDh已经提前分配了一个特定的地址大小了,如果这里随便改一下整个地址都会被改变,并且测试了一下,发现如果写cmp eax,1
仍然会改变结构,但是cmp eax,7CEh
则不会,猜想应该是预分配地址大小的问题。
这么造成的结果就是,莫名奇妙的BUG:
2.4 更改jnz short loc_1229
那么我们这个时候,尝试更改一下jnz short loc_1229
吧,其中jnz代表了jump no zero,就是说不为0的时候则跳转地址loc_1229,short则表示短转移,表示与loc_1229之间相距在0FFH以内。参考来自《这条汇编指令是什么意思?》
我们直接将jnz short loc_1229
更改为jz short loc_1229
就可以了,这样他们的条件就完全相反,那么结果就完全取反了,这就说明我们只要输入随机一个错误的密码,程序就会输出Valid.
,这可比我们直接猜测密码简单多了。
然后我们到处Patch
点击IDA中的Edit > Patch program > Apply patches to input file
,将Create backup勾上。
测试一下。
发现不知道什么原因失败了,而且其实IDA中的图中,红线和绿线也是和jnz short loc_1229
之前一样的。(这个只能说,要好好去学习一下汇编语言才能够知道为什么了。)
2.5 直接添加call valid
叹气,那么就试一下这个办法吧,我们直接暴力的在jnz short loc_1229
前面加一个call valid
,直接调用valid方法。
可以发现结构也改变了,但是不知道实际上的测试结果如何,去测试一下~。
成功~!
2.5 (Youtube版)直接添加call valid
学习了一下Youtube Up主的《How To Patch Binary With IDA PRO》,发现这个Up主直接是在影响最小的printf函数上面进行的更改,感觉很有道理的样子,于是试一下。
更改后的样子,发现结构也变了很多:
第一次apply的时候失败了,但是第二次把更改撤回以后又成功了,挺奇怪的。(发现问题了,之前我一直用的是.bak的文件,但是.bak就是一个backup文件,是之前文件的备份,用之前文件的备份,那当然不是现在修改的文件,那当然失败了...所以应该用源文件,而不是源文件.bak,我晕了,第一个Youtube是错误的,不应该用.bak文件,或者是我看错了,他并没有用.bak,他只是做一个备份)
2.6 将 call invalid
改为call valid
还有一种也很暴力的,也很棒的办法,就是直接将call invalid
,改为call valid
不就好了~。
测试一下~!
成功!
总结
用了Youtube Up主的《How To Patch Binary With IDA PRO》的一个简单的C程序,并且自己想了几种办法,由于还没有怎么接触过汇编语言,所以当前最适合自己的办法,还是直接更改call [function_name]
这样的语句,因为最不容易出错~!
下一步估计就是要好好学习一下计算机操作系统 和 汇编语言了~!
星星同学,fighting!
参考
[1] How To Patch Binary With IDA PRO
Q.E.D.