不带.RELOC节的可执行文件

问题描述

我正在使用MSVC2019。我已经编译了一个简单的C ++代码(Hello World ...)。在x86体系结构中以发布模式进行编译时,会有一个.reloc部分,但是在x64体系结构中进行编译时,则.reloc部分不存在。 / p>

这是什么原因?我需要带有.reloc节的可执行文件

最诚挚的问候。

编辑-1:

C / C ++ Settigs:

/permissive- /GS- /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc142.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MT /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\test-reloc.pch" /diagnostics:column

链接器设置:

/OUT:"F:\Test\x64\Release\test-reloc.exe" /MANIFEST:NO /LTCG:incremental /NXCOMPAT /PDB:"F:\Test\x64\Release\test-reloc.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" /FIXED:NO /MACHINE:X64 /ENTRY:"relocMain" /OPT:REF /SAFESEH:NO /INCREMENTAL:NO /PGD:"F:\Test\x64\Release\test-reloc.pgd" /SUBSYstem:CONSOLE /MANIFESTUAC:NO /OPT:ICF /ERRORREPORT:PROMPT /NOlogo /NODEFAULTLIB /TLBID:1

解决方法

问题是关于MSVC在x64版本中生成的PE布局。省略不相关的细节,可以在纯C中重新编写,如下所示。

// main.c

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int __stdcall rawMain()
{
    OutputDebugStringA("Hello World!\n");
    return 0;
}

上面的简约C程序是在不使用或不链接到CRT的情况下构建的,在x64编译器中没有.reloc部分。

X:\etc>cl /nologo main.c /GS- /O2 /link /nodefaultlib kernel32.lib /manifest:no /subsystem:console /machine:x64 /entry:rawMain
main.c

X:\etc>dumpbin /nologo main.exe

Dump of file main.exe

File Type: EXECUTABLE IMAGE

  Summary

        1000 .pdata
        1000 .rdata
        1000 .text

X:\etc>

这是什么原因?

原因是所生成的代码没有重定位,因此没有创建.reloc部分,因为“ 如果部分为空,Windows将拒绝加载DLL(或EXE)” -如SO上对How to use the fixups attribute on a section?的回答所引用,并引用了面板上的dll in fasm (bug?!)线程。

如果绝对需要.reloc节,最简单的方法是在代码中强制使用可重定位符号。例如,以下足以实现它。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

static void (*foo)(LPCSTR) = OutputDebugStringA;

int __stdcall rawMain()
{
    foo("Hello World!\n");
    return 0;
}
X:\etc>cl /nologo main.c /GS- /O2 /link /nodefaultlib kernel32.lib /manifest:no /subsystem:console /machine:x64 /entry:rawMain
main.c

X:\etc>dumpbin /nologo /relocations main.exe

Dump of file main.exe

File Type: EXECUTABLE IMAGE

BASE RELOCATIONS #5
    3000 RVA,C SizeOfBlock
       0  DIR64      0000000140001018
       0  ABS

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .text

X:\etc>