我在理解程序集中更复杂的系统调用时遇到了一些麻烦。我写了一个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 []);
全部谢谢
答案 0 :(得分: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
答案 1 :(得分:3)
您不会将字符串放入寄存器中。您应该将指针(地址)传递给此函数的寄存器中的null(0)终止字符串(C样式)。某些系统调用(如write
)采用指针(不一定由'\0'
终止)和两个寄存器中的长度。
# somewhere in the data section:
myString:
.asciz "/bin/bash"
并使用寄存器传递$myString
。