You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hook库构造函数调用dlsym出现段错误,添加特定代码后异常消失的原因排查

动态库Hook初始化段错误排查

我编写了一个hook.so用于挂钩目标程序的read、write等系统调用,使用GNU的__attribute__((constructor))标记初始化函数get_origin_function,让它在hook.so加载时自动执行,代码如下:

void get_origin_function() {

  GLIBC_OPEN = (open_ptr)dlsym(RTLD_NEXT, "open");
  GLIBC_OPENAT = (openat_ptr)dlsym(RTLD_NEXT, "openat");
  LIBC_FOPEN = (fopen_ptr)dlsym(RTLD_NEXT, "fopen");
  LIBC_FOPEN64 = (fopen64_ptr)dlsym(RTLD_NEXT, "fopen64");
  GLIBC_READ = (read_ptr)dlsym(RTLD_NEXT, "read");
  LIBC_FREAD = (fread_ptr)dlsym(RTLD_NEXT, "fread");
  GLIBC_CLOSE = (close_ptr)dlsym(RTLD_NEXT, "close");
  LIBC_FCLOSE = (fclose_ptr)dlsym(RTLD_NEXT, "fclose");
  LIBC_FPRINTF = (fprintf_ptr)dlsym(RTLD_NEXT, "fprintf");
  LIBC_PRINTF = (printf_ptr)dlsym(RTLD_NEXT, "printf");
  GLIBC_WRITE = (write_ptr)dlsym(RTLD_NEXT, "write");

}

使用LD_PRELOAD=./hook.so my_program测试时出现段错误,推测是空指针引用。但奇怪的是,在函数末尾添加usleep(1)或打印函数指针的printf("%p %p %p...",GLIBC_OPEN)后,段错误消失,代码如下:

void get_origin_function() {

  GLIBC_OPEN = (open_ptr)dlsym(RTLD_NEXT, "open");
  GLIBC_OPENAT = (openat_ptr)dlsym(RTLD_NEXT, "openat");
  LIBC_FOPEN = (fopen_ptr)dlsym(RTLD_NEXT, "fopen");
  LIBC_FOPEN64 = (fopen64_ptr)dlsym(RTLD_NEXT, "fopen64");
  GLIBC_READ = (read_ptr)dlsym(RTLD_NEXT, "read");
  LIBC_FREAD = (fread_ptr)dlsym(RTLD_NEXT, "fread");
  GLIBC_CLOSE = (close_ptr)dlsym(RTLD_NEXT, "close");
  LIBC_FCLOSE = (fclose_ptr)dlsym(RTLD_NEXT, "fclose");
  LIBC_FPRINTF = (fprintf_ptr)dlsym(RTLD_NEXT, "fprintf");
  LIBC_PRINTF = (printf_ptr)dlsym(RTLD_NEXT, "printf");
  GLIBC_WRITE = (write_ptr)dlsym(RTLD_NEXT, "write");
  usleep(1); // or printf()

}

如果在函数开头添加printf(),仍会出现段错误,代码如下:

void get_origin_function() {
  printf();
  GLIBC_OPEN = (open_ptr)dlsym(RTLD_NEXT, "open");
  GLIBC_OPENAT = (openat_ptr)dlsym(RTLD_NEXT, "openat");
  LIBC_FOPEN = (fopen_ptr)dlsym(RTLD_NEXT, "fopen");
  LIBC_FOPEN64 = (fopen64_ptr)dlsym(RTLD_NEXT, "fopen64");
  GLIBC_READ = (read_ptr)dlsym(RTLD_NEXT, "read");
  LIBC_FREAD = (fread_ptr)dlsym(RTLD_NEXT, "fread");
  GLIBC_CLOSE = (close_ptr)dlsym(RTLD_NEXT, "close");
  LIBC_FCLOSE = (fclose_ptr)dlsym(RTLD_NEXT, "fclose");
  LIBC_FPRINTF = (fprintf_ptr)dlsym(RTLD_NEXT, "fprintf");
  LIBC_PRINTF = (printf_ptr)dlsym(RTLD_NEXT, "printf");
  GLIBC_WRITE = (write_ptr)dlsym(RTLD_NEXT, "write");

}

最初怀疑是glibc等动态库未加载,尝试在函数开头调用dlopen也未解决问题,恳请排查该异常的原因。

内容的提问来源于stack exchange,提问作者wenju sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:10:03