Код операции для отрицательного скачка


Я пытаюсь создать некоторый шеллкод, где мне нужно прыгнуть назад (отрицательный прыжок). Я хочу вернуться на 2400 байт назад. И это код операции, который я использую:

x90xE9x98xef

Это сначала 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 будет то, что я имел в виду). Кто-нибудь может видеть, что я сделал? неправильно?

3 3

3 ответа:

Мне кажется, что вы кодируете скачок с 32-битным смещением. Посмотрите на сгенерированные байты кода (последняя строка вашего примера):

02a8ffad e998efcccc      jmp     cf75ef4a

Процессор будет использовать значение 0xccccef98 в качестве смещения перехода. Если вы хотите 16-битное смещение, вы должны указать его явно. Или (это было уже давно), вам придется предоставить 32-битный операнд.

e9 значит, вам нужен операнд dword , двух байт недостаточно:

jmp $-4200    ; e9 93 ef ff ff

Часто проще использовать ассемблер, когда вы пробуете эти вещи:

$ cat shellcode.asm
bits 32
jmp $-4200
$ nasm -o shellcode shellcode.asm
$ hexdump -C shellcode
...

Работа над созданием нового компилятора ASM и префикса 66, похоже, просто не работает для меня.

[66 E9 XX XX] всегда вызывают GPF.

Похоже, вы не можете использовать 66 для JXX (JMP, JNE, JBE и т. д..)

Проверьте PUSH:

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)

Вы заметили, что также нет кода операции, чтобы толкать 16 бит сразу как 32bits =D

Теперь я думаю, что Мартин был прав сначала, вы не можете использовать его, потому что это спутает процессор с реальным режимом.