【问题标题】:JMP rel16 (instead of JMP rel32)JMP rel16(而不是 JMP rel32)
【发布时间】:2015-01-22 22:29:39
【问题描述】:

我需要为漏洞利用演示制作一个跳转操作码。

我需要在跳转指令之后跳转到大约 200 个字节。这对jmp short 来说太过分了。

如果我生成一个带有常规跳转的操作码,jmp $200 我会得到这个:

e9 fb 01 00 00

这里的问题是操作码包含 00,它在将字符串传递给程序时被解释为字符串的结尾(因此我无法传递包含它的完整 shellcode)。

我以为我的方法搞砸了,但后来I checked the manual 在第二行显然有一个“近跳”,需要 2 个字节(还有另一个需要 4 个字节,我在上面显示的那个)。这两个跳转都以相同的字节 e9 开始。

如何将e9 fb 01 作为只需要两个字节参数的近跳转传递?如何防止操作系统在e9之后查找四个字节,即:e9 fb 01 90 90

【问题讨论】:

  • 为什么需要将程序作为字符串传递?可以用长度前缀字符串吗?
  • 寻找四个字节的肯定不是操作系统,而是处理器

标签: assembly x86 exploit opcode


【解决方案1】:

你不能。

0xE9 操作码在处理器运行于 32 位模式时使用 32 位偏移量,而仅在处理器处于 16 位模式时使用 16 位偏移量。

【讨论】:

  • 谢谢,我就是这么想的。我认为没有空字节就无法进行这种相对跳转。
  • 从技术上讲,这不是真的。您可以使用操作数大小覆盖。这样做的问题是目标 EIP 将被屏蔽为 16 位。 @Juicy:作为一种解决方法,您可以使用 2 次跳跃来弥补差距。
  • @Jester 谢谢,我看看能不能找到一种方法,通过两次短跳来做到这一点
  • @Jester 是的,我在另一篇文章中发现了 66 操作数,但就像你说的,它掩盖了一个 16 位目标 eip,所以它没有帮助。
【解决方案2】:

如果你可以访问 shellcode 中的当前 EIP 地址并且内存区域是可写的,你可以这样做:

; say in ECX you have shellcode start address
; (calculated with delta offset etc.)
_start:

...

; ECX = offset _start

; decrypt zero bytes in jmp instruction relative address

; 80 69 xx  AB
sub byte ptr[ecx+(_fix1-_start)], 0ABh

; 80 69 xx+1 BA
sub byte ptr[ecx+(_fix2-_start) + 1], 0BAh

; jmp instruction with those 00s encrypted
_jmp  db 0E9h, 0FBh, 01h ; first 3 bytes of jmp near instruction
_fix1 db 0 + 0ABh        ; encrypted displacement (last 2 bytes)
_fix2 db 0 + 0BAh     

所以jmp near指令中编码的相对地址不包含00,但在运行时这些字节会被恢复。

请记住,如果与计算 (_fix1-_start) 的差异包含零,则解密指令也可能包含 00,如果生成的指令是 sub [r32 + imm32], imm8) 的长形式,则更有可能,所以检查一下也可以手动。

【讨论】:

  • 如果你可以访问EIP,你可以直接做一个间接跳转,不需要弄乱自修改代码。
  • 嗯,你总是可以用增量偏移或 FPU(最新执行的指令)来计算它,所以获取当前 EIP 的代码并不是什么大问题。
猜你喜欢
  • 2022-12-17
  • 2016-11-27
  • 2023-04-04
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2017-10-09
相关资源
最近更新 更多