《0day安全》第1章Crack小实验复现

《0day安全》第1章的实验,由于离此书出版已经过去很久了,因此很多软件和操作系统已经非主流,书中提到“如果完全采用实验指导所推荐的实验环境,将精确地重现指导中所有的细节,包括动态调试时的内存地址和静态调式的文件偏移地址;否则,一些地址可能需要重新调试来确定”。当时作者使用的是Windows XP SP2+Visual C++ 6.0,目前都已经不再被广泛使用,同时鉴于自己刚开始学习逆向知识,因此想挑战一下。我采用的操作系统为Win10英文版,IDE使用的是CodeBlocks(最开始使用的是VS2022,但是感觉逆向的效果不如CodeBlcoks效果好)。
首先是书中的一段C语言代码:

编译生成exe之后执行,当输入1234567时会打印成功的提示,其余输入均会打印错误信息

这段代码的逻辑很简单,正如书中所述,如果想破解此程序,即输入错误的密码也可以通过验证,需要修改if判断所在的位置。
使用IDA打开exe文件,查看IDA的流程图界面

找到C代码中的if分支点:jnz short loc_402C60,用鼠标选中这条指令后点击空格,切换到汇编指令界面。

这条指令的地址位于PE文件的.text节,并且IDA已经自动将该指令的地址换算成了运行时的内存地址VA:0x00402CBF
书中使用OllyDbg对exe做了动态调试,这里我用的是x64dbg
我们可以按快捷键Ctrl+G直接跳到有IDA得到的VA:0x00402CBF处查看那条引起程序分支的关键指令。

if语句通过以下两条指令实现:
test al,al
jne crackme2.402C60
也就是说如果用户输入的密码不对,就会跳转到402C60的位置去打印报错信息,如果输入的密码正确,jne不发生跳转,就将继续执行下面的命令,打印正确
这是右键这条指令,选择“assemble”,将jne(75)改为je(74),这表明在输入错误的密码后,反而会继续执行打印密码正确的提示

通过对比就可以发现,我们对if语句的修改成功了。

上面只是在内存中修改程序,下面我们尝试在二进制文件中修改相应的字节。
使用LordPE打开crackme.exe,查看PE文件的节信息,首先点击“PE Editor”,然后点击“Sections”,如下图所示。


前面已经知道跳转指令在内存中的地址是VA=0x00402C8F,
按照VA与文件地址的换算公式:文件偏移地址 = 虚拟内存地址(VA)- 装载基址(Image Base) - 节偏移
其中节偏移 = 相对虚拟偏移量/相对虚拟地址(RVA)- 文件偏移量/文件偏移地址(File Offset),前者在LordPE中被标识为VOffset,后者在LordPE中被表示为ROffset。
文件偏移地址 = 虚拟内存地址(VA)- 装载基址(Image Base) - 节偏移
= 0x00402C8F - 0x00400000 - (0x00001000 - 0x00000400)
= 0x208F
也就是说这条这令在PE文件中位于距离文件开始处0x208F的位置,原书中提到使用UltraEdit按照二进制方式打开crackme.exe,这里我使用开源软件imhex来替代UltraEdit,imhex可在github上下载。
按快捷键Ctrl+G,输入0x208F直接跳到JNE指令的机器代码处。

双击这个字节,将其由75(JNE)修改成74(JE),保存后重新运行可执行文件。

重新执行修改过的exe,当输入正确的密码“1234567”时,会提示错误。如果输入任意其他内容,则提示正确。

posted @ 2025-05-17 12:11  歌德巴赫猜想  阅读(6)  评论(0)    收藏  举报