3

我正在尝试创建一些需要跳回的shellcode(负跳转)。我想跳回 2400 字节。这是我使用的操作码:

\x90\xE9\x98\xef

这首先是a nop,然后是接近跳跃到-4200。0xef98 = -4200(至少我认为是这样)。但是在调试器中它看起来像这样:

0:142> t
eax=00000000 ebx=7c9032a8 ecx=02a8eb70 edx=7c9032bc esi=00000000 edi=00000000
eip=02a8ffac esp=02a8ea94 ebp=02a8eaa8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
02a8ffac 90              nop
0:142> t
eax=00000000 ebx=7c9032a8 ecx=02a8eb70 edx=7c9032bc esi=00000000 edi=00000000
eip=02a8ffad esp=02a8ea94 ebp=02a8eaa8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
02a8ffad e998efcccc      jmp     cf75ef4a

正如预期的那样,首先是 nop,然后是 jmp,但跳转到的地址不是我所期望的(就像jmp 02A8EF45我所想的那样)。谁能看到我做错了什么?

4

3 回答 3

4

e9意味着jmp rel32你需要一个双字操作数,两个字节是不够的:

jmp $-4200    ; e9 93 ef ff ff

当您尝试这些事情时,使用汇编程序通常更容易:

$ cat shellcode.asm
bits 32
jmp $-4200
$ nasm -o shellcode shellcode.asm
$ hexdump -C shellcode
...
于 2013-02-17T19:43:54.797 回答
3

在我看来,好像您正在编写一个 32 位偏移量的跳转代码。查看生成的代码字节(示例的最后一行):

02a8ffad e998efcccc      jmp     cf75ef4a

处理器将使用该值0xccccef98作为跳转偏移量。如果你想要一个 16 位的偏移量,你必须明确地指定它。或者(已经有一段时间了),您必须提供一个 32 位操作数。

于 2013-02-17T19:42:24.000 回答
2

努力制作一个新的 ASM 编译器和 66 前缀似乎对我不起作用。

[66 E9 XX XX] 总是导致 GPF。

看来您不能将 66 用于 JXX(JMP、JNE、JBE 等)

查看推送:

6A 12          = PUSH 12    (IM8 as a 32bits)
68 34 12 00 00 = PUSH 1234  (32 bits)

66 6A 00       = PUSH 0     (IM8 as a 16 Bits)
66 68 34 12    = PUSH 1234  (16 bits)

您注意到也没有 OPCode 将 16 位立即推送为 32 位 =D

我现在的猜测是 Martin 一开始是对的,你不能使用它,因为它会将 CPU 与 REAL MODE 混淆。

于 2013-05-13T20:10:33.690 回答