5

I compiled a C++ program to have an EXE file in release mode. When I open the EXE file in an editor, I see pieces of text blocks, which are mostly the names of used low level functions in the program.

It is always said that the computer only understands binary machine code. Then, what is the purpose of existence for these human readable text inside the executable program file? Why does the computer need the function names to run the program?

enter image description here

IDE: Visual Studio 2015 RC
Platform: Windows 8.1 x64

Compiler command line options:

/GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /Ox /Ob2 /sdl
/Fd"x64\Release\vc140.pdb" /Zc:inline /fp:precise /D "_MBCS"
/errorReport:prompt /GT /WX- /Zc:forScope /Gd /Oy /Oi /MD
/Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Ot
/Fp"x64\Release\<ProjectName>.pch"

Linker command line options:

/OUT:"<SolutionPath>\x64\Release\<ProjectName>.exe"
/MANIFEST /LTCG /NXCOMPAT
/PDB:"<SolutionPath>\x64\Release\<ProjectName>.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib"
"uuid.lib" "odbc32.lib" "odbccp32.lib"
/MACHINE:X64 /OPT:REF /PGD:"<SolutionPath>\x64\Release\<ProjectName>.pgd"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"x64\Release\<ProjectName>.exe.intermediate.manifest"
/OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1

EDIT:

I did the change in rcgldr's answer. I made the project setting change that alter the command line switch \MD to \MT. The executable file size changed from 56kb to 436kb. I guess it is because now the required libraries are not linked at runtime, but they are stored in the EXE file from the beginning. But still there are blocks of text in the EXE file as seen in the screen shot below. Function names from the Standard Template Library (STL) are completely gone, but there are a lot of Win32 API function names. What could be the reason now?

enter image description here

Community
  • 1
  • 1
hkBattousai
  • 10,583
  • 18
  • 76
  • 124
  • Consider debugging information. The hairless ape is great at reading text, but not so good with numbers so you will find little tags and hints left in anything that hasn't been deliberately obfuscated. – user4581301 Jul 18 '15 at 17:44
  • See Peter Torr's response below. Functions imported from the operating system cannot be statically linked. – Raymond Chen Jul 18 '15 at 23:06

2 Answers2

2

Those are names to access from the .DLL . Try building using static library instead and those names should go away, but the .EXE will get larger. To do this, for release build, right click on the source file name(s) in the project, and change run time library from "Multi-threaded DLL" (/MD) to "Multi-threaded (/MT)". The main change here is the compiler command line option /MD gets changed to /MT.

However, as commented by Peter Torr below you're still stuck with some dll modules, like kernel32.dll.

rcgldr
  • 27,407
  • 3
  • 36
  • 61
  • 2
    And then, as you have seen, you will get a list of the functions that the CRT / STL use from Windows. These functions are always dynamically linked. – Peter Torr - MSFT Jul 18 '15 at 22:05
1

Executables built on windows used the Portable Executable format: https://msdn.microsoft.com/en-us/library/ms809762.aspx

In order to link to functions in a DLL, the EXEs are created with import and export tables that contain the addresses of functions that are used at runtime. If you use the SDK (or VC++?) utility "dumpbin" with /exports or /imports you can see the functions that are imported or exported from a module. The layout of DLLs can change when new versions come out, so the import and export tables are a way for the caller to get the address of a function in another module that is dynamically linked.

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29