一、基本知识
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: