visual-studio-2010 - 从 DLL 中去除特定符号

标签 visual-studio-2010 dll symbols strip portable-executable

我使用 MSVC 2010 创建了一个 Win32-DLL,其中包含不需要的导出 C++ 符号。我正在使用模块定义文件( .def )和 __stdcall我想要导出的特定函数的约定。然而,由于我也在使用 Boost Serialization,因此存在大量从 Boost 导出的 C++ 符号。由于这一事实,这些符号由 Boost 导出(发现 here ):

I am using boost::serialization from 1.44.0. One thing that I noticed is that linking statically to the serialization libs will add several hundred exports in the final exe file that I get. Using dumpbin /exports my_program.exe

这些函数不是从库中显式调用的。但他们 被称为序列化过程的一部分。只是MSVC 没有看到他们。因此,当您编译发布时,MSVC 链接器 删除它们,程序将不再工作。为了工作 围绕这一点,这些函数被显式导出。这可以防止 MSVC 不会将它们剥离。欲了解更多信息,请参阅 force_include.hpp

导出的符号(摘录):

class boost::archive::detail::extra_detail::map<class boost::archive::binary_oarchive> & >boost::serialization::singleton<class boost::archive::detail::extra_detail::map<class boost::archive::binary_oarchive> >::get_instance(void)'::`2'::`local static guard'{2}'

您可以通过创建 DLL 项目并包含 Boost 来重现这种情况(链接 libboost_serialization-vc100-mt-gd-1_55.lib ):

#include <boost/archive/binary_oarchive.hpp>
#include <fstream>

extern "C" int __stdcall test();

int __stdcall test() {
    std::fstream stream;
    boost::archive::binary_oarchive o(stream, boost::archive::no_header);
    return 1;
}

我测试了 GNU 实用程序 strip from binutils 。然而,它似乎总是删除所有符号。例如。使用此命令

strip --strip-symbol=test DllBoostTest.dll -o test.dll

这个简单的测试不起作用。它应该只删除测试符号。不幸的是,它也删除了所有符号。还使用通配符和 -N不起作用,因为它也会删除所有导出。

有没有办法删除所有不需要的 boost C++ 符号?比如说,删除所有带有“boost”文本的符号?

如果您需要更多信息,我很乐意提供。

<小时/>

注意:这与调试或 PDB 文件无关!

最佳答案

这很难以干净的方式修复。真正的解决办法是消除 boost hack 的影响,强制包含这些符号。这需要删除 __declspec(dllexport) 属性,并使用/OPT:NOREF 链接器选项来抑制优化或使用/INCLUDE(或 #pragma 注释)来确保包含符号。然而,这需要重建 boost 库,并且由于损坏名称的不可预测性,维护起来很麻烦。所以你可能不喜欢这个选项,Boost 团队显然也不喜欢。

我认为尝试破解strip不会给你带来任何好处,重要的是链接器仍然可以看到这些符号,这样它就不会优化它们。您只能在构建 DLL 之后执行此操作,这需要重写文件中的导出表。这在技术上是可行的,但不容易做到。

一种可能性是防止这些名称可见。 DEF 文件为您提供了该选项,您可以使用 NONAME 属性来防止名称可见,并使用 PRIVATE 属性来防止名称在导入库中可见。让它看起来像这样:

EXPORTS

??_B?1??get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ@51 @1 NONAME PRIVATE
??_B?1??get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ@51 @2 NONAME PRIVATE
?get_const_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SAABV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @3 NONAME PRIVATE
?get_const_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SAABV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @4 NONAME PRIVATE
?get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @5 NONAME PRIVATE
?get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @6 NONAME PRIVATE
?get_mutable_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @7 NONAME PRIVATE
?get_mutable_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @8 NONAME PRIVATE
?instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@0AAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@A @9 NONAME PRIVATE
?instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@0AAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@A @10 NONAME PRIVATE
?is_destroyed@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SA_NXZ @11 NONAME PRIVATE
?is_destroyed@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SA_NXZ @12 NONAME PRIVATE
?t@?1??get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@4@XZ@4V?$singleton_wrapper@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@734@A @13 NONAME PRIVATE
?t@?1??get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ@4V?$singleton_wrapper@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@detail@34@A @14 NONAME PRIVATE
 _test@0 = _test@0

您将收到 LNK4197 警告,因为链接器看到两个导出请求,一个来自 __declspec(dllexport),另一个来自 DEF 文件。这些警告是良性的,您可以忽略它们。请注意,您可能需要调整这些名称,我使用 VS2012 和 Boost 版本 1.53 对此进行了测试

删除 PDB 文件后(不要忘记),导出如下所示:

ordinal hint RVA      name

     15    0 0001582F _test@0
      1      0004DE94 [NONAME]
      2      0004DEB8 [NONAME]
      3      0001524E [NONAME]
      4      000153A2 [NONAME]
      5      00015AA5 [NONAME]
      6      00015460 [NONAME]
      7      000154E7 [NONAME]
      8      00016199 [NONAME]
      9      0004DE7C [NONAME]
     10      0004DEA0 [NONAME]
     11      00015AFF [NONAME]
     12      00015B9F [NONAME]
     13      0004DE84 [NONAME]
     14      0004DEA8 [NONAME]

关于visual-studio-2010 - 从 DLL 中去除特定符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21027374/

相关文章:

visual-studio-2010 - 什么是第一次机会异常(exception)?

python - 我试图用 python ctypes 打开一个用 c 编写的 dll 并运行其中的函数,但它是一个字符,而不是字符串

c# - 在 TFS 构建定义中包含 Sharepoint WSP

asp.net - 如何在报告查看器中定义主体尺寸? ( Visual Studio 2010)

debugging - vsjitdebugger.exe 建议一个新实例,忽略已经运行的实例 - 怎么办?

c++ - Cmake、.lib、dll 并避免在二进制文件中复制多个 .lib

c# - 错误模块名称 : KERNELBASE. dll

python - SymPy - 将数字视为符号

development-environment - 如何在 Sublime Text 编辑器中获取大纲 View ?

r - R中的意外符号请参阅代码