[英]Link to kernel32.dll using ld.exe
I have assembled my assembly program using the following command:我使用以下命令组装了我的汇编程序:
nasm -f win64 -o test.obj test.asm
test.asm contains a few functions that call Win32 functions like GetStdHandle, HeapAlloc, etc test.asm 包含一些调用 Win32 函数的函数,如 GetStdHandle、HeapAlloc 等
Normally, I would link one of my assembly projects like so:通常,我会像这样链接我的一个装配项目:
ld -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
And it produces a test.exe
file, as expected.正如预期的那样,它会生成一个
test.exe
文件。
However, once I begin to use Win32 functions making use of the heap , like HeapAlloc, HeapFree, GetProcessHeap, I get the following error when linking:但是,一旦我开始使用利用堆的Win32 函数,如 HeapAlloc、HeapFree、GetProcessHeap,在链接时会出现以下错误:
C:\msys64\mingw64\bin\ld.exe: ertr000016.o:(.rdata+0x0): undefined reference to '_pei386_runtime_relocator'
I was then able to assume it has to do with MinGW's files being linked in. So I tried to compile it without them:然后我可以假设它与链接到 MinGW 的文件有关。所以我尝试在没有它们的情况下编译它:
ld -nostdlib -nostartfiles -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
and get the following error:并得到以下错误:
C:\msys64\mingw64\bin\ld.exe: cannot find -lkernel32
So, my question is: how am I supposed to link to kernel32 using ld.exe (without including startfiles or stdlib), because no matter what I try I cannot get it to work.所以,我的问题是:我应该如何使用 ld.exe(不包括 startfiles 或 stdlib)链接到 kernel32,因为无论我尝试什么,我都无法让它工作。
Thank you for your help!谢谢您的帮助!
(I would like an answer that doesn't just tell me use GoLink , please, unless that is the only possible solution). (我想要一个不只是告诉我使用GoLink的答案,除非这是唯一可能的解决方案)。
I've realized that the answer is in the comments now, but I'll post all the steps here just to be clear:我已经意识到答案现在在评论中,但为了清楚起见,我将在此处发布所有步骤:
.def
file for the DLL to be used..def
文件。 This can be done like this:LIBRARY [name of the dll]
EXPORTS
[required export #1]
[required export #2]
[etc.]
dlltool.exe
to create an archive library file for the .def
file:dlltool.exe
为.def
文件创建存档库文件:dlltool -d "[path to the .def file]" -l "[path to output file C, defined below]"
In this command, C
is libXXX.a
, with XXX
changed out for a different name (preferably the name of the original dll without the extension).在此命令中,
C
为libXXX.a
,其中XXX
更改为不同的名称(最好是原始 dll 的名称,不带扩展名)。
ld.exe
, use the linker built into gcc.exe
.ld.exe
,而是使用 gcc.exe 内置的gcc.exe
。 Also, change out the directory after -L
for the directory containing the libXXX.a
archive file(s) and change out the dll names that follow for the XXX
that was replaced in libXXX.a
.-L
之后的目录更改为包含libXXX.a
存档文件的目录,并更改在 libXXX.a 中替换的XXX
后面的libXXX.a
名称。 These steps, in the context of the original problem, would be:[Kernel32.def file]
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
[...]
dlltool -d "kernel32.def" -l "libkernel32.a"
gcc -LC:/path/to/this/directory/ -lkernel32 -e main -o test.exe test.obj
... -LC:/Windows/System32 -lkernel32...
This is definitely wrong: -lkernel32
will not search for a DLL file named kernel32.dll
, but for a library file named libkernel32.a
.这绝对是错误的:
-lkernel32
不会搜索名为kernel32.dll
的 DLL 文件,而是搜索名为libkernel32.a
的库文件。
... and libkernel32.a
is surely not located in C:/Windows/System32
. ...并且
libkernel32.a
肯定不在C:/Windows/System32
中。
How I would go about using
dlltool.exe
to generate my ownlibkernel32.a
?我将如何 go 关于使用
dlltool.exe
生成我自己的libkernel32.a
?
For 64-bit Windows this is easier than for 32-bit Windows (because in 32-bit Windows the fuctions are named differently in the DLL and in the object files). For 64-bit Windows this is easier than for 32-bit Windows (because in 32-bit Windows the fuctions are named differently in the DLL and in the object files).
First, you create a definition file ( .def
) that looks like this:首先,您创建一个如下所示的定义文件 (
.def
):
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
There is a 3rd party tool that can read a .dll
file and generate a .def
file containing all functions of the DLL;有一个第三方工具可以读取一个
.dll
文件并生成一个包含DLL所有功能的.def
文件; however, you can do this manually and only add the functions that you need.但是,您可以手动执行此操作,并且只添加您需要的功能。
Then run the following command line:然后运行以下命令行:
dlltool -d kernel32.def -l libkernel32.a
Unfortunately, I cannot tell you if this solves your problem with _pei386_runtime_relocator
.不幸的是,我无法告诉您这是否可以解决您的
_pei386_runtime_relocator
问题。
EDIT编辑
undefined reference to 'SetFilePointer'
SetFilePointer
is also a function defined in kernel32.dll
. SetFilePointer
也是kernel32.dll
中定义的 function 。 Did you add SetFilePointer
to the .def
file?您是否将
SetFilePointer
添加到.def
文件中?
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
SetFilePointer <-- HERE?
I am linking with the following command:
我正在使用以下命令链接:
There may be a second problem:可能还有第二个问题:
Some versions of gcc
require the command line arguments in a certain order. gcc
的某些版本需要按一定顺序使用命令行 arguments。 Maybe this is true for ld
, too.也许这对
ld
也是如此。
Try to move the -L
and -l
argument to the end of the line:尝试将
-L
和-l
参数移到行尾:
ld ... -o test.exe test.o -L... -lkernel32
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.