我花了过去几个小时尝试链接一个简单的 x86 汇编程序,而无需any使用 MinGW 的 CRT 初始化代码。我希望可执行文件只包含_main
下面列出的方法和一次导入ExitProcess
核函数。
在反汇编程序中打开各种生成的文件表明_main
确实是入口点,导入表包含以下导入ExitProcess
(没有名字装饰)来自KERNEL32.dll
,但是 Windows 不会加载可执行文件,并声称“%1 不是有效的 Win32 应用程序”。
我注意到的一件奇怪的事情是,当我打开文件时资源黑客 http://www.angusj.com/resourcehacker/,添加一个小的嵌入式资源并保存,生成的文件执行没有问题。这让我相信这不是链接步骤本身的问题,而是文件头的问题,因为这应该是过程中唯一发生变化的部分。删除嵌入资源并再次保存会导致 Resource Hacker 崩溃并将可执行文件恢复到之前的损坏状态。
The code
; 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
and -Wl,-e_main
to the gcc
电话,但似乎都没有任何效果。
环境
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
根据要求,我将将此作为答案发布,但有一个很大的警告:
虽然这解决了发布的问题,但我不太明白为什么。我不知道(也找不到)任何 Windows PE 要求您必须有一个 rdata 部分,这表明这是“意外”修复问题。
另外,当我使用rdata
here, pdata
也有效(但是data
才不是)。
考虑到这一点,您可以通过添加 rdata 部分来解决问题。因此,按如下方式更改代码可以解决问题,使可执行文件按预期运行:
; test.asm
section .rdata
db 9
section .text
extern _ExitProcess@4
global _main
_main:
push 0
call _ExitProcess@4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)