glibc 升级后在静态链接应用程序中使用 --wrap 选项覆盖 glibc malloc 的问题

问题描述 投票:0回答:1

升级到最新的 glibc 后,我注意到 malloc_hooks 已被弃用,因此我尝试使用 --wrap 符号用用户定义的函数覆盖某些 glibc 函数。例如,我使用 --wrap=malloc 来使用自定义的wrapp_malloc 覆盖 glibc malloc 函数。

我的代码中对 malloc 的直接调用被正确重定向到wrap_malloc。然而,当调用像 fopen() 这样的 glibc 函数时,它会在内部调用 malloc,内部 malloc 调用不会被我的 wrap_malloc 覆盖。

有人对如何解决此问题并确保内部 malloc 调用(例如,来自 fopen() 的调用)被我的自定义函数覆盖有建议吗?任何见解将不胜感激!

我尝试使用 LD_PRELOAD 选项,但它似乎不起作用,因为我的应用程序是静态构建的

hook wrapper glibc
1个回答
0
投票

对于完全静态链接,您最好的(可能也是唯一的)选择是用替代实现替换整个

libc.a(malloc.o)

请注意,您必须替换

malloc.o
中的所有符号,否则您的链接将因多重定义的符号而失败。

例如,在 Fedora 40 上,以下“有效”:

#include <stdio.h>
#include <string.h>

static char buf[10000] __attribute__((aligned(16)));
static char *mptr = &buf[0];

void *malloc(size_t sz)
{
  char *r = mptr;
  mptr += (sz + 0xF) & ~0xF;
  fprintf(stderr, "malloc(%zu) -> %p\n", sz, r);
  return r;
}

void free(void *p)
{
  fprintf(stderr, "free(%p)\n", p);
}

void *calloc(size_t nelem, size_t sz)
{
  void *r = malloc(nelem * sz);
  fprintf(stderr, "calloc(%zu, %zu) -> %p\n", nelem, sz, r);
  return r;
}

void *realloc(void *p, size_t sz)
{
  char *r = malloc(sz);
  memcpy(r, p, sz);
  fprintf(stderr, "realloc(%p, %zu) -> %p\n", p, sz, r);
  return r;
}

int main(int argc, char *argv[])
{
  if (argc < 2) return 0;
  fprintf(stderr, "  fopen(%s)\n", argv[1]);
  FILE *fp = fopen(argv[1], "w");
  fprintf(stderr, "  fopen(%s) -> %p\n", argv[1], fp);

  if (fp == NULL) return 1;


  fprintf(stderr, "  fclose(%p)\n", fp);
  fclose(fp);

  fprintf(stderr, "  main returns\n");
  return 0;
}
gcc -Wall -Wextra -static t.c && ./a.out foo.txt
malloc(6) -> 0x49d1b0
malloc(1241) -> 0x49d1c0
calloc(1241, 1) -> 0x49d1c0
malloc(24) -> 0x49d6a0
malloc(160) -> 0x49d6c0
malloc(160) -> 0x49d760
malloc(256) -> 0x49d800
malloc(256) -> 0x49d900
  fopen(foo.txt)
malloc(472) -> 0x49da00
  fopen(foo.txt) -> 0x49da00
  fclose(0x49da00)
free(0x49da00)
  main returns
free(0x49d900)
free(0x49d800)

在上面您可以清楚地看到

malloc
被从
fopen
调用,而
free
被从
fclose
调用。

© www.soinside.com 2019 - 2024. All rights reserved.