Web View
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
### 怎么识别指令跳转条件和内存访问
|
||||
|
||||
**如何识别指令跳转条件**
|
||||
|
||||
在汇编语言中,跳转指令分为**无条件跳转**和**有条件跳转**
|
||||
|
||||
**1. 无条件跳转**
|
||||
|
||||
这是最简单的一种。它们总是会改变程序的执行流程
|
||||
|
||||
- **指令**:`jmp` (Jump)
|
||||
- **识别方法**:在反汇编代码中,`jmp` 指令后面通常跟着一个目标地址。它像一个程序里的 `goto` 语句,直接将控制权转移到另一个位置,没有其他条件
|
||||
|
||||
**2. 有条件跳转**
|
||||
|
||||
这些跳转指令依赖于 CPU 的**标志寄存器(Flags Register)**的状态。标志寄存器中的位(如零标志、符号标志、进位标志等)在执行算术或比较指令后会被设置
|
||||
|
||||
- **指令**:有条件跳转指令通常以字母 `j` 开头,后面跟着一个或两个字母来表示其条件
|
||||
- `je` (Jump if Equal):如果零标志(ZF)为1,则跳转。通常跟在 `cmp` 或 `test` 指令之后,用于判断两个值是否相等
|
||||
- `jne` (Jump if Not Equal):如果零标志(ZF)为0,则跳转
|
||||
- `jg` (Jump if Greater):如果大于则跳转(有符号)
|
||||
- `jl` (Jump if Less):如果小于则跳转(有符号)
|
||||
- `ja` (Jump if Above):如果大于则跳转(无符号)
|
||||
- `jb` (Jump if Below):如果小于则跳转(无符号)
|
||||
- **识别方法**:
|
||||
1. **寻找前置指令**:有条件跳转指令通常紧跟在**比较(`cmp`)**或**测试(`test`)**指令之后
|
||||
2. **分析标志位**:`cmp` 指令会执行一次减法操作,但不保存结果,只根据结果设置标志位。`test` 指令会执行一次逻辑与操作,也不保存结果,同样只设置标志位
|
||||
3. **理解逻辑**:当看到 `cmp eax, ebx` 后跟着 `je` 时,它的逻辑就等同于 C 语言的 `if (eax == ebx)`
|
||||
|
||||
**如何识别内存访问**
|
||||
|
||||
内存访问涉及程序从内存中读或写数据。在汇编代码中,这通常通过方括号 `[]` 来表示
|
||||
|
||||
**1. 直接内存访问**
|
||||
|
||||
这是最直接的方式,通常是访问全局变量或特定地址
|
||||
|
||||
- **格式**:`mov eax, [0x401000]`
|
||||
- **识别方法**:指令的操作数直接是一个十六进制地址,且用方括号包围。这表示从这个地址读取数据。例如,`mov eax, [0x401000]` 的意思是把内存地址 `0x401000` 处的值加载到 `eax` 寄存器
|
||||
|
||||
**2. 间接内存访问**
|
||||
|
||||
间接访问更为常见,它通过寄存器中存储的地址来访问内存
|
||||
|
||||
- **格式**:`mov eax, [ebx]`
|
||||
- **识别方法**:方括号中是一个寄存器。这表示程序从寄存器 `ebx` 中存储的地址读取数据。这在访问指针、数组元素或动态分配的内存时非常常见
|
||||
|
||||
**3. 相对内存访问**
|
||||
|
||||
这种方式结合了基址寄存器和偏移量
|
||||
|
||||
- **格式**:`mov eax, [ebx + 8]`
|
||||
- **识别方法**:方括号中包含一个基址寄存器(如 `ebx`)和一个数字偏移量。这通常用于访问结构体成员或栈上的局部变量。例如,`mov eax, [ebp-4]` 是一种非常常见的模式,它表示访问栈上**栈帧基址**(`ebp`)向下偏移 4 字节处的局部变量
|
||||
|
||||
**4. 复杂内存访问**
|
||||
|
||||
更复杂的访问模式包括索引寄存器和比例因子,通常用于访问数组
|
||||
|
||||
- **格式**:`mov eax, [ebx + esi * 4]`
|
||||
- **识别方法**:这表示一个数组访问,`ebx` 是数组的基地址,`esi` 是索引,`4` 是每个元素的大小(例如,一个 `int` 占 4 字节)。这等同于 C 语言的 `eax = array[esi]`
|
||||
Reference in New Issue
Block a user