Я пытаюсь понять, как работает системный вызов execve
и базовая сборка.Вот мой пример программы:
// p1.c
#include <stdio.h>
void main() {
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
}
Моя система x86_64
.Я скомпилировал его, используя gcc -ggdb -static -fno-stack-protector p1.c
.Версия Gcc была 7.3.0
Вот objdump -d ./a.out
только для main
0000000000400b4d <main>:
400b4d: 55 push %rbp
400b4e: 48 89 e5 mov %rsp,%rbp
400b51: 48 83 ec 10 sub $0x10,%rsp
400b55: 48 8d 05 08 14 09 00 lea 0x91408(%rip),%rax # 491f64 <_IO_stdin_used+0x4>
400b5c: 48 89 45 f0 mov %rax,-0x10(%rbp)
400b60: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
400b67: 00
400b68: 48 8b 45 f0 mov -0x10(%rbp),%rax
400b6c: 48 8d 4d f0 lea -0x10(%rbp),%rcx
400b70: ba 00 00 00 00 mov $0x0,%edx
400b75: 48 89 ce mov %rcx,%rsi
400b78: 48 89 c7 mov %rax,%rdi
400b7b: e8 50 7f 04 00 callq 448ad0 <__execve>
400b80: 90 nop
400b81: c9 leaveq
400b82: c3 retq
400b83: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400b8a: 00 00 00
400b8d: 0f 1f 00 nopl (%rax)
Я понял каждую строку до вызова callq 448ad0 <__execve>
.Затем я проверил сборку __execve
из вывода objdump
.
0000000000448ad0 <__execve>:
448ad0: b8 3b 00 00 00 mov $0x3b,%eax
448ad5: 0f 05 syscall
448ad7: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
448add: 73 01 jae 448ae0 <__execve+0x10>
448adf: c3 retq
448ae0: 48 c7 c1 c0 ff ff ff mov $0xffffffffffffffc0,%rcx
448ae7: f7 d8 neg %eax
448ae9: 64 89 01 mov %eax,%fs:(%rcx)
448aec: 48 83 c8 ff or $0xffffffffffffffff,%rax
448af0: c3 retq
448af1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
448af8: 00 00 00
448afb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Я понял, что регистры edx,rsi,rdi
используются для передачи аргументов execve
из функции main
.Но я не могу найти ассемблерный код для обработки этих аргументов внутри __execve
кода.
То, что я думаю $0x3b
, возможно, номер системного вызова и инструкция syscall
скрывают большую часть реализации.Если я выполняю интерактивные шаги вперед в gdb, то после запуска оболочки syscall instruction
at 448ad5:
.
Могу ли я узнать (если да как ?), Какие еще регистры и используются для обработки аргументов и выполнения системного вызова __execve
?Или инструкция syscall
по адресу 448ad5:
напрямую принимает значения аргументов из регистров edx,rsi,rdi
?