JMP rel16(而不是 JMP rel32)

JMP rel16 (instead of JMP rel32)

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

我需要在跳转指令后跳转到大约200字节。这对于 jmp short.

来说太多了

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

e9 fb 01 00 00

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

我以为我的方法搞砸了,但是 I checked the manual 并且在第二行显然有一个 "near jump" 占用 2 个字节(还有另一个占用 4 个字节,我如上所示)。这两个跳转都以相同的字节开始,e9.

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

你不能。

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

如果您可以访问 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 的长格式,则更有可能) , 所以也要手动检查一下。