Как получить указатель инструкции в x86_64 без байтов 0x00 или 0xFF? - PullRequest
0 голосов
/ 28 августа 2018

Есть ли способ получить доступ к значению в указателе инструкций (RIP) без использования call, за которым следует pop на ассемблере? Или есть опкод машинного кода, который может это сделать?

Я гуглил без четких результатов.

Моя проблема в том, что у меня не может быть нулей в машинном коде, иначе я получаю ошибку SIGSEGV. Это связано с тем, как сервер загружает код и выполняет его из строки байтов. Ближайший вызов имеет нули на расстоянии от подпрограммы, поэтому использование вызова не вариант.

Я нахожусь на Linux, 64-битной, и у меня есть нос и ясм.

1 Ответ

0 голосов
/ 28 августа 2018

В x86_64 стандартным способом является использование относительной RIP-адресации вместо CALL, как в x86. Даже тогда, колл / поп не рекомендуется 1

Обычно вы будете использовать lea rax, [rip] для передачи RIP в RAX (который на самом деле кодируется как lea rax, [rip + 0] с четырьмя байтами для непосредственного конца). Однако, поскольку LEA не разыменовывает адрес памяти, вы можете просто добавить любое постоянное смещение в RIP и вычесть его позже

0:  48 8d 05 04 03 02 01    lea    rax,[rip+0x1020304]
7:  48 2d 04 03 02 01       sub    rax,0x1020304

Вы можете выбрать любые непосредственные значения, которые не имеют нулевого или 0xFF байта. Если вам нужен адрес инструкции после lea (длина которого составляет 7 байт), вы можете исправить его с помощью sub rax, 0x01020304 - 7


1 Рекомендуемый способ равен

GetCurrentAddress:
    mov eax, [esp]
    ret
...
    call GetCurrentAddress
    mov [currentInstruction], eax

во избежание несоответствия между стеком вызовов и буфером стека возврата (RSB). Но, вероятно, это не важно в шеллкоде

...