Link 到 kernel32.dll 使用 ld.exe
Link to kernel32.dll using ld.exe
我使用以下命令组装了我的汇编程序:
nasm -f win64 -o test.obj test.asm
test.asm 包含一些调用 Win32 函数的函数,如 GetStdHandle、HeapAlloc 等
通常,我会 link 我的一个装配项目是这样的:
ld -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
并按预期生成 test.exe
文件。
但是,一旦我开始使用 Win32 函数利用堆,如 HeapAlloc、HeapFree、GetProcessHeap,我在 linking 时会收到以下错误:
C:\msys64\mingw64\bin\ld.exe: ertr000016.o:(.rdata+0x0): undefined reference to '_pei386_runtime_relocator'
然后我可以假设它与 MinGW 的文件有关 linked in。所以我尝试在没有它们的情况下编译它:
ld -nostdlib -nostartfiles -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
并得到以下错误:
C:\msys64\mingw64\bin\ld.exe: cannot find -lkernel32
所以,我的问题是:我应该如何使用 ld.exe(不包括 startfiles 或 stdlib)link 到 kernel32,因为无论我尝试什么,我都无法让它工作。
感谢您的帮助!
(我想要一个不只是告诉我使用 GoLink 的答案,除非那是唯一可能的解决方案)。
... -LC:/Windows/System32 -lkernel32 ...
这绝对是错误的:-lkernel32
不会搜索名为 kernel32.dll
的 DLL 文件,而是搜索名为 libkernel32.a
.
的库文件
... libkernel32.a
肯定不在 C:/Windows/System32
.
How I would go about using dlltool.exe
to generate my own libkernel32.a
?
对于 64 位 Windows 这比 32 位 Windows 更容易(因为在 32 位 Windows 中,函数在 DLL 和对象中的命名不同文件)。
首先,您创建一个如下所示的定义文件 (.def
):
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
有一个第 3 方工具可以读取 .dll
文件并生成包含 DLL 的所有函数的 .def
文件;但是,您可以手动执行此操作,并且只添加您需要的功能。
然后运行以下命令行:
dlltool -d kernel32.def -l libkernel32.a
遗憾的是,我无法告诉您这是否解决了您 _pei386_runtime_relocator
的问题。
编辑
undefined reference to 'SetFilePointer'
SetFilePointer
也是kernel32.dll
中定义的函数。您是否将 SetFilePointer
添加到 .def
文件?
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
SetFilePointer <-- HERE?
I am linking with the following command:
可能还有第二个问题:
某些版本的 gcc
要求命令行参数按特定顺序排列。也许 ld
也是如此。
尝试将 -L
和 -l
参数移动到行尾:
ld ... -o test.exe test.o -L... -lkernel32
我已经意识到答案现在在评论中,但为了清楚起见,我将post这里的所有步骤:
- 为要使用的 DLL 创建一个
.def
文件。可以这样做:
LIBRARY [name of the dll]
EXPORTS
[required export #1]
[required export #2]
[etc.]
- 使用
dlltool.exe
为.def
文件创建归档库文件:
dlltool -d "[path to the .def file]" -l "[path to output file C, defined below]"
在这个命令中,C
是libXXX.a
,XXX
换了一个不同的名字(最好是没有扩展名的原始dll的名字)。
- 不使用
ld.exe
,而是使用 gcc.exe
中内置的链接器。此外,将 -L
之后的目录更改为包含 libXXX.a
存档文件的目录,并更改 XXX
之后的 dll 名称,这些名称在 libXXX.a
中被替换].在原始问题的上下文中,这些步骤将是:
[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
我使用以下命令组装了我的汇编程序:
nasm -f win64 -o test.obj test.asm
test.asm 包含一些调用 Win32 函数的函数,如 GetStdHandle、HeapAlloc 等
通常,我会 link 我的一个装配项目是这样的:
ld -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
并按预期生成 test.exe
文件。
但是,一旦我开始使用 Win32 函数利用堆,如 HeapAlloc、HeapFree、GetProcessHeap,我在 linking 时会收到以下错误:
C:\msys64\mingw64\bin\ld.exe: ertr000016.o:(.rdata+0x0): undefined reference to '_pei386_runtime_relocator'
然后我可以假设它与 MinGW 的文件有关 linked in。所以我尝试在没有它们的情况下编译它:
ld -nostdlib -nostartfiles -LC:/Windows/System32 -lkernel32 -e main -o test.exe test.obj
并得到以下错误:
C:\msys64\mingw64\bin\ld.exe: cannot find -lkernel32
所以,我的问题是:我应该如何使用 ld.exe(不包括 startfiles 或 stdlib)link 到 kernel32,因为无论我尝试什么,我都无法让它工作。
感谢您的帮助!
(我想要一个不只是告诉我使用 GoLink 的答案,除非那是唯一可能的解决方案)。
... -LC:/Windows/System32 -lkernel32 ...
这绝对是错误的:-lkernel32
不会搜索名为 kernel32.dll
的 DLL 文件,而是搜索名为 libkernel32.a
.
... libkernel32.a
肯定不在 C:/Windows/System32
.
How I would go about using
dlltool.exe
to generate my ownlibkernel32.a
?
对于 64 位 Windows 这比 32 位 Windows 更容易(因为在 32 位 Windows 中,函数在 DLL 和对象中的命名不同文件)。
首先,您创建一个如下所示的定义文件 (.def
):
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
有一个第 3 方工具可以读取 .dll
文件并生成包含 DLL 的所有函数的 .def
文件;但是,您可以手动执行此操作,并且只添加您需要的功能。
然后运行以下命令行:
dlltool -d kernel32.def -l libkernel32.a
遗憾的是,我无法告诉您这是否解决了您 _pei386_runtime_relocator
的问题。
编辑
undefined reference to 'SetFilePointer'
SetFilePointer
也是kernel32.dll
中定义的函数。您是否将 SetFilePointer
添加到 .def
文件?
LIBRARY KERNEL32.DLL
EXPORTS
HeapAlloc
HeapFree
GetProcessHeap
CreateFileA
ReadFile
SetFilePointer <-- HERE?
I am linking with the following command:
可能还有第二个问题:
某些版本的 gcc
要求命令行参数按特定顺序排列。也许 ld
也是如此。
尝试将 -L
和 -l
参数移动到行尾:
ld ... -o test.exe test.o -L... -lkernel32
我已经意识到答案现在在评论中,但为了清楚起见,我将post这里的所有步骤:
- 为要使用的 DLL 创建一个
.def
文件。可以这样做:
LIBRARY [name of the dll]
EXPORTS
[required export #1]
[required export #2]
[etc.]
- 使用
dlltool.exe
为.def
文件创建归档库文件:
dlltool -d "[path to the .def file]" -l "[path to output file C, defined below]"
在这个命令中,C
是libXXX.a
,XXX
换了一个不同的名字(最好是没有扩展名的原始dll的名字)。
- 不使用
ld.exe
,而是使用gcc.exe
中内置的链接器。此外,将-L
之后的目录更改为包含libXXX.a
存档文件的目录,并更改XXX
之后的 dll 名称,这些名称在libXXX.a
中被替换].在原始问题的上下文中,这些步骤将是:
[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