由于名称错误导致输出文件中可见的内容是什么?

时间:2017-01-17 09:17:50

标签: c++ c++11

名称重整后,只有公共函数可见吗?私有和受保护的功能会发生什么?类成员变量,常量,枚举等怎么样?嵌套类?

我知道每个编译器都会有不同的变形,但我想他们会破坏相同的东西?是吗?

编译类后,如何检查输出文件以查看可见的内容?

例如,如果我有以下类,并且它被编译,最终用户何时可以通过检查输出文件来确定(他们不能访问源代码)。

class SomeSwearWord{

private:
     int _anotherSwearWord;
     int getNextSwearWord();
protected:
     std::string _aCurseWord;
     std::string refineMyCurseWord();
public:
    int _aVeryBadWord;
    int getPreviousBadWord();
}

编辑:出于举例的目的,让我们考虑LLVM或gcc ......

编辑:无法访问源代码的客户是否能够仅从可执行文件或目标文件中确定上述诅咒词?

编辑:任何人都可以给出全面的答案吗?实际的平台并不重要,我只想了解什么是可见的。我知道不同的编译器不同,但我只是想在最坏的情况下理解,局外人可以看到多少?

1 个答案:

答案 0 :(得分:3)

可能需要重新定位的所有内容都在输出文件中可见。所以在结果二进制文件中有任何固定位置的东西。

  • 会员不可见。
  • 非虚拟成员功能可见
  • 虚拟成员函数可见
  • 类名可能是可见的,因为它们的构造函数需要在某处调用,或者它们的名称是完整函数名的一部分。
  • 可见静态成员
  • 可以看到静态成员函数。
  • 根本没有列举,结构,工会和班级。
  • C字符串(即"MyString")不作为符号出现,而是作为只读数据出现。

因此,在您的示例中,没有成员可见,但所有函数都将是 - 如果它们被调用。

存在虚函数名,因为你的vtable是一个包含所有虚函数重定位的数组。

您可以通过在链接时使用包含您想要的输出的确切列表的定义文件来抑制它们在输出文件中的存在。在Windows上,这是共享库的默认设置(即隐藏所有内容),但在Linux / Mac上,默认情况下是使它们可见并且可以覆盖。

当谈到"名称错误"时,我们实际上在讨论如何将函数实例化,模板内容,参数等转换为一个唯一的字符串。提到的名称本身是逐字和未解的。

例如,您的示例将生成以下符号(GCC):

_ZN13SomeSwearWord16getNextSwearWordEv
_ZN13SomeSwearWord17refineMySwearWordEv
_ZN13SomeSwearWord18getPreviousBadWordEv

请注意,返回类型不存在。您可以使用objdump -t <myBinary>

从目标文件或可执行文件中获取此信息