разборка системного вызова execve - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь понять, как работает системный вызов 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?

...