在c ++可执行文件中存储了多少源信息

时间:2012-09-26 22:05:38

标签: c++ c exe

前几天我偶然在Notepad ++中打开了商业应用程序的C ++可执行文件,发现有很多关于存储在可执行文件中的原始源代码的信息。

在可执行文件中,我可以找到文件名(app.c,dlgstat.c,...),函数名称(GetTickCountDispatchMessageA,...)和一小段源代码,主要是条件(szChar != TEXT('\0')iRow < XTGetRows( hwndList ))。之后我检查了另一个QT可执行文件,并且:是源文件名和方法签名。

因此我想知道有多少源代码信息真正存储在C / C ++可执行文件中(例如,使用QT或MinGW编译)。这可能是某种仍包含原始源的调试版本吗?这些信息是用于某些反思的东西吗?出版商有没有理由不删除这些内容?

3 个答案:

答案 0 :(得分:11)

  

在C / C ++可执行文件中确实存储了多少源代码信息?

在实践中,并不多。运行时不需要源代码。你命名的字符串来自两件事:

  • 函数名称(例如GetTickCount)是从其他模块导入的函数的名称。这些名称在运行时是必需的,因为函数是动态解析的(通过使用函数名称调用GetProcAddress)。

  • 条件可能是断言:assert宏将其参数字符串化,以便在它触发时知道哪些条件未得到满足。

如果构建DLL,它还将包含它导出的所有函数的名称,因此可以在运行时解析它们(对于其他共享对象格式也是如此)。

调试符号也可能包含一些原始源代码,但它取决于调试符号使用的格式。这些符号可以包含在二进制文件本身或辅助文件中(例如,Windows上使用的.pdb文件)。

答案 1 :(得分:2)

Windows函数名称:它们可能只是因为它们是动态访问的 - 在程序的某个地方有一个GetProcAddress来获取它们的地址。仍然没有理由担心,每个应用程序都使用WinAPI,所以从这些信息中发现可执行文件并不多。

条件:可能来自某些assert - 像宏;它们被包括在内以允许assert打印失败的条件触发失败的断言。无论如何,在发布模式下,断言应该自动删除。

源文件名和方法签名:可能来自__FILE____func__宏的一些用法;可能,再次来自assert

关于程序内部结构的其他信息来源是RTTI,它必须为typeid可能正在处理的每种类型提供一些表示。如果您不需要它的功能,可以禁用它(但我不知道Qt项目中是否可以这样做。)

答案 2 :(得分:0)

混合到C ++应用程序的二进制文件中,您将找到大多数全局符号的名称(如果在编译器中启用,则调试符号),但使用额外的“装饰文本”来编码符号的调用签名(如果它是功能或方法。同样,字符串的文字嵌入在明文中。但是,您在哪里找不到编译器用于创建二进制可执行文件的实际源代码。在编译过程中丢失了这些信息,如果在构建中使用C ++模板,则特别难以进行逆向工程。