В 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). Но, вероятно, это не важно в шеллкоде