【问题标题】:MinGW: Linking with -nostdlib produces invalid executableMinGW:与 -nostdlib 链接会产生无效的可执行文件
【发布时间】:2021-01-31 12:43:43
【问题描述】:

在过去的几个小时里,我尝试使用 MinGW 链接一个没有任何 CRT 初始化代码的简单 x86 汇编程序。我希望可执行文件只包含下面列出的_main 方法和ExitProcess 内核函数的单个导入。

在反汇编程序中打开各种生成的文件显示_main 确实是入口点,并且导入表包含从KERNEL32.dll 导入的ExitProcess(没有名称装饰),但是 Windows 不会加载可执行文件,声称“%1 不是有效的 Win32 应用程序。”

我注意到一个奇怪的事情是,当我在Resource Hacker 打开文件时,添加一个小的嵌入式资源并保存,生成的文件执行没有问题。这让我相信这不是链接步骤本身的问题,而是文件头的问题,因为这应该是过程中唯一改变的部分。删除嵌入的资源并再次保存会导致 Resource Hacker 崩溃并将可执行文件恢复到之前的损坏状态。

代码

; test.asm
global _main
extern _ExitProcess@4
section .text
_main:
    push    0
    call    _ExitProcess@4

尝试失败

  • nasm -fwin32 test.asm & gcc -s test.obj
    创建一个正常运行的可执行文件,但还包含我试图避免的所有 CRT 启动代码。
  • nasm -fwin32 test.asm & gcc -s -nostartfiles test.obj
    创建一个无效的可执行文件。
  • nasm -fwin32 test.asm & gcc -s -nostdlib test.obj
    创建一个无效的可执行文件。
  • nasm -fwin32 test.asm & ld test.obj -e _main
    创建一个无效的可执行文件。

所有命令都成功执行,没有控制台输出。我还尝试在gcc 调用中添加-lkernel32-Wl,-e_main 的各种组合,但似乎都没有任何效果。

环境

C:\Projects\asm>systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
OS Name:     Microsoft Windows 10 Home
OS Version:  10.0.19041 N/A Build 19041

C:\Projects\asm>nasm --version
NASM version 2.15.05 compiled on Aug 28 2020

C:\Projects\asm>gcc --version
gcc (MinGW.org GCC Build-2) 9.2.0

C:\Projects\asm>ld --version
GNU ld (GNU Binutils) 2.32

【问题讨论】:

  • FWIW,我可以重现这个。将crtbegin.o 添加到链接命令会生成一个正常运行的可执行文件。我不知道 crtbegin 中有什么,但如果你挖掘源代码,那可能就是你能找到答案的地方。也许只是它添加了一个 rdata 部分?
  • @DavidWohlferd 很好的观察,添加 .rdata 部分确实使一切变得不同。我可以通过在程序集源中手动添加它来实现这一点。您想将此作为实际答案发布,以便我接受吗?

标签: assembly gcc linker mingw ld


【解决方案1】:

根据要求,我将发布此作为答案,但有一个很大的警告:

虽然这解决了发布的问题,但我真的不明白为什么。我不知道(也找不到)任何 Windows PE 要求您必须有一个 rdata 部分,这表明这是“意外”修复问题。

另外,虽然我在这里使用rdata,但pdata 也可以工作(但data 不行)。

考虑到这一点,您可以通过添加 rdata 部分来解决问题。所以修改代码如下解决问题,让可执行文件按预期运行:

; test.asm

section .rdata
db      9

section .text
extern _ExitProcess@4

global _main
_main:
    push    0
    call    _ExitProcess@4

【讨论】:

  • 另一种方法是使用i686 TDM GCC(i686/x86 MinGW-w64 版)之类的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 2011-11-06
  • 2020-02-18
  • 1970-01-01
  • 2019-04-29
相关资源
最近更新 更多