Мой код хорошо работает с malloc
, но не с mmap
. Код ниже:LD_PRELOAD не может перехватывать syscalls, но только libcalls?
main.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int * p = (int*) malloc(sizeof(int));
printf("in main(): value p = %d\n", *p);
free(p);
}
preload.c
#define _GNU_SOURCE
#include <time.h>
#include <dlfcn.h>
#include <stdio.h>
#include <sys/types.h>
void *(*orig_malloc)(size_t size);
void *malloc(size_t size){
printf(" Hooked(preload)! malloc:size:%lu\n", size);
return orig_malloc(size);
}
void * (*orig_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset);
void * mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset){
printf(" Hooked(preload)! mmap:start:%p, length:%lu, prot:%d, flags:%p, fd:%p, offset:%d\n", start, length, prot, flags, fd, offset);
return orig_mmap(start, length, prot, flags, fd, offset);
}
void
_init(void)
{
printf("Loading hack.\n");
orig_malloc = (void* (*)(size_t)) dlsym(RTLD_NEXT, "malloc");
orig_mmap = (void* (*)(void*, size_t, int, int, int, off_t)) dlsym(RTLD_NEXT, "mmap");
}
скомпилировать его
gcc -Wall -fPIC -DPIC -c preload.c
ld -shared -o preload.so preload.o -ldl
gcc main.c
, чтобы запустить его с LD_PRELOAD
LD_PRELOAD=./preload.so ./a.out
запустить его трассированием
strace ./a.out 2>&1 | view -
распечатку из LD_PRELOAD
не перехватывает вызовы mmap
, но только звонки malloc
. Между тем, при работе с strace
, распечатка действительно показывает, что mmap
вызывается несколько раз.
Этот результат меня озадачивает; предполагая, что mmap
действительно вызван main.c
(я догадываюсь через malloc
), почему preload.c
не может перехватить mmap
?
PS: Моя платформа Ubuntu 14.04 с ядром Linux 3,13
PS2: К системному вызову, я имею в виду системный вызова обертку в LIBC (не уверен, если это имеет значение для вопроса, хотя) ..
Я означает, что syscall действительно syscall-оболочка в libc .. в этом смысле, может быть 'LD_PRELOAD' захват syscall wr apper? (Я полагаю, что оболочка syscall вызывается после ld.so) – Richard
@ Richard: Нет, оболочка syscall в libc очень рано связана с PLT-заглушкой. Так рано, что LD_PRELOAD не в состоянии вступить в силу. – datenwolf
@ Richard: см. Эту статью о том, как работает вся PLT/GOT: https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic- libraries.html – datenwolf