首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >链接到ntdll.lib并在ntdll.dll中调用函数

链接到ntdll.lib并在ntdll.dll中调用函数
EN

Stack Overflow用户
提问于 2016-02-19 15:53:11
回答 2查看 10.2K关注 0票数 6

我最近对私有API进行了一些研究。我尝试在运行时用NtOpenFileGetProcAddress调用ntdll.dll中的LoadLibraryGetProcAddress等函数。幸运的是它成功了。今天早上,我在我的电脑上做了一个文件搜索,在我的C驱动器中找到了ntdll.lib。据我所知,这种.lib文件应该包含可用于链接的dll导出的存根。因此,我试图将我的应用程序链接到这个库,但我经常收到unresolved external symbol错误。但是,dumpbin /EXPORTS显示ntdll.lib显然已经导出了NtOpenFile。如何解决此错误?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-19 16:58:06

问题是函数的名称,它记录在库中,是由编译器生成的。

dumpbin只向您显示基本导出的符号NtOpenFile (未修饰的符号),但也有一个导入符号__imp_NtOpenFile。现在,如果您尝试链接静态NtOpenFile,将其声明为:

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2019-07-16 05:49:53

不再是这种情况了,当我在2019年编写这篇文章时,可以找到ntdll.lib导入库和NT头。

要以GetProcAddress()的方式完成这一任务,需要大量额外的代码。当然,直接导入更干净,也是我们习惯于C/C++桌面应用程序的模式。

我过去常常创建自己的"ntdll.lib“导入库,方法是创建一个带有.def文件的简单Windows项目,等等。当我需要每个ntdll函数作为存根和头文件时,添加它们一个。丢弃.dll,只使用它的.lib。

但至少自2017年以来,它包含了32位和64位版本的用于x86和ARM的用户模式(用于桌面应用程序)、x86库和ARM。这可能需要安装Windows 10 WDK。只需搜索"C:\Program (x86)“中的"ntdll.lib”,就可以找到它们。

然后在标题前面,很多ntdll原型和定义都在“winterl.h”中,但不幸的是,很多部分都丢失了,并且/或只有结构的简化版本等等。要解决这个问题,您可以使用来自"Process“项目的奇妙的NT头集:https://github.com/processhacker/processhacker报头在"phnt”中。

而不是典型的"windows.h“和”wintl.h“组合,您将使用:

代码语言:javascript
运行
复制
#include <phnt_windows.h>
#include <phnt.h>

然后,以Windows 10为目标(默认为Windows 7),您可以这样做:

代码语言:javascript
运行
复制
#undef PHNT_VERSION
#define PHNT_VERSION PHNT_THRESHOLD 

注意,"phnt_windows.h“已经包括了"windows.h”。因此,您应该能够在后面的任何其他Windows、stdlib、stl等文件中跟踪它;与典型的桌面构建环境没有太大的不同。

或其他可供使用的:

https://github.com/Fyyre/ntdll

还包括libs:

https://github.com/x64dbg/ScyllaHide/tree/master/3rdparty/ntdll

还有另一个具有ntdll库的库:

https://github.com/odzhan/injection/tree/master/ntlib

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35509388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档