– Conhecendo e utilizando a LD_PRELOAD - .:: Jorge Pereira ::.
– Conhecendo e utilizando a LD_PRELOAD
June 11, 2010 at 3:55 AM jpereira 5 comments
Muitas pessoas utilizam, utilizaram ou vão utilizar a variável LD_PRELOAD, e por sua vez nem sempre sabem para que ela serve! Caso este seja o seu problema, problema este não mais será!! 😛
O que acontece basicamente e que o linker dinâmico do Linux (assim como em tantos outros sistemas operacionais) utiliza diversas formas, alguma delas sendo através de variáveis de ambiente para controlar seu comportamento. Sendo que neste caso a variável LD_PRELOAD informa ao linker dinâmico que carregue as bibliotecas listadas nela antes de carregar quaisquer outras bibliotecas necessárias, enquando LD_LIBRARY_PATH especifica um caminho alternativo para usar ao procurar bibliotecas que serão carregadas.
Partindo deste principio podemos fazer com que um programa a ser executado seja "hijacked" por outro programa, ou seja. Podemos fazer por exemplo que a função hehe() previamente chamada pelo programa "A" tenha seu comportamento alterado sem precisar fazer quaisquer alteração no programa "A". Um pouco complexo? talvez! Mais vamos por a mão na massa! hands on!
Digamos que você tem o programa "main" conforme o código de exemplo abaixo, perceba que o código e super simples. apenas declaro um ponteiro de caracteres, aloco memória e em seguida copio uma sequência de caracteres para o ponteiro previamente alocado. Simples, certo?
1) Abaixo código de exemplo de nosso "main.c" ou clique aqui para download.
*  Filename: hijack_main.c
*  Created: Wed Jun  9 22:11:12 BRT 2010
*  Author: Jorge Pereira <jpereiran@gmail.com>
char* nome = (char*)malloc (100);
strcpy (nome, "Jorge Pereira");
printf ("NOME: %s\n", nome);
# Vamos compilar e executar o nosso exemplo "main.c"
$ gcc -Wall -o main main.c
NOME: Jorge Pereira
Até aqui tudo bem, porém imagine você em uma determinada situação em que precisa saber quantos bytes está sendo alocado por um determinado programa? e você por alguns instantes imagina sobre a possibilidade de poder fazer algum tipo de "overload" de uma determinada função na qual você conhece sua assinatura. (Digamos, você sabe a assinatura do método, quantidade e tipos dos parâmetros, …).
Pois bem, neste exemplo que irei demonstrar será para sobrecarregar todas as chamadas feitas pelo meu programa "main" às funções malloc() e free() e em seguida exibir uma mensagem no caso do malloc() imprimindo seu parâmetro que e o tamanho de bytes alocados, e na função free() exibindo os ponteiros que foram liberados.
Neste caso, iremos criar uma biblioteca chamada "libhijack_hehe.so" que será carregada através da variável mágica LD_PRELOAD em parceria com nosso querido linker dinâmico.
2) Abaixo código de exemplo de "hijack_hehe.c", ou clique aqui para download.
*  Filename: hijack_hehe.c
#define HIJACK_DEBUG(fmt, ...) \
fprintf(stderr, " ** DEBUG: %s:%d %s(): "fmt"\n", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
static void* (*hack_malloc)(size_t size) = NULL;
static void  (*hack_free)(void *p) = NULL;
static void* rest_malloc = NULL;
if (hack_malloc == NULL)
hack_malloc = (void *(*)(size_t)) dlsym (RTLD_NEXT, "malloc");
rest_malloc = NULL;
if (rest_malloc == NULL)
rest_malloc = hack_malloc (size);
HIJACK_DEBUG ("Alocando (%d) bytes, chunck(%p)", size, (void*)rest_malloc);
return rest_malloc;
hack_malloc = NULL;
free (void *p)
HIJACK_DEBUG ("Desalocando (%p)", p);
if (hack_free == NULL)
hack_free = (void (*)(void *)) dlsym(RTLD_NEXT, "free");
hack_free (p);
Agora vamos compilar, executar e analisar o comportamento.
$ gcc -Wall -shared -ldl -o libhijack_hehe.so hijack_hehe.c
$ LD_PRELOAD=./libhijack_hehe.so ./main
** DEBUG: hijack_hehe.c:35 malloc(): Alocando (100) bytes, chunck(0x9273008)
** DEBUG: hijack_hehe.c:46 free(): Desalocando (0x9273008)
Percebeu algo diferente na execução com a LD_PRELOAD passando como parâmetro a nossa libhijack_hehe.so? pois bem, todas as chamadas às funções malloc() e free() foram sobrecarregadas e passaram a se comportar conforme as versões que escrevi em hijack_hehe.c. Caso tenha ficado curioso, e so re-escrever tais exemplos com outras funções que você deseja sobrecarregar e ver o comportamento. Lembrando que basta utilizar a criatividade e perceberá na quantidade de coisas que podem ser feita com tal técnica.
Exemplo: Nas funções que fazem checagem com strcmp(), uso da crypt(), … entre outras.
man 8 ld.so
Data: Wed Jun 9 23:42:26 BRT 2010
C/C++, Debug, Hacking, Outros ld_preload linux hacking
#1 | Written by Jonh Wendell about 12 years ago. Reply
Massa a dica! Bom ter vc de volta!
Valeu cara!! =)
#3 | Written by JohnTortugo about 11 years ago. Reply
Kra, eu não conhecia este recurso, achei muito interessante!
Vou tomar a liberdade de adicionar um link para o seu post no meu blog!
#4 | Written by Thiago Figueredo Cardoso about 11 years ago. Reply
Grande Jorge! Bicho, esse link foi o segundo no Google pra LD_PRELOAD! Super mão na roda pra resolver minhas broncas no trampo hoje. Valeu!
#5 | Written by Alex Smith about 10 years ago. Reply
#1 | Pinged by Conhecendo e utilizando a LD_PRELOAD « John Tortugo about 11 years ago.
[…] [1] http://blog.jorgepereira.com.br/2010/06/11/conhecendo-e-utilizando-a-ld_preload/ Tags:linux, Programação, Programming Comments RSS feed LikeBe the first to like this post. […]