budynek a.so jest to również plik wykonywalny

Więc prawdopodobnie każdy wie, że /lib/libc.so.6 glibc może być uruchamiany w powłoce jak normalny program wykonywalny, w którym to przypadku wypisuje informacje o swojej wersji i kończy działanie. Odbywa się to poprzez zdefiniowanie punktu wejścia w .so. w niektórych przypadkach może być interesujące użycie tego dla innych projektów. Niestety, niskopoziomowy punkt wejścia, który można ustawić za pomocą opcji-e ld, jest nieco za niski: dynamiczny loader nie jest dostępny, więc nie można wywołać żadnych właściwych funkcji bibliotecznych. glibc z tego powodu implementuje wywołanie systemowe write () poprzez nagie wywołanie systemowe w tym punkcie wejścia.

Moje pytanie brzmi teraz, czy ktoś może wymyślić miły sposób, jak można uruchomić pełny dynamiczny linker z tego punktu wejścia, aby można było uzyskać dostęp do funkcji z innych. so ' S?

Author: Martin v. Löwis, 2009-09-20

3 answers

Budowanie biblioteki współdzielonej za pomocą opcji -pie daje Ci wszystko, czego chcesz:

/* pie.c */
#include <stdio.h>
int foo()
{
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return 42; 
}
int main() 
{ 
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return foo(); 
}


/* main.c */
#include <stdio.h>

extern int foo(void);
int main() 
{ 
  printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
  return foo(); 
}


$ gcc -fPIC -pie -o pie.so pie.c -Wl,-E
$ gcc main.c ./pie.so


$ ./pie.so
in main pie.c:9
in foo pie.c:4
$ ./a.out
in main main.c:6
in foo pie.c:4
$

P. S. glibc implementuje write(3) poprzez wywołanie systemowe, ponieważ nie ma innego miejsca do wywołania (jest to już najniższy poziom). Nie ma to nic wspólnego z możliwością wykonania libc.so.6.

 44
Author: Employed Russian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-20 17:13:56

Nie jest to dobry sposób, ale stworzyłbym malutki plik wykonywalny wrapper wokół .so, który wywołuje funkcję punktu wejścia, którą chcę uruchomić.

 1
Author: Yawar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-20 01:13:37

Przypuszczam, że masz swój ld -e punkt wejścia, który następnie użyje rodziny funkcji dlopen(), aby znaleźć i uruchomić resztę linkera dynamicznego. Oczywiście musiałbyś upewnić się, że dlopen() jest albo statycznie połączone, albo być może będziesz musiał zaimplementować wystarczająco dużo własnego łącznika, aby się do niego dostać (używając interfejsów wywołania systemowego, takich jak mmap(), tak jak robi to sama libc.

Dla mnie to nie brzmi "miło". W rzeczywistości tylko myśl o odczytaniu źródeł glibc (i kod źródłowy ld-linux, jako jeden przykład) wystarczający do oceny wielkości zadania brzmi dla mnie dość chrypliwie. Może to być również koszmar przenośności. Mogą występować duże różnice między sposobem implementacji Linuksa ld-linux A sposobem linkowania pod OpenSolaris, FreeBSD i tak dalej. (Nie wiem).
 0
Author: Jim Dennis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-20 03:26:38