软安实验1:逆向破解初步
破解test
先用vc++6.0将test.c编译成test.exe

运行exe文件
如果输入错误的密码,会输出“incorrect password!”,并重新输入。如果正确,则输出“Congratulation! You have passed the verification!”并结束程序。

Ollydbg调试

F8单步运行至停止处,这里需要等待输入,下断点

ctrl+F2重载,F9运行至断点处,F7步入函数查看

这里展示了核心逻辑

- 提示用户并获取输入 (地址
00401076-0040108A) - 调用密码验证函数 (地址
0040108F-00401094)- 函数返回值到
EAX寄存器中。根据strcmp的原理,如果密码正确,EAX的值会是0;如果错误,则为非0。
- 函数返回值到
- 核心判断逻辑 (地址
0040109C-0040109E)test eax, eax:如果EAX的值是0,那么零标志位(Zero Flag, ZF)就会被设置为1
- 两个路径:
je指令没有跳转,则运行 失败路径;je指令成功跳转,则运行 成功路径
破解
法1:反转跳转逻辑
将je改成jne即可让跳转逻辑反转,密码错误时输出“Congratulation”

保存修改


运行,逻辑已经相反

法2:直接赋值eax
既然eax=0是密码正确时的返回值,那么可以直接将0赋值给eax。但这里不能用mov eax,0(5个字节),因为test eax,eax指令长度只有2个字节。可以使用xor eax,eax(2个字节)代替

修改后保存
输入任何字符都会成功

破解Crackme
运行,尝试输入,注册失败

Ollydbg调试
右键→查找→所有参考文本字串

双击“crackmepassword”

在此处下断点,F9运行

输入用户名和密码后程序停在断点处

F8单步运行,并在跳转的位置用注释标出“跳转是否实现”

运行到0040163E弹出“注册失败”

由此可知,上面的两个跳转决定了注册成功还是失败
对关键的汇编代码进行分析

法1:修改跳转逻辑

修改后保存,运行
输入密码任意,都会显示注册成功

法2:修改判断逻辑
已经分析得到,字符串比较完后,结果存入eax,相等则是0,不相等非0。又通过test eax,eax判断eax是否为0。
可以直接给eax赋值为0,从而不进行jnz short 00401637的跳转,运行注册成功的函数。

修改后保存,运行
输入任意密码都显示注册成功

法3:NOP填充法

修改后保存,运行

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Bastandern's Blog!
评论

