Для сборки с помощью gcc вы определяете _start
, а не main
, поэтому вам нужно использовать -nostdlib
. Как gcc -m32 -nostdlib -static -o key shellcode.o
. Это заставит gcc вызывать ld
так, как вы это делали вручную.
loop
доступен только со смещением rel8, поэтому он не может достичь абсолютного адреса 0xb7
с гораздо более высокого адреса, где ld
размещает его в сегменте кода.
Если вы действительно хотите это сделать (но вы почти наверняка этого не сделаете) , вы можете использовать dec ecx / jnz 0xb7
, который будет использовать кодировку jcc rel32
и, следовательно, можно получить любой абсолютный адрес через EIP + rel32
. Или используйте скрипт компоновщика, чтобы связать сегмент TEXT по очень низкому виртуальному адресу, чтобы loop rel8
мог достичь.
(Но в любом случае это не зависит от позиции. Обычно шелл-код должен работать после внедрения по неизвестному адресу. Если вы действительно хотите перейти к абсолютному адресу в независимом от позиции шелл-коде, например, вызвать конкретную ошибку страницы (?), вам нужен адрес в реестре и использовать jmp eax
)
Но гораздо более вероятно, что вы захотите перейти в другое место в своем коде , а не к какому-либо низкому абсолютному адресу. Поместите метку на цель вашего филиала и используйте dec ecx / jnz label
. (Или используйте инструкцию loop
, так как вы, вероятно, оптимизируете размер кода независимо от того, насколько он медленный.)
Если вы позаимствовали этот код где-то, возможно, он находился в ассемблере, где loop 0xb7
устанавливает значение смещения rel8
. Или, может быть, это был NASM с org 0x0
и BITS 32
, делающими плоский двоичный файл? Но было бы гораздо больше смысла просто использовать метку, если вы хотите вернуться обратно в этот код.