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

如何剥离共享对象(Shared Object)中除指定符号外的所有符号?

如何在共享对象中仅保留指定公开符号并隐藏其余符号

有两种可靠的方法可以实现你的需求:只让SoMain()作为公开符号,隐藏其他所有函数名,避免被反汇编工具识别。

方法一:编译时设置默认符号隐藏,显式公开目标符号

通过-fvisibility=hidden编译选项将所有符号默认设为隐藏,再给需要公开的SoMain()添加visibility("default")属性,确保它能被外部识别。

修改后的代码:

#include <fstream>
#include <iostream>

// 这些函数默认会被隐藏,无需额外标记
void PrintMessage(std::string msg)
{
    std::cout << msg << std::endl;
}

void HelloWorld()
{
    std::string s = "HelloWorld!";
    std::cout << s << std::endl;
}

// 显式指定该符号为公开可见,同时保留constructor属性
extern "C" __attribute__((constructor, visibility("default"))) void SoMain() {
    std::ofstream file("HelloWorld");
    file.close();
    HelloWorld();
}

对应的编译命令:

g++ -shared -fPIC -fvisibility=hidden -o test.so test.cpp

方法二:使用链接脚本控制符号导出

如果你不想修改代码,可以通过链接脚本精确指定要导出的符号,其余全部隐藏。

  1. 创建一个名为export.lds的链接脚本文件,内容如下:
{
    global: SoMain;  # 仅公开SoMain符号
    local: *;        # 所有其他符号设为局部(隐藏)
};
  1. 编译时指定该链接脚本:
g++ -shared -fPIC -Wl,--version-script=export.lds -o test.so test.cpp

验证效果

编译完成后,可以用以下命令检查动态符号表,确认只有SoMain可见:

nm -D test.so
# 或者
readelf -s test.so

执行后你会发现,HelloWorld、PrintMessage等函数不会出现在动态符号表中,反汇编工具自然无法识别这些函数名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:13:24