一、基本知识
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:
![]()














