简体   繁体   English

使用 ld.exe 链接到 kernel32.dll

[英]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:我已经意识到答案现在在评论中,但为了清楚起见,我将在此处发布所有步骤:

  1. Create a .def file for the DLL to be used.为要使用的 DLL 创建一个.def文件。 This can be done like this:这可以这样做:
LIBRARY [name of the dll]
EXPORTS
    [required export #1]
    [required export #2]
    [etc.]
  1. Use 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).在此命令中, ClibXXX.a ,其中XXX更改为不同的名称(最好是原始 dll 的名称,不带扩展名)。

  1. Instead of using 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 own libkernel32.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM