c++ - 如何识别可执行文件是由 C 还是 C++ 编译的?

标签 c++ c compiler-construction exe executable

我的大学教授问我如何识别 .exe 文件是使用 C 还是 C++ 创建的?

有谁知道如何识别吗?

最佳答案

简单的方法:如果你的二进制文件没有被去除符号,它的 C++ 组件将包含损坏的名称,例如?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@.?AVbad_typeid@@_ZNSt8ios_base4InitC1Ev。 C 二进制文件不应包含损坏的符号。另一方面,以 _R 开头的符号强烈建议 Rust name mangling .

如果您没有任何符号,您可以使用导入或字符串来获取提示,但您开始进入猜测领域:

如果二进制文件是来自 MSVC 的 C++ 二进制文件,它将链接到 MSVC++ 运行时或另一个 C++ 运行时(例如 libstdc++)。因此,您将看到嵌入在二进制文件中的文字字符串 "Microsoft Visual C++ Runtime Library",或者您将看到一个名为类似于 msvcp###.dll 的文件导入表中的 (注意名称中的 P)。

如果您使用的是 msys/mingw/cygwin 之类的东西,您仍然会看到与 C++ 运行时库相关的字符串,但确切的措辞会有所不同。即使在从 clang++ 中剥离的二进制文件中,我也观察到 GLIBCXX_3.4 以及一些损坏的名称,但您的结果可能会有所不同。其他提示是 C++ 异常或类的名称,例如basic_stringbad_typeid

如果做不到这一点,您可以查找看起来像损坏名称的字符串(参见第一段);我查看了系统上的一些 C++ 二进制文件,尽管它们的符号表已被删除,但它们仍然有大量损坏的名称显示为字符串。

其他赠品是指向代码部分的指针表,它们可能形成虚拟调度表,或 Windows RTTI 。在 Windows x86 上,预计大量此类函数会从 ECX/RCX 获取指针输入(即 this)。

请注意,这并不是万无一失的;如果愿意的话,我可以创建一个 C++ 二进制文件,然后小心地混淆所有这些提示。一旦您知道如何负责任且有效地使用它,真正的逆向工程工具(例如 Ghidra)就可以帮助您做出这些决定以及更多见解。

关于c++ - 如何识别可执行文件是由 C 还是 C++ 编译的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71367610/

相关文章:

C++:在另一个函数内声明一个函数不是编译器错误所以......它是什么?

C - 创建/写入/读取命名管道

c# - 在 try-finally block 中等待

成员函数的C++条件模板类定义

c++ - 避免在树结构中使用强制转换

c - 如何更改文件权限的格式?

c++ - 在 netbeans 中使用 visual studio c++ 编译器

c++ - 编译器警告和错误是如何定义的,它们是否包含在标准中

c++ - Win32 DLL 导入问题 (DllMain)

c++ - CMake:CMake 构建类型 (DCMAKE_BUILD_TYPE) 有什么作用?