ZBLOG

typedef void* (*original_malloc_t)(size_t size); original_malloc_t original_malloc = NULL; original_malloc = (original_malloc_t)dlsym(RTLD_NEXT, "malloc"); 这样写会不会钩子函数的参数和dlsym函数的参数不匹配

你的代码片段是用来通过 dlsym 获取系统 malloc 函数的地址,并将其赋值给一个函数指针 original_malloc。这里的关键点在于类型匹配和调用约定是否正确。

1. 参数匹配分析

  • dlsym 的返回类型
    dlsym 的原型是 void* dlsym(void* handle, const char* symbol),它返回一个 void* 类型的函数地址。
    你需要将这个地址强制转换为目标函数的指针类型(即 original_malloc_t)。

  • 函数指针类型定义
    你的 original_malloc_t 是正确的:

    typedef void* (*original_malloc_t)(size_t size);
    

    它明确声明了一个函数指针类型,该函数接受 size_t 参数并返回 void*

  • 强制转换的合理性
    你通过强制转换将 dlsym 返回的通用指针 (void*) 转为特定函数指针 (original_malloc_t):

    original_malloc = (original_malloc_t)dlsym(RTLD_NEXT, "malloc");
    

    这种转换是安全的,前提是:

    1. 被钩取的函数原型必须与定义的函数指针完全一致(包括参数和返回值)。
      • C库的 malloc 确实是 void* malloc(size_t size),所以匹配。
    2. 编译器和平台支持从数据指针到函数指针的转换
      • POSIX(如Linux)允许这种操作,但某些严格平台(如嵌入式系统)可能不允许。

2. 潜在问题

  • 未检查返回值
    如果 dlsym 失败(例如符号未找到),它会返回 NULL,直接调用 original_malloc 会导致段错误。建议添加错误处理:
original_malloc = (original_malloc_t)dlsym(RTLD_NEXT, "malloc");
if (!original_malloc) {
    fprintf(stderr, "Error: Failed to find malloc\n");
    abort();
}
  • 线程安全性
    在多线程环境中,需确保对全局变量 original_malloc 的初始化只执行一次(例如用 pthread_once)。

###3. 其他注意事项

  • 调用约定一致性
    在大多数现代系统上(如Linux/x86_64),默认调用约定已统一为兼容模式,通常无需额外声明。但在特殊场景(如Windows的跨语言调用)可能需要显式指定调用约定(如 __attribute__((stdcall)))。
  • 动态链接库的作用域
      RTLD_NEXT 会查找后续动态库中的符号,确保它在当前库之后加载。如果钩子逻辑位于主程序中而非动态库中,可能需要调整作用域。

###4. 完整示例代码

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

typedef void* (*original_malloc_t)(size_t size);
static original_malloc_t original_malloc = NULL;

void init_hook() {
    original_malloc = (original_malloc_t)dlsym(RTLD_NEXT, "malloc");
    if (!original_malloc) {
        fprintf(stderr, "Error: dlsym failed for malloc\n");
        abort();
    }
}

// Hooked malloc
void* malloc(size_t size) {
    if (!original_mallloc) init_hook(); // Lazy initialization
    printf("Hook: malloc(%zu)\n", size);
    return original_mallloc(size);
}

###总结 你的写法本身没有问题,只要目标函数的原型与定义的函数指针一致即可。但需注意错误处理和线程安全等工程细节。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24099

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?