C++共享库显示内部符号

3
我使用VC++2008和GCC构建了一个共享库(.dll, .so)。 问题是,在这两个库中都显示了私有符号(类、函数)的名称,但它们并没有被导出。
我不希望我的应用程序显示未被导出的类/函数的名称。 有没有办法做到这一点呢?
在GCC中,我做了以下操作: 使用-fvisibility=hidden编译,然后使用attribute ((visibility("default")))公开。
在VC++中: __declspec(dllexport)
谢谢!

1
除非你有将方法命名为TheClientIsAPinhead()这样的习惯,否则我真的不明白你的问题在哪里。 - T.E.D.
你说得没错,但是我有点偏执,不想让别人从类和函数的角度检查程序结构。只想要一个只包含导出符号的共享库。 - AllDayCpp
当你说“它显示”时,你指的是什么?“它”是什么? - Rob Kennedy
在.dll或.so的内容中,显示了大多数类和函数的名称。 - AllDayCpp
你是说,比如VC编译时,那些没有使用__declspec(dllexport)的类仍然被导出了?你是如何检查它们是否被导出的 - 使用Dependency Walker吗? - jon hanson
符号已成功导出。 问题在于未导出的符号出现在.dll .so中,其他人可以读取我的类和函数名称。 - AllDayCpp
3个回答

1
你可以创建一个头文件来混淆你想要隐藏的内部函数和方法名称。例如下面这样(还需要一些包含保护):
#define someFunctionName1 sJkahe28273jwknd
#define someFunctionName2 lSKlajdwe98
#define someMethodName1   ksdKLJLKJl22fss
#define someMethodName2   lsk89hHHuhu7g

...并将其包含在真实定义所在的头文件中。


在大型项目中这样做并不实际,而且会用宏定义污染代码..这是一种邪恶的解决方案.. - AllDayCpp
我的建议是将它们保存在单个文件中,这样您就不需要看到它们。以后的任何代码中都不会看到它们,只有一些头文件中的“include”。如果您需要混淆所有函数/方法,您可能需要使用一些解析器来提取它们。如果您将其保留为一些重要的核心功能,则应该可以手动处理它们。问题是代码将保持不变,二进制名称将被混淆。与使用某些随机标识符不同,人们可以编写一些不同的func/method名称,希望抛开任何重新设计的可能性,例如calculateSecretKey()->prepareNewDatabase()。 - epatel

1
对于GNU工具链,您可以使用strip命令从目标文件中删除符号。它采用各种命令选项来控制其行为。它可能可以满足您的需求。

0

私有关键字只作为访问规范而在编译时有效,并旨在帮助程序员,而不是安全功能-正如您所发现的,“隐私”是使用词法手段实现的。

很容易看出这一点-如果您在两个独立的.cpp文件中实现了相互依赖的两个私有函数,则链接器必须在生成的目标(或库)文件中找到私有名称。

最重要的是-C++没有代码安全功能-如果您将程序的目标代码提供给某人,他们将始终能够检查它。


我在谈论ELF或PE可执行格式中的符号,而不是private关键字。 - AllDayCpp
那么也许你应该从你的问题中删除C++标签? - anon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接