Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable C++ Builder exporting unit names?

Tags:

c++builder

Whenever I build an Win32 EXE in release mode with C++ Builder (Version XE4, but previous versions do this also), it always creates an export directory and exports an Initialize/Finalize entry for every unit in my project. This leads to thousands of unnecessary exports. There is a similar issue with Win64 builds, but the exports generated are not as many.

A quick check with the dumpbin tool gives the following (abbreviated) output:

  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
       ...

My concern is apart from adding to the PE file size and loading time, these export entries provide metadata which could aid reverse engineering my binary and as such I would like to strip them out.

A hacky solution is to manually delete the PE images export directory after it is built, however there must be a solution for this from within the c++ builder IDE/compiler.

Why is C++ Builder doing this and how can I disable generating these export directory entries?

Update: Building an empty VCL Forms application in Win32 Release mode generates the following exports by default...

  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
like image 509
QAZ Avatar asked May 16 '13 13:05

QAZ


1 Answers

If you delete the automatically generated

#pragma package(smart_init)

line from the top of your .cpp file, then C++Builder won't export per-unit Initialize and Finalize methods.

I think that #pragma package(smart_init) is only needed if you plan on putting your .cpp files in a package (instead of directly in an exe). So I think it's safe to delete in your case, The docwiki has more details.

With that said, I don't think this is worth worrying about:

  • Unless you've determined that these are having a measurable impact on your file size and / or loading time, there are more important things to worry about. ("Premature optimization is the root of all evil," "always measure performance" before optimizing, etc.)
  • The design of Delphi and C++Builder already leaks plenty of information for reverse engineering. Delphi's RTTI means that any __published properties are embedded in the executable, and there are utilities to extract DFMs from executables. Leaking unit names from exported Initialize and Finalize methods is relatively minor compared to this.
  • Reverse engineering is probably not as big of a worry as programmers often make it out to be; the consensus is that (a) a sufficiently motivated and skilled hacker can reverse engineer anything he wants to and (b) your and your company's knowledge, customer relations, and support are worth far more than any algorithms in your code.
like image 195
Josh Kelley Avatar answered Oct 19 '22 02:10

Josh Kelley