0 jmp指令

本文解析X86架构下JMP指令的工作原理,重点介绍短跳转、近跳转及远跳转的区别,并通过实例展示了如何计算跳转偏移量。

od随便打开一个记事本,汇编几条jmp指令,可以看到如下

地址      HEX        反汇编

010073B4   - E9 7B9E8787    JMP 88881234

010073B9   - E9 769E8787    JMP 88881234

010073BE   - E9 719E8787    JMP 88881234

010073C3   - E9 6C9E8787    JMP 88881234

010073C8   - E9 679E8787    JMP 88881234

010073CD   - E9 629E8787    JMP 88881234

010073D2   - E9 5D9E8787    JMP 88881234

010073D7   - E9 589E8787    JMP 88881234

010073DC   - E9 539E8787    JMP 88881234

010073E1   - E9 4E9E8787    JMP 88881234

010073E6   - E9 499E8787    JMP 88881234

可以看到同样的汇编指令,在不同的地址上的机器码不一样。

有啥关系呢?看第一条:88881234-010073b4=87879e80

这个值跟E9后面的那个值差了5(E9后面那个值要反过来看,因为X86是大端模式)


同样这个规律也使用与后面几条。


为什么呢?

下面摘录一个网上的


直接的jmp分3种 

Short Jump(短跳转)机器码 EB rel8 

只能跳转到256字节的范围内 

Near Jump(近跳转)机器码 E9 rel16/32 

可跳至同一个段的范围内的地址 

Far Jump(远跳转)机器码EA ptr 16:16/32 

可跳至任意地址,使用48位/32位全指针 

要注意的是,短跳转和近跳转指令中包含的操作数都是相对于(E)IP的偏移,而远跳转指令中包含的是目标的绝对地址,所以短/近跳转会出现跳至同一目标的指令机器码不同,不仅会不同,而且应该不同。而远跳转中包含的是绝对地址,因此转移到同一地址的指令机器码相同 

下面的指令是这样计算偏移的. 

004A2FCE   ^ E9 072BFEFF  jmp   00485ADA 

         ======== 

485ADA-4A2FCE=  FFFE2B0C  这里只是指向当前指令的IP处,实际计算跳转地址要去 

掉当前指令的长度,当前的跳转指令需要5个字节,FFFE2B0C-5=FFFE2B07


我们一般就用E9了,所以计算公式就是 要跳转的地址-指令所在的位置-5=机器码

当然 如果我们要在内存中写的话,肯定是写机器码的。也就是也E9 机器码。



结合上面的博文,可以在被HOOK的地址出写入JMP指令跳回到原来的地方,

被HOOK的地址-原来地址-5 = 机器码(这个就是要写入到 被HOOK地址的地方)

为什么不直接修改SSDT表,因为很多程序都会循环去看又没有被改回来,又会被修改回去。










本文转自 h2appy  51CTO博客,原文链接:http://blog.51cto.com/h2appy/1573921,如需转载请自行联系原作者
### jmp指令的工作原理 `jmp` 是一种控制流指令,主要用于实现程序中的无条件跳转功能。它通过修改程序计数器(PC)的值来改变程序执行的顺序[^1]。具体而言,当处理器遇到 `jmp` 指令时,会立即将 PC 的值设置为目标地址,从而使得下一条被执行的指令位于目标地址处。 #### 1. 跳转类型 `jmp` 指令可以分为两种主要形式: - **绝对跳转**:直接指定一个固定的内存地址作为目标地址。例如,在 x86 架构中,可以通过立即数或寄存器提供目标地址。 - **间接跳转**:目标地址存储在一个寄存器或内存单元中,CPU 需要先读取该地址再进行跳转。 以下是 x86 架构下的简单示例代码: ```asm ; 绝对跳转 jmp label ; 跳转到标签 'label' 处继续执行 ; 寄存器间接跳转 mov eax, target_address jmp eax ; 根据 EAX 中的目标地址进行跳转 ``` #### 2. 应用场景 `jmp` 指令广泛应用于各种编程需求中,包括但不限于以下几种情况: - 实现函数调用后的返回机制; - 控制循环结构的退出; - 支持分支语句(如 `if-else` 和 `switch-case`)的底层实现; - 执行状态机的状态切换逻辑。 值得注意的是,在某些高级语言编译过程中,可能会将复杂的条件判断转换成一系列基于比较结果的 `jmp` 操作序列[^3]。 #### 3. 流程表示方法的选择 为了更好地向不同受众群体解释涉及 `jmp` 指令的过程,可以选择适当的表现手法。如果面向非技术人员,则建议采用直观易懂的方式描绘基本动作链路;而针对开发者和技术专家,则需借助标准化图形符号精确刻画各个细节环节及其关联性[^2]。 --- ### 示例代码片段 下面给出一段伪汇编代码演示如何利用 `jmp` 完成简单的条件分支: ```asm section .data value db 5 ; 初始化变量值为5 section .text global _start _start: mov al, [value] ; 将'value'加载至AL寄存器 cmp al, 0 ; 对比 AL 是否等于零 je is_zero ; 如果相等则跳转至"is_zero" not_zero: ; 不为零时到达此处 inc al ; 增加 AL 的数值 jmp end_process ; 直接前往结束部分 is_zero: ; 当检测到零时进入此路径 dec al ; 减少 AL 的数值 end_process: ; 公共结尾段落 ... ``` 在此例子中可以看到,依据特定条件下产生的标志位变化决定下一步行动方向——这正是依靠了灵活运用 JMP 来达成目的的结果之一[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值