MinGW:与-nostdlib链接产生无效的可执行文件 [英] MinGW: Linking with -nostdlib produces invalid executable

查看:110
本文介绍了MinGW:与-nostdlib链接产生无效的可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了最后两个小时,尝试使用MinGW链接不带任何CRT初始化代码的简单x86汇编程序.我希望可执行文件仅包含下面列出的 _main 方法和 ExitProcess 内核函数的单个导入.

I've spent the last couple of hours trying to link a simple x86 assembly program without any of the CRT initialization code using MinGW. I want the executable to only contain the _main method listed below and a single import of the ExitProcess kernel function.

在反汇编器中打开生成的各种文件,发现 _main 确实是入口点,并且导入表包含从<导入的 ExitProcess (无名称修饰).code> KERNEL32.dll ,但是Windows不会加载可执行文件,声称%1不是有效的Win32应用程序."

Opening the various generated files in a disassembler reveals that _main is indeed the entry point and the import table contains an import of ExitProcess (without the name decorations) from KERNEL32.dll, however Windows won't load the executable, claiming that "%1 is not a valid Win32 application."

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

One curious thing I noticed is that when I open the file in Resource Hacker, add a small embedded resource and save, the resulting file executes without issues. This leads me to believe that it's not an issue with the linking step itself, but rather with the file header, since that should be the only part changing in the process. Deleting the embedded resource and saving again causes Resource Hacker to crash and restores the executable to its previous broken state.

; 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
    创建无效的可执行文件.
  • 所有命令成功执行,没有控制台输出.我还尝试过将 -lkernel32 -Wl,-e_main 的各种组合添加到 gcc 调用中,似乎都没有任何组合效果.

    All of the commands execute successfully with no console output. I've also tried adding various combinations of -lkernel32 and -Wl,-e_main to the gcc calls, none of which seemed to have any effect.

    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
    

    推荐答案

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

    As requested, I'm going to post this as an answer, but with a big caveat:

    尽管此操作可以解决已发布的问题,但我真的不明白为什么.我不知道(也找不到)任何Windows PE要求,即您必须具有rdata节,这表明这是偶然"修复问题.

    While this fixes the problem as posted, I don't really understand why. I'm not aware of (and can't find) any Windows PE requirement that you must have an rdata section, which suggests this is fixing things "by accident."

    此外,虽然我在这里使用 rdata ,但 pdata 也可以工作(但 data 无效).

    Also, while I'm using rdata here, pdata also works (but data does not).

    考虑到这一点,您可以通过添加rdata节来解决该问题.因此,按如下所示更改代码可以解决问题,并允许可执行文件按预期运行:

    With that in mind, you can solve the problem by adding an rdata section. So changing the code as follows solves the problem, allowing the executable to run as expected:

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

    这篇关于MinGW:与-nostdlib链接产生无效的可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆