Ошибка сегментации происходит до запуска любого кода Сборка

Я пытаюсь написать программу с кодом оболочки, которая будет вызывать execve и создавать оболочку. Я работаю на 32-битной виртуальной машине, которая была предложена для этого класса. Код выглядит следующим образом:

section .text

global _start

_start:
;clear out registers
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
;exacve("/bin/sh",Null,NULL)
;ascii for /bin/sh;
;2f 62 9 6e 2f 73 68 3b
push 0x3b68732f
push 0x6e69622f
mov ebx, esp
mov al, 11
int 0x80
;exit(int status)
movv al, 1
xor ebx, ebx
int 0x80

Я компилирую с nasm -f elf -g shell.asm и связываю с ld -o shell shell.o Когда я пытаюсь запустить его, я получаю ошибку сегментации. Я попытался использовать gdb, чтобы увидеть, где я допустил ошибку, но он дает сбой, даже если установить точку останова на _start+0. Пишет, что был segfault по адресу после последней инструкции кода. т. е. если последняя строка имеет адрес 0x804807c, то ошибка сегментации происходит по адресу 0x804807e до того, как какой-либо код сможет запуститься.

Может ли кто-нибудь указать мне правильное направление, чтобы я мог понять, как это исправить?


person a1j9o94    schedule 27.12.2013    source источник
comment
Обратите внимание, что отладчик может не иметь возможности правильно установить точку останова. Такое случается... Таким образом, он может выполняться, и отладчик обнаруживает проблему, но не может понять, в чем проблема.   -  person Alexis Wilke    schedule 27.12.2013


Ответы (1)


Одна ошибка в вашем коде заключается в том, что в ascii-коде строки нет 0x3b:

;exacve("/bin/sh",Null,NULL)
;ascii for /bin/sh;
;2f 62 9 6e 2f 73 68 3b
push 0x3b68732f
push 0x6e69622f

Следующий код должен решить эту проблему (при условии, что вы работаете с машиной с прямым порядком байтов):

;exacve("/bin/sh",Null,NULL)
;ascii for /bin/sh;
;2f 62 99 6e 2f 73 68 00
push 0x0068732f
push 0x6e69622f
person starrify    schedule 27.12.2013
comment
Спасибо. Я почему-то думал, что в последнем стоит точка с запятой. - person a1j9o94; 27.12.2013
comment
@ a1j9o94 a1j9o94 Даже если это точка с запятой, вам все равно нужно что-то, чтобы указать, где заканчивается строка, верно? :) Или программы бы точно не знали. Обычно принято, что строка должна заканчиваться нулевым символом (0x00). - person starrify; 27.12.2013
comment
В конце концов я понял, что именно поэтому я получаю ошибку seg. Сначала мне пришлось поместить в стек один из пустых регистров. - person a1j9o94; 28.12.2013