2009-11-20 11 views
1

У меня проблемы с пониманием более сложных системных вызовов в сборке. Я написал EXEC системный вызов, и он работал большойСборочные и системные вызовы

.bss 

.text 

.globl _start 

_start: 

#exit(0) system call 

     movl $1, %rax 
     movl $0, %rbx 
     int $0X80 

Хотя я немного подстраховаться и не смогли найти информацию, касающиеся того, как вы положили строки в регистр. Так, например, я хотел бы выполнить системный вызов exec, и ему, поскольку его первому параметру требуется имя файла для запуска, и я хочу запустить «/ bin/bash», но как получить его в rbx. Как я даже знаю, что мне нужно использовать rbx, в X86 я знаю, что буду использовать ebx, это те же отношения в amd64 ebx = rbx, ecx = rcs и т. Д.

int execve (const char * filename, char * const argv [], char * const envp []);

Все

ответ

4

Вот трюк, чтобы быстро продвигаться по этим аспектам сборки: попросите компилятор C показать вам, как он это делает! Напишите программу C, которая делает то, что вы хотите сделать, и введите gcc -S.

Пример:

Manzana:ppc pascal$ cat t.c 
#define NULL ((void*)0) 
char *args[] = { "foo", NULL } ; 
char *env[] = { "PATH=/bin", NULL } ; 


int execve(const char *filename, char *const argv[], char *const envp[]); 

int main() 
{ 

    execve("/bin/bash", args, env); 

} 

затем:

Manzana:ppc pascal$ gcc -S -fno-PIC t.c # added no-PIC for readability of generated code 
Manzana:ppc pascal$ cat t.s 
.globl _args 
    .cstring 
LC0: 
    .ascii "foo\0" 
    .data 
    .align 2 
_args: 
    .long LC0 
    .long 0 
.globl _env 
    .cstring 
LC1: 
    .ascii "PATH=/bin\0" 
    .data 
    .align 2 
_env: 
    .long LC1 
    .long 0 
    .cstring 
LC2: 
    .ascii "/bin/bash\0" 
    .text 
.globl _main 
_main: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $24, %esp 
    movl $_env, 8(%esp) 
    movl $_args, 4(%esp) 
    movl $LC2, (%esp) 
    call _execve 
    leave 
    ret 
    .subsections_via_symbols 
3

Вы не ставите строки в регистр. Вы должны передать указатель (адрес) в строку с нулевым (0) завершенным (стиль C) в регистре для этой функции. Некоторые системные вызовы (например, write) принимают указатель (не обязательно завершаемый '\0') и длину в двух регистрах.

# somewhere in the data section: 
myString: 
    .asciz "/bin/bash" 

и пройти $myString используя регистр.

+0

теперь я понимаю, спасибо. – Recursion

+0

, но вы имеете в виду .asciiz правильно, поэтому его нуль завершен? – Recursion

+0

Рекурсия: Да. –

Смежные вопросы