C dl * как поменять указатель функции на другой указатель функции - PullRequest
0 голосов
/ 29 мая 2018

Как мне безопасно поменять функцию для другой функции в C, поскольку у меня есть это

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

void *(*malloc_mem_real)(size_t);
void *(*calloc_mem_real)(void*,size_t);
void *(*realloc_mem_real)(void*,size_t);
void (*free_mem_real)(void*);

void memory__init(void) {
    if (!malloc_mem_real) malloc_mem_real = dlsym(RTLD_NEXT, "malloc");
    if (!calloc_mem_real) calloc_mem_real = dlsym(RTLD_NEXT, "calloc");
    if (!realloc_mem_real) realloc_mem_real = dlsym(RTLD_NEXT, "realloc");
    if (!free_mem_real) free_mem_real = dlsym(RTLD_NEXT, "free");
}

/*
const char *getObjectName (object *anObject) {
    static char * (*func)();

    if(!func)
        func =  dlsym(RTLD_NEXT, "getObjectName");
    printf("Overridden!\n");     
    return(func(anObject));    // call original function
}
*/

void* _malloc(size_t sz);

int bit, saved;

void swap_malloc() {
    if (bit == 0) {
        void *(* malloc)() = &_malloc;
        bit = 1;
        write(1, "1\n", 2);
    }
    else if (bit == 1) {
        void *(* malloc)() = &malloc_mem_real;
        bit = 0;
        write(1, "0\n", 2);
    }
}


void* _malloc(size_t sz) {
    swap_malloc(); // should swap void* _malloc(size_t sz) for void* malloc(size_t __size), bit = 0
    return malloc(sz*2); // returns libc malloc(sz*2);
}

void* malloc(size_t sz) {
    if (saved == 0) {
        memory__init(); // save real malloc address
        saved = 1;
    }
    swap_malloc(); // should swap void* malloc(size_t sz) for void* _malloc(size_t sz), bit = 1
    return malloc(sz); // returns _malloc(sz);
}

int main() {
    char * h;
    h = malloc(50); // should allocate 100 instead
    printf("%p\n", h);
    free(h);
    return 0;
}

, которое предназначено для замены файлов malloc на libc malloc, но swap_malloc продолжает вызываться рекурсивно, что приводит к записи:переполнение стека

Основная идея заключается в следующем:

вызывает оболочку malloc

для установки оболочки malloc в libc malloc

Делать функции, которые требуют, например, libc mallocprintf

переключить libc malloc обратно в оболочку malloc

...