Dlaczego pusty program wywołuje tyle funkcji systemowych?

0

Pusty program w C:

 int main(){}

Kompiluję:

 gcc wtf.c

Wywołuję:

 strace ./a.out

Wypisuje mi od cholery zawołań systemowych:

 execve("./a.out", ["./a.out"], [/* 56 vars */]) = 0
brk(NULL)                               = 0x10ed000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7850b46000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=140688, ...}) = 0
mmap(NULL, 140688, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7850b23000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f785055a000
mprotect(0x7f7850719000, 2097152, PROT_NONE) = 0
mmap(0x7f7850919000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f7850919000
mmap(0x7f785091f000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f785091f000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7850b22000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7850b21000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7850b20000
arch_prctl(ARCH_SET_FS, 0x7f7850b21700) = 0
mprotect(0x7f7850919000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7f7850b48000, 4096, PROT_READ) = 0
munmap(0x7f7850b23000, 140688)          = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Po co to wszystko? Przecież to jest pusty program, nawet bez żadnych nagłówków. Czemu tam jest cokolwiek oprócz execve i close?

0

Przed wywołaniem maina uruchamiany jest rzeczywisty entry point aplikacji (od biblioteki standardowej), który przygotowuje środowisko pod aplikację.

4

@kmph popatrz co tam jest wołane i będziesz wiedział ;)
Masz tam głównie przygotowanie pamięci dostępnej dla procesu i ustawienie Data Execution Prevention - pamięć gdzie załaduje się kod programu można wykonywać, ale już pamięci gdzie są alokowane zmienne (stos, sterta) wykonywać nie można, żeby bronić się przed niektórymi exploitami. Masz tam też ładowanie standardowej biblioteki C.
Oprócz tego jak widać jest tam wczytanie nagłówka pliku wykonywalnego.

Moja sugestia: weź tą skompilowaną binarkę i zdekompiluj (np. objdump -d) i zobaczysz ile dodatkowego kodu, poza tym twoim main, się wygenerowało. I pamiętaj że w trakcie samego ładowania tej binarki OS używa loadera który też wykonuje pewne operacje (jak właśnie ustawianie DEP)

1 użytkowników online, w tym zalogowanych: 0, gości: 1