// you’re reading...

Featured

Перехватываем malloc функции из glibc

Библиотека glibc позволяет легко и просто перехватывать функции аллокации памяти, такие как malloc(), realloc(), free(). Помимо этого, можно вставить свой собственный код в самое начало выполнения программы, например, для инициализации чего-либо. Я разберу как это делается на примере реализации QMP2.

Все, что нам потребуется — это зарегистрировать функцию инициализации для наших перехватчиков и сохранить старые перехватчики. Остальное — это правильно обрабатывать вызовы malloc/realloc/free в наших функциях-перехватчиках.

Необходимо, чтобы инициализация была произведена в самом начале выполнения программы, перед первым запуском malloc/realloc/free. Для этого инициализируем переменную __malloc_initialize_hook своей функцией qmp_init():

static void qmp_init()
{
    qmp_elf_init();
    qmp_ptr2trace_init();
    qmp_trace_map_init();
    atexit(qmp_print_result);
 
    old_malloc_hook = __malloc_hook;
    old_free_hook   = __free_hook;
 
    qmp_hook();
}
 
// Initialize point
void (*__malloc_initialize_hook) () = qmp_init;

Эта переменная — ссылка на функцию инициализации. В этой функции мы заодно инициализируем массу всего дополнительного, что нам понадибится позднее. Заодно мы сохраняем чужие перехватчики. Функция qmp_hook(), устанавливает наши функции-перехватчики для malloc() и free():

static void qmp_hook()
{
    __malloc_hook = qmp_malloc_hook;
    __free_hook   = qmp_free_hook;
}

Теперь, когда вызывается функция malloc(), то вместо нее срабатывает наш перехватчик qmp_malloc_hook():

static void *qmp_malloc_hook(size_t size, const void *caller)
{
    void *p;
 
    qmp_unhook();
    p = malloc(size);
    qmp_hook();
 
    return p;
}

Чтобы правильно отработала системная функция нам надо вернуть перехваченные функции обратно, с помощью qmp_unhook():

static void qmp_unhook()
{
    __malloc_hook = old_malloc_hook;
    __free_hook   = old_free_hook;
}

Далее вызвать системную функцию malloc(), где заодно отработают чужие перехватчики, и снова перехватить функции аллокации с помощью qmp_hook().

Вот нормальный цельный кусок кода:

static void qmp_hook()
{
    __malloc_hook = qmp_malloc_hook;
    __free_hook   = qmp_free_hook;
}
 
static void qmp_unhook()
{
    __malloc_hook = old_malloc_hook;
    __free_hook   = old_free_hook;
}
 
static void *qmp_malloc_hook(size_t size, const void *caller)
{
    void *p;
 
    qmp_unhook();
 
    // some pre code...
    p = malloc(size);
    // some post code...
 
    qmp_hook();
 
    return p;
}
 
static void qmp_init()
{
    // some initializations...
 
    old_malloc_hook = __malloc_hook;
    old_free_hook   = __free_hook;
 
    qmp_hook();
}
 
// Initialize point
void (*__malloc_initialize_hook) () = qmp_init;

Полная документация по glibc ТУТ. Описание как перехватить malloc функции ЗДЕСЬ.


Discussion

Ads

Похожие статьи