首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从DLL中剥离特定符号

从DLL中剥离特定符号
EN

Stack Overflow用户
提问于 2014-01-09 17:42:03
回答 2查看 2.7K关注 0票数 3

我已经使用MSVC 2010创建了一个包含不必要的导出C++符号的Win32 32-DLL.对于要导出的特定函数,我使用模块定义文件(.def)和__stdcall约定。但是,由于我也在使用Boost序列化,有大量来自Boost的导出C++符号。由于这一事实,这些符号是通过Boost导出的(发现这里):

我使用的是从1.44.0开始的boost::序列化。我注意到的一件事是,静态链接到序列化库将在我得到的最终exe文件中添加数百个导出。使用dumpbin /exports my_program.exe,这些函数不是从库中调用的。但是它们作为序列化过程的一部分被调用。只是MSVC没有看到他们。因此,当您为发布而编译时,MSVC链接器会将它们删除,程序将不再工作。为了解决这个问题,这些函数被显式导出。这样可以防止MSVC将其剥离。有关更多信息,请参见force_include.hpp

出口符号(摘录):

代码语言:javascript
复制
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)来重新创建这种情况:

代码语言:javascript
复制
#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实用程序binutils。然而,它似乎总是删除所有的符号。例如使用此命令

代码语言:javascript
复制
strip --strip-symbol=test DllBoostTest.dll -o test.dll

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

那么有什么方法可以删除所有不必要的boost C++符号吗?比如说,删除所有带有“助推”文字的符号?

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

注意:,这不是关于调试或PDB文件!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-17 14:50:41

这件事很难用干净的方式解决。一个真正的解决办法是去掉刺激攻击,强制将这些符号包括在内。这需要删除__declspec(dllexport)属性,或者使用/OPT:NOREF链接器选项来抑制优化,或者使用/INCLUDE (或#/INCLUDE注释)来确保符号被包括在内。但是,这需要重新构建boost库,并且由于损坏名称的不可预见性,需要进行令人生厌的维护。所以你可能不喜欢这样的选择,而助推队显然不喜欢。

我不认为试图黑条会让你去任何地方,这是重要的是,链接器仍然看到符号,所以它不会优化他们离开。只有在生成DLL后才能这样做,这需要重写文件中的导出表。这在技术上是可能的,但并不容易做到。

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

代码语言:javascript
复制
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文件(别忘了)之后,导出如下所示:

代码语言:javascript
复制
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]
票数 1
EN

Stack Overflow用户

发布于 2014-08-22 16:13:55

使用MSVC 2010,您可能没有任何可供选择的工作,但在in 2012/2013 你可以选择“pdbcopy.exe”。从帮助中,你可以找到你所需要的:

代码语言:javascript
复制
PDBCopy v11.00.50307
usage: PDBCopy <source_pdb> <destination_pdb> [-p] [-s] [-f] [-F] [-a] [-A] [-?]
    [-p]                remove private debug information
    [-s]                create new signature
    [-f:{@file|symbol}] filter specific public symbols out of stripped pdb
    [-F:{@file|symbol}] leave only specific public symbols in stripped pdb
    [-a]                leave all annotation symbols in stripped pdb
    [-a:{@file|symbol}] filter specific annotation symbols out of stripped pdb
    [-A:{@file|symbol}] leave only specific annotation symbols in stripped pdb
    [-?]                display this message
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21027374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档