Второй аргумент для execve - это адрес массива строковых указателей (char **
или char *argv[]
). Вы дали ему адрес одной строки (char *
).
Также execve(2)
принимает третий параметр, список среды. Как описывает man-страница, argv и / или envp могут иметь значение NULL, и Linux рассматривает это как эквивалент пустого списка (действительный указатель на NULL в памяти).
Вот что должно быть:
mov rax, 59
lea rdi, [rel bin]
lea rsi, [rel args]
xor edx, edx ; Linux accepts NULL instead of a pointer to NULL
syscall
; section .rodata
align 8
args dq bin, arg1, arg2, 0
arg1 db '-c',0
arg2 db '/bin/id',0
bin db '/bin/bash',0
Если вы пишете шелл-код, обратите внимание, что он содержит несколько байтов 0
как в инструкциях (неотрицательные rel32
режимы адресации и 32-битные непосредственные значения), так и в данных.
Если вы не пишете шелл-код (который будет извлечен в плоский двоичный файл с кодом и данными вместе), поместите ваши данные в отдельный раздел, предпочтительно .rodata
для данных только для чтения.