破解密码验证程序

来源:互联网 发布:淘宝网应用 编辑:程序博客网 时间:2024/06/01 10:50

程序:由 密码验证程序 编译出来的 .exe 文件
工具:IDA Por、OllyDbg、LoadPE、UltraEdit、VS\VC++

在本次破解中,由源代码编译出来的.exe文件命名为 crack.exe

首先用 IDA 打开 crack.exe

在 IDA View-A 中找到 main 函数(默认情况下IDA会自动识别出main函数)
这里写图片描述

然后 按空格键,出现如下界面
这里写图片描述

从这里可以看到,程序并不是一开始就执行main函数的,而是有一些其他的前期准备工作。

我们双击 _main 然后IDA的图形界面会跳转到程序流程图
,找到如下流程
这里写图片描述
我们可以看到,jz(jump if zero)指令下方有两个分支,符合C语言中if语句的效果,以此我们判断这条jz指令就是.c源文件中的if语句

单击选择 jz,然后按空格键,IDA会转到jz指令所在的汇编指令界面
这里写图片描述
光标高亮的语句就是我们在图形界面中选中的引起程序分支的指令,可以看到这条指令位于PE文件的.text节,它在运行时的内存地址为VA:004010E5

接着打开 OllyDbg 进行动态调试来看看程序到底是如何分支的。
用OllyDbg打开crack.exe
这里写图片描述
(其实如果现在就已经可以读取到正确密码了,注意那一行:ASCII “1234567”)

用快捷键Ctrl+G,直接跳转到VA:004010E5
这里写图片描述

选择这条指令,按F2设置断点,这时指令的地址会被标记为不同颜色。
按F9键让程序运行起来,这时控制权会回到程序,OllyDbg暂时挂起,在Console中随便输入一个错误的密码,回车确认后,控制权会被OllyDbg收回。
这里写图片描述

密码验证函数verify_password()的返回值会被储存在EAX寄存器中,所以if语句是通过以下两条指令实现的

TEST EAX,EAXJE [XXXXX]

也就是说当EAX中的值为0时,跳转将被执行,程序进入密码确认流程,否则跳转不执行,进入密码重输流程。

如果我们把JE修改为JNE(jump when not equal)那么输入错误密码将会被确认,输入正确密码反而要求重新输入;
或者将

TEST EAX,EAX

改为

XOR EAX,EAX

那么无论密码正确与否,都会得到确认。

双击 JE 指令,将其修改为 JNE ,单击Assemble按钮将其写入内存
这里写图片描述

这时我们按F8单步执行,可以看到跳转被执行,输出了“Congratulation! You have passed the verification!”
这里写图片描述

但这只是在内存中修改程序,我们还要进一步在PE文件中修改相应的字节。
用LoadPE打开crack.exe
这里写图片描述
记下ImageBase(基址):00400000

查看区段
这里写图片描述
由于jz指令位于PE文件的.text节,我们只需记下.text节的VOffset(文件虚拟地址):00001000和ROffset(文件物理址):00001000即可

根据VA与文件地址(FileOffset)的换算公式:
FileOffset = VA - ImageBase - VRk
VRk = VOffset - ROffset

可以计算出:
FileOffset
= VA - ImageBase - (VOffset - ROffset)
= 0x004010E5 - 0x00400000 - (0x00001000 - 0x00001000)
= 0x000010E5

也就是说,这条指令在PE文件中距离文件开始处0x000010E5字节的地方,用UltraEdit打开crack.exe文件
铵快捷键Ctrl+G,输入0x000010E5直接跳转到JE指令的机器代码处
这里写图片描述
74即JE,我们将其改为75(JNE)
保存后重新运行程序,这时输入错误密码可以得到确认,输入正确密码”1234567”反而提示错误了。
这里写图片描述