一、基本知识
1. 常用指令机器码
- 不同版本对应机器码不同,这里以我做实验的kali(Intel 80386)为例。
| 指令 | 作用 | 机器码 | 
|---|---|---|
| nop | 无作用(no operation) | 90 | 
| call | 调用子程序,子程序以ret结尾 | e8 | 
| ret | 返回程序 | c3 | 
| cmp | 比较 | c3 | 
| jmp | 无条件跳转 | eb | 
| je/jz | 若相等则跳转 | 74/84 | 
| jne/jnz | 不相等则跳转 | 75/85 | 
| mov | 传值 | 89 | 
| movl | 长字传值 | c7 | 
- 实际上使用更改的主要是跳转指令。
2. 修改工具
(1)反汇编:objdump
- 
输出目标文件的符号表: objdump -t obj![]() 
- 
输出目标文件的所有段概括 objdump -h obj![]() 
- 
输出反汇编源代码结果 objdump -d obj![]() 
(2)十六进制编程器
- 
查看文件的十六进制编码(输出规范的十六进制和ASCII码): hexdump -C obj![]() 
二、程序破解实践
1. login程序简述
- 
基本功能:模拟登陆过程。 
- 
初始密码:2046 
- 
登陆成功: ![]() 
- 
登陆失败: ![]() 
2. 使用反汇编查看login程序
objdump -d login
- 
找到main函数部分,可以看到: ![]() 
- 
密码:07feH(即十进制2046) 
- 
输入比较: - 若成功,继续执行后面的代码(804858),打印成功信息。
- 若失败,则跳转到8048466处的代码,打印失败信息。
 
3. 修改程序
- 
基本步骤: - 用编辑器打开 - 使用命令 `:%!xxd` 转换显示十六进制 - 进行修改 - 使用命令 `:%!xxd -r` 还原显示 - 保存退出
(1)实现任何输入都成功登录
- 
找到比较 750e处:![]() 
- 
将 e更改为0,不判断条件而是直接执行下面登录成功的代码:![]() 
- 
运行,任意输入密码验证: ![]() 
(2)实现任何输入都无法成功登陆
- 
找到比较 750e处:![]() 
- 
将 75更改为eb,将条件跳转更改为无条件跳转,直接执行登陆失败的代码:![]() 
- 
运行,输入密码2046: ![]() 
(3)实现密码更改
- 
找到密码 07fe处:![]() 
- 
将 07fe更改为14c5(即十进制的5317),注意使用大端法写入:![]() 
- 
运行,输入原密码2046和新密码5317: ![]() 
 
                    
                 















