前言

今天刚写完一篇第一篇逆向工程的文章,但是那个只是通过逆向工程获得信息,于是思考了一下,肯定有办法通过逆向工程修改程序吧。

虽然已经在文章《[安全] 记一次简单的逆向工程》中,实现了,但是还是在这里正规的说一下是如何去做的吧!

正文

1. CrackMe介绍

这个CrackMe,假设我们已经知道其密码是1997,具体行为如下:

  1. 当未输入正确密码1997时,输出Invalid.
  2. 当输入正确密码1997时,输出Valid.

具体入下图所示:

image.png

我们需要做的就是,寻找是否能够直接跳过输入可以的方法,直接得到Valid.

2. 逆向工程

2.1 打开文件

image.png

image.png

image.png

2.2 初看文件

其实,我觉得看到汇编代码的一瞬间,其实就挺明显的了,这基本属于一个简单到不能再简单的CrackMe小程序,如下图:

image.png

主要可以关注一下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。

image.png

我们其实可以知道,是eax在和1997这个数字在比较。然后接下来的jnz short loc_1229,决定了,是会去往call valid 还是 call fail

那么这个时候我们的方法也很清晰了,我们至少有两种方法:

  1. 更改cmp eax, 7CDh
  2. 更改jnz short loc_1229
  3. 直接添加call valid
  4. call invalid改为call valid

2.3 更改cmp eax, 7CDh

这个方法比较简单,我们这里直接对cmp进行更改,这里点击IDA中的Edit > Patch program > Assemble an instruction。将cmp eax, 7CDh 直接改为 cmp eax, eax即可。

image.png

image.png

改完之后,发现把后面的jnz结构都给改变了,思考了一下,这应该是由于7CDh已经提前分配了一个特定的地址大小了,如果这里随便改一下整个地址都会被改变,并且测试了一下,发现如果写cmp eax,1仍然会改变结构,但是cmp eax,7CEh则不会,猜想应该是预分配地址大小的问题。

image.png

image.png

这么造成的结果就是,莫名奇妙的BUG:

1690664527558.png

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.,这可比我们直接猜测密码简单多了。

image.png

然后我们到处Patch

点击IDA中的Edit > Patch program > Apply patches to input file,将Create backup勾上。

image.png

测试一下。

image.png

发现不知道什么原因失败了,而且其实IDA中的图中,红线和绿线也是和jnz short loc_1229之前一样的。(这个只能说,要好好去学习一下汇编语言才能够知道为什么了。)

2.5 直接添加call valid

叹气,那么就试一下这个办法吧,我们直接暴力的在jnz short loc_1229前面加一个call valid,直接调用valid方法。

image.png

可以发现结构也改变了,但是不知道实际上的测试结果如何,去测试一下~。

image.png

成功~!

2.5 (Youtube版)直接添加call valid

学习了一下Youtube Up主的《How To Patch Binary With IDA PRO》,发现这个Up主直接是在影响最小的printf函数上面进行的更改,感觉很有道理的样子,于是试一下。

image.png

更改后的样子,发现结构也变了很多:

image.png

第一次apply的时候失败了,但是第二次把更改撤回以后又成功了,挺奇怪的。(发现问题了,之前我一直用的是.bak的文件,但是.bak就是一个backup文件,是之前文件的备份,用之前文件的备份,那当然不是现在修改的文件,那当然失败了...所以应该用源文件,而不是源文件.bak,我晕了,第一个Youtube是错误的,不应该用.bak文件,或者是我看错了,他并没有用.bak,他只是做一个备份)

1690662737994.png

2.6 将 call invalid改为call valid

还有一种也很暴力的,也很棒的办法,就是直接将call invalid,改为call valid不就好了~。

image.png

测试一下~!

1690665045658.png

成功!

总结

用了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.


立志做一个有趣的碳水化合物