Системный вызов sys_execve из сборки - PullRequest
4 голосов
/ 18 февраля 2012

asm_execve.s:

.section .data
file_to_run:
.ascii       "/bin/sh"

.section .text
.globl main

main:
    pushl %ebp
    movl %esp, %ebp
    subl $0x8, %esp         # array of two pointers. array[0] = file_to_run  array[1] = 0

    movl file_to_run, %edi
    movl %edi, -0x4(%ebp)   
    movl $0, -0x8(%ebp)

    movl $11, %eax                      # sys_execve
    movl file_to_run, %ebx              # file to execute       
    leal -4(%ebp), %ecx                 # command line parameters
    movl $0, %edx                       # environment block
    int  $0x80              

    leave
    ret

Makefile:

NAME = asm_execve
$(NAME) : $(NAME).s
    gcc -o $(NAME) $(NAME).s

Программа выполнена, но sys_execve не вызывается:

alex@alex32:~/project$ make
gcc -o asm_execve asm_execve.s
alex@alex32:~/project$ ./asm_execve 
alex@alex32:~/project$ 

Ожидаемый результат:

alex@alex32:~/project$ ./asm_execve 
$ exit
alex@alex32:~/project$

Эта программа на ассемблере должна работать как следующий код C:

char *data[2];
data[0] = "/bin/sh"; 
data[1] = NULL;
execve(data[0], data, NULL);

Что-то не так в параметрах системного вызова?

Ответы [ 2 ]

10 голосов
/ 19 февраля 2012

Системный вызов execve вызывается , но вы действительно передаете ему неверные параметры.

(Вы можете увидеть это, запустив свой исполняемый файл, используя strace.)

Есть три проблемы:

  1. .ascii не завершает строку 0. (Возможно, вам повезет, поскольку в этом разделе .data в этом примере нет ничего следующего, но это не гарантировано ...) Добавьте 0 или используйте вместо него .asciz (или .string).

  2. movl file_to_run, %edi перемещает значение , указываемое на символом file_to_run, в %edi, то есть в первые 4 байта строки (0x6e69622f). адрес строки - это просто значение самого символа, поэтому для литеральных значений необходимо использовать префикс $: movl $file_to_run, %edi. Точно так же вы должны сказать movl $file_to_run, %ebx на несколько строк ниже. (Это общий источник путаницы между синтаксисом AT & T и синтаксисом Intel!)

  3. Параметры размещены в стеке в неправильном порядке: -0x8(%ebp) является более низким адресом, чем -0x4(%ebp). Таким образом, адрес командной строки должен быть записан в -0x8(%ebp), 0 должен быть записан в -0x4(%ebp), а инструкция leal должна быть leal -8(%ebp), %ecx.


Фиксированный код:

.section .data
file_to_run:
.asciz       "/bin/sh"

.section .text
.globl main

main:
    pushl %ebp
    movl %esp, %ebp
    subl $0x8, %esp         # array of two pointers. array[0] = file_to_run  array[1] = 0

    movl $file_to_run, %edi
    movl %edi, -0x8(%ebp)   
    movl $0, -0x4(%ebp)

    movl $11, %eax                      # sys_execve
    movl $file_to_run, %ebx              # file to execute       
    leal -8(%ebp), %ecx                 # command line parameters
    movl $0, %edx                       # environment block
    int  $0x80              

    leave
    ret
1 голос
/ 04 октября 2017

На самом деле вам не нужно ничего загружать в другие аргументы.Если вы делаете это в x86, следующий более простой код также будет работать:

.global _main
.section .text

.data
file_to_run:
.asciz "/bin/sh"

.section .text
.globl main

_main:
pushl %ebp
movl %esp, %ebp

movl $11, %eax                      # sys_execve
movl $file_to_run, %ebx              # file to execute       
movl $0, %ecx                       # Null value will work too
movl $0, %edx                       # Null will works too
int  $0x80              

leave
ret

Это откроет терминал оболочки после вызова системного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...