为什么 EXE 文件中有文本函数名称?
Why are there text function names inside EXE file?
我编译了一个 C++ 程序,在发布模式下有一个 EXE 文件。当我在编辑器中打开 EXE 文件时,我看到了一些文本块,它们大多是程序中使用的低级函数的名称。
总有人说计算机只懂二进制机器码。那么,可执行程序文件中这些人类可读的文本存在的目的是什么?为什么计算机 运行 程序需要函数名?
IDE: Visual Studio 2015 RC
平台:Windows 8.1 x64
编译器命令行选项:
/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"
链接器命令行选项:
/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
编辑:
我在 中进行了更改。我进行了项目设置更改,将命令行开关 \MD
更改为 \MT
。可执行文件大小从 56kb 更改为 436kb。我猜是因为现在需要的库在运行时没有链接,而是从一开始就存储在EXE文件中。但是 EXE 文件中仍然有文本块,如下面的屏幕截图所示。标准模板库 (STL) 中的函数名已完全消失,但有很多 Win32 API 函数名。现在可能是什么原因?
这些是要从 .DLL 访问的名称。尝试使用静态库进行构建,这些名称应该会消失,但 .EXE 会变大。为此,对于发布版本,右键单击项目中的源文件名,并将 运行 时间库从 "Multi-threaded DLL" (/MD) 更改为 "Multi-threaded (/MT)"。这里的主要变化是编译器命令行选项 /MD 更改为 /MT。
但是,正如下面 Peter Torr 所评论的那样,您仍然坚持使用一些 dll 模块,例如 kernel32.dll。
基于 windows 构建的可执行文件使用可移植可执行文件格式:https://msdn.microsoft.com/en-us/library/ms809762.aspx
为了 link 在 DLL 中运行,EXE 使用导入和导出表创建,其中包含运行时使用的函数的地址。如果您将 SDK(或 VC++?)实用程序 "dumpbin" 与 /exports 或 /imports 一起使用,您可以看到从模块导入或导出的函数。当新版本发布时,DLL 的布局可能会发生变化,因此导入和导出表是调用者获取另一个动态模块中函数地址的一种方式 linked.
我编译了一个 C++ 程序,在发布模式下有一个 EXE 文件。当我在编辑器中打开 EXE 文件时,我看到了一些文本块,它们大多是程序中使用的低级函数的名称。
总有人说计算机只懂二进制机器码。那么,可执行程序文件中这些人类可读的文本存在的目的是什么?为什么计算机 运行 程序需要函数名?
IDE: Visual Studio 2015 RC
平台:Windows 8.1 x64
编译器命令行选项:
/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"
链接器命令行选项:
/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
编辑:
我在 \MD
更改为 \MT
。可执行文件大小从 56kb 更改为 436kb。我猜是因为现在需要的库在运行时没有链接,而是从一开始就存储在EXE文件中。但是 EXE 文件中仍然有文本块,如下面的屏幕截图所示。标准模板库 (STL) 中的函数名已完全消失,但有很多 Win32 API 函数名。现在可能是什么原因?
这些是要从 .DLL 访问的名称。尝试使用静态库进行构建,这些名称应该会消失,但 .EXE 会变大。为此,对于发布版本,右键单击项目中的源文件名,并将 运行 时间库从 "Multi-threaded DLL" (/MD) 更改为 "Multi-threaded (/MT)"。这里的主要变化是编译器命令行选项 /MD 更改为 /MT。
但是,正如下面 Peter Torr 所评论的那样,您仍然坚持使用一些 dll 模块,例如 kernel32.dll。
基于 windows 构建的可执行文件使用可移植可执行文件格式:https://msdn.microsoft.com/en-us/library/ms809762.aspx
为了 link 在 DLL 中运行,EXE 使用导入和导出表创建,其中包含运行时使用的函数的地址。如果您将 SDK(或 VC++?)实用程序 "dumpbin" 与 /exports 或 /imports 一起使用,您可以看到从模块导入或导出的函数。当新版本发布时,DLL 的布局可能会发生变化,因此导入和导出表是调用者获取另一个动态模块中函数地址的一种方式 linked.