5

每当我使用 C++ Builder(版本 XE4,但以前的版本也这样做)以发布模式构建 Win32 EXE 时,它总是会创建一个导出目录并为我的项目中的每个单元导出一个 Initialize/Finalize 条目。这会导致数千次不必要的出口。Win64 版本也有类似的问题,但生成的导出并不多。

使用 dumpbin 工具快速检查会得到以下(缩写)输出:

  Section contains the following exports for PROJECTX.exe

    00000000 characteristics
           0 time date stamp Thu Jan 01 00:00:00 1970
        0.00 version
           1 ordinal base
        1205 number of functions
        1205 number of names

    ordinal hint RVA      name

      1046     0 003ECF44 @$xp$13Gdipapi@INT16
      1077     1 003ED64C @$xp$13Gdipapi@PARGB
      1053     2 003ED0D4 @$xp$13Gdipapi@Unit_
      1047     3 003ECF5C @$xp$14Gdipapi@UINT16
      1049     4 003ECF88 @$xp$14Gdipapi@UINT32
       ...
       261    E0 000BD758 @@Find@Finalize
       260    E1 000BD748 @@Find@Initialize
       153    E2 0007EE70 @@Flags@Finalize
       152    E3 0007EE60 @@Flags@Initialize
       ...

我担心的是除了增加 PE 文件的大小和加载时间之外,这些导出条目提供的元数据可以帮助对我的二进制文件进行逆向工程,因此我想将它们删除。

一个 hacky 解决方案是在构建后手动删除 PE 图像导出目录,但是必须在 c++ builder IDE/编译器中为此提供解决方案。

为什么 C++ Builder 会这样做,如何禁用生成这些导出目录条目?

更新:在 Win32 Release 模式下构建一个空的 VCL Forms 应用程序会默认生成以下导出...

  Section contains the following exports for Project1.exe

    00000000 characteristics
           0 time date stamp Thu Jan 01 00:00:00 1970
        0.00 version
           1 ordinal base
           5 number of functions
           5 number of names

    ordinal hint RVA      name

          3    0 000036C8 @@Unit1@Finalize
          2    1 000036B8 @@Unit1@Initialize
          5    2 00006974 _Form1
          1    3 00001F59 __GetExceptDLLinfo
          4    4 000060AC ___CPPdebugHook
4

1 回答 1

8

如果删除自动生成的

#pragma package(smart_init)

.cpp 文件顶部的行,则 C++Builder 不会导出每个单元InitializeFinalize方法。

认为只有#pragma package(smart_init)当您计划将.cpp文件放入包中(而不是直接放入 exe 中)时才需要这样做。所以我认为在你的情况下删除是安全的,docwiki有更多细节。

话虽如此,我认为这不值得担心:

  • 除非您确定这些对您的文件大小和/或加载时间有可衡量的影响,否则还有更重要的事情需要担心。(“过早的优化是万恶之源”、 “在优化之前总是衡量性能”等)
  • Delphi 和 C++Builder 的设计已经泄露了大量用于逆向工程的信息。Delphi 的 RTTI 意味着任何 __published 属性都嵌入在可执行文件中,并且有一些实用程序可以从可执行文件中提取 DFM。与此相比,从导出InitializeFinalize方法中泄漏的单元名称相对较小。
  • 逆向工程可能不像程序员通常所说的那样令人担忧。共识是(a)一个有足够动力和技术的黑客可以对任何他想要的东西进行逆向工程;(b)你和你公司的知识、客户关系和支持比你代码中的任何算法都更有价值。
于 2013-05-16T14:41:54.977 回答