我最近正在对私有API进行一些研究。我试图在运行时使用NtOpenFile
和LoadLibrary
在ntdll.dll中调用GetProcAddress
等函数。幸运的是,它成功了。今天早上我在计算机上执行了文件搜索,并在我的C盘中找到ntdll.lib
。据我所知,这样的.lib文件应该包含可用于链接的dll导出的存根。所以,我试图将我的应用程序链接到该lib,但我经常遇到unresolved external symbol
错误。但是,dumpbin /EXPORTS
表明ntdll.lib显然已导出NtOpenFile。我怎么能解决这个错误?
答案 0 :(得分:2)
问题是库中记录的函数名称以及编译器生成的函数名称
dumpbin
只显示基本导出符号NtOpenFile
(未修饰的符号),但还有一个导入符号__imp_NtOpenFile
。
现在,如果您尝试静态链接NtOpenFile
,请将其声明为:
NTSTATUS NtOpenFile(
_Out_ PHANDLE FileHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ ULONG ShareAccess,
_In_ ULONG OpenOptions
);
编译器将为32位以下的__stdcall
函数生成符号_NtOpenFile@24
,如果我没有错误计算调用参数的字节大小,那么显然不在库中。
这是因为ntdll.lib旨在在DDK下用于驱动程序开发,其中编译器生成未修饰的符号。
为了阐明概念,使用二进制编辑器打开ntdll.lib文件并查找NtOpenFile
,您将只看到它和导入版本__imp_NtOpenFile
。现在以gdi32.lib打开一个标准库,只需命名一个,然后搜索CreateDIBSection
您会找到_CreateDIBSection@24
和__imp__CreateDIBSection@24
。
发生什么了?简单dumpbin始终显示未修饰的名称,但编译器生成装饰的名称,结果:链接器失败。据说名称使用PASCAL
约定,与__stdcall
相同,但不装饰符号(即读取此https://msdn.microsoft.com/en-us/library/aa235591(v=vs.60).aspx)。
有办法解决这个问题吗?是的,您必须创建自己的导入库,为具有正确装饰的所需函数指定别名。开始阅读此https://msdn.microsoft.com/en-us/library/0b9xe492.aspx。
答案 1 :(得分:0)
不再如此,我在2019年编写此文件时,便可以找到ntdll.lib导入库和NT标头。
使用 GetProcAddress()方法执行此操作有很多额外的代码。当然,直接导入更干净,这是我们在C / C ++桌面应用程序中惯用的模式。
我以前通过使用.def文件等创建一个简单的Windows DLL项目来制作自己的“ ntdll.lib”导入库。在需要时,将每个ntdll API函数都添加为一个存根,对于一个头文件。 丢弃.dll,仅使用其中的.lib即可。
但是至少从MSVC 2017开始,它包括用于32位和64位版本的x86和ARM的用户模式(用于桌面应用程序)ntdll.lib库。这可能需要安装Windows 10 WDK。 只需在“ C:\ Program Files(x86)”中搜索“ ntdll.lib”,即可找到它们。
然后在头文件的开头,许多ntdll原型和定义都在“ winternl.h”中,但是不幸的是,缺少了很多部分和/或仅是结构的简化版本等。 为了解决这个问题,您可以使用“ Process Hacker”项目中出色的NT标头集: https://github.com/processhacker/processhacker 标头位于“ phnt”中。
您将使用:
来代替典型的“ windows.h”和“ winternl.h”组合。#include <phnt_windows.h>
#include <phnt.h>
然后以Windows 10作为目标(例如,默认为Windows 7)作为目标,您可以按照以下步骤操作:
#undef PHNT_VERSION
#define PHNT_VERSION PHNT_THRESHOLD
请注意,“ phnt_windows.h”已包含“ windows.h”。 因此,您应该能够在其他Windows,stdlib,stl等标头之后跟随它;与典型的桌面构建环境没什么不同。
或其他一些要使用的内容:
https://github.com/Fyyre/ntdll
还包括库:
https://github.com/x64dbg/ScyllaHide/tree/master/3rdparty/ntdll
还有另一个带有ntdll库的文件:
https://github.com/odzhan/injection/tree/master/ntlib