问题标签 [nt-native-api]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - NtCreateFile 返回 STATUS_OBJECT_NAME_NOT_FOUND 即使文件存在于目录中
我一直在尝试使用 NtCreateFile 打开现有文件,尽管它无法找到我正在寻找的文件,即使它存在于我试图打开文件的目录中。
NtCreateFile 返回错误代码 0x34,即 STATUS_OBJECT_NAME_NOT_FOUND。
我三重检查了路径是否格式正确,我还确保 UNICODE_STRING 的 Length 和 MaximumLength 都是偶数而不是奇数,因为它会导致 NtCreateFile 抛出错误代码 0x33(更多信息:NtOpenFile 返回 STATUS_OBJECT_NAME_INVALID)。
我注意到,虽然在同一个文件夹中使用另一个 .png 文件可以正常工作,但我可以成功地获取文件的句柄,使用不同的标志是 FILE_DIRECTORY_FILE 而不是 FILE_NON_DIRECTORY_FILE。
这是代码:
c++ - 如何正确使用 MAXIMUM_ALLOWED?
我创建了一个小框架,为多个文件系统/API(即 Win32、Posix、NFS)提供统一的 API。所说的 API 有点类似于 Posix——要访问一个文件,您需要“打开”它,为预期目的(r
或w
)rw
提供提示。类似的东西open_file("/abc/log.txt", access::rw)
。
由于 Win32 的“声明性”性质,在这个框架中支持 Win32 API 让我很头疼——您应该预先知道您计划在给定句柄上执行哪些操作并将相关的操作传递dwDesiredAccess
给相关(Nt)CreateFile()
调用。r/w/rw
不幸的是,除了通用提示之外,框架不知道客户端将执行什么操作(即更改所有者、写入属性等) 。而且我不愿意让 Win32 概念泄漏到我的框架中(即我不喜欢dwDesiredAccess
在我的open_file()
.
这是我尝试过的:
1. MAXIMUM_ALLOWED
想法:使用 MAXIMUM_ALLOWED 打开相关句柄——我将尽我所能,如果缺少某些权利,相关操作(例如set_mime()
)将简单地以access denied
.
问题:
- 它不适用于只读文件或卷(
(Nt)CreateFile()
失败access denied
) - MSDN警告说,如果 FAT 卷上正在进行碎片整理 - 尝试以这种方式打开目录将失败
MAXIMUM_ALLOWED
一般来说,由于某种原因似乎不赞成使用
2. 必要时重新打开对象
想法:代表所有需要额外访问权限的操作(例如requires r/w/rw
)重新打开具有所需访问权限的对象。GENERIC_READ
GENERIC_WRITE
delete()
DELETE
问题:
- 重新打开对象并不便宜
- 通过第二个对象所做的更改可以被静默覆盖,例如:
set_mtime()
重新打开文件FILE_WRITE_ATTRIBUTES|SYNCHRONIZE
- 调用
NtSetInformationFile(... FileBasicInformation)
更新元数据并关闭句柄 - 后来原始句柄被关闭,它会导致数据刷新并静默覆盖
ModifiedTime
先前设置的set_mtime()
3.复制句柄而不是重新打开对象
想法:与上一节相同,但不是重新打开对象——复制原始句柄(要求新的访问权限):
问题:
- 每次我需要执行(非普通读/写)操作时复制(和关闭)文件句柄似乎过多且有些昂贵
DuplicateHandle()
文档警告(未提供任何详细信息)要求额外访问可能会失败。它在我检查过的所有用例中都运行良好(通常要求在打开的句柄上使用DELETE
/之类的东西),但显然 Win32 API 不提供任何保证:-/FILE_WRITE_ATTRIBUTES
GENERIC_READ
...否则方法似乎有效。
底线:
我正在寻找解决MAXIMUM_ALLOWED
问题的方法。(或者对替代方法的建议,也许?)
winapi - MmMapLockedPages 在 UserMode 中有什么作用?
编辑:在 StackOverflow 上浏览时,我发现ZwAllocateVirtualMemory并没有通过任何谷歌搜索或文档拖网产生,因为它在文档的“以前的版本”下 - 这是否意味着不推荐使用此功能?为什么它不在更新的文档中,在VirtualAlloc上使用它有什么缺点吗?
无论如何,这使我的问题相当过时,但我仍然想了解当 AccessMode = UserMode 时MmMapLockedPages 的真正作用。
OP:我在这个问题中读到内核驱动程序可以使用MmMapLockedPages将它在系统内存中分配的空间映射到用户内存中。从我在文档中可以找到的内容来看,没有任何其他(记录的)NT API 内核模式函数可以用来将内存“放入”用户空间虚拟内存。我想知道该映射是否允许用户对内存进行某种查看,但该内存仍在系统空间中,或者用户空间中是否存在完全可以访问的相同大小的“映射”内存块调用者,好像该内存已被malloc'd。
我对记忆系统的理解远非很好,所以请原谅任何术语的滥用!
winapi - 在 Windows 上与用户客户端进行自定义软件驱动程序通信
编辑:通过论坛上的另一个问题,我了解到 DeviceIoControl 可以是异步的,所以问题 4 现在只是问题 2
我发现,关于客户端用户模式应用程序如何直接与特定设备通信的大量 Windows 驱动程序文档几乎没有说明。我了解通常此类操作由 Win32 api 管理,但在特定设备或(我感兴趣的)软件驱动程序的情况下,我不知道有很多方法可以完成
文档说可以使用CreateFile、ReadFile、WriteFile 等将驱动程序作为“文件”“打开”,然后从/向它读/写,如果你愿意,可能是异步的。这听起来不错,但感觉这不是所有事情的最佳选择,也不是唯一的选择。DeviceIoControl可以具有特定的控制代码,并且您可以命令这样的驱动程序,但我在那里的文档中看不到任何异步功能。
在驱动程序文档中,很明显驱动程序必须为发送给它的调度调用编写其回调例程,但我不明白这些调度调用来自哪里,或者用户模式客户端如何直接与之交互。
使用 Valorant 的 Vanguard 作为示例软件驱动程序,我高度怀疑它只是从运行中的“文件”中读取/写入 - 它似乎太抽象而无法快速,或者对于复杂系统来说不够具体,正如你所能做的那样fileapi.h被读取和写入,没有任何真正的参数化 - 对吧?
我的问题是:
软件驱动程序是否必须为文档推荐的所有调度调用编写例程,即使它们与硬件无关?
除了R/W 文件 api和DeviceIoControl函数之外,还有其他技术可以与特定(软件)驱动程序进行通信吗?
当我们的软件驱动程序完全为目标用户应用程序定制时,是否有高效、“精益和平均”的解决方案,就像 Vanguard 一样?
(忽略)异步 R / W文件操作是否是以多线程异步方式完成此操作的唯一方法,其中客户端提交许多可能重叠的调用,或者DeviceIoControl是否可以利用线程和异步?
winapi - 是否可以在 Windows 上的用户模式应用程序中从内核模式驱动程序调用函数?
我在这里读到相反的情况是可能的,但是如何实现这样的事情呢?我希望有一种简单的方法,类似于从加载的 DLL 调用,但我的谷歌研究一无所获。我唯一的另一个想法是,可以传递一些预定义的常量,WriteFile
或者DeviceIoControl
驱动程序像 switch 语句一样解析以执行相关功能;是否存在更直接的方法?
winapi - NtQueryInformationFile(FileBothDirectoryInformation) 间歇性地报告某些子目录的非零大小 (EndOfFile/AllocationSize)
我有一个简单的实用程序,可以递归地扫描目录(使用NtQueryInformationFile(FileBothDirectoryInformation)
)并计算各种统计信息。它通常针对各种 SMB 共享(托管在 Win12 服务器上)执行。
特别是它计算total-bytes
(使用FILE_BOTH_DIR_INFORMATION::EndOfFile
字段)。
通常所有子目录都报告为大小为 0,但如果我在 5 秒内重新运行我的实用程序(自上次运行以来)——报告一些子目录的大小为 4096。如果我在重新运行实用程序之前数到 5——一切正常。这会导致不稳定的结果和不必要的警报。
所有受影响的目录似乎都有相同的共同点——每一个:
- 要么包含
Thumbs.db
文件 - 或者是包含
Thumbs.db
文件 的目录的父级- ...但并非总是如此——有时父目录大小是稳定的 0
问题:
- 为什么会发生这种情况,为什么 5 秒?
- 如何避免这种情况?我是否应该始终将 subdirs 视为“使用零字节”?
PS 同样的情况也发生在FILE_BOTH_DIR_INFORMATION::AllocationSize
字段上。
c - 如何从使用 NtCreateUserProcess 创建的进程中隐藏窗口?
我用 NtCreateUserProcess 创建了进程。但我想用隐藏窗口选项创建进程。
我在 RTL_USER_PROCESS_PARAMETERS 中找到了 ShowWindowFlags 参数,当我将 SW_HIDE 传递给它们时,它不起作用。
以下代码是当前用于 NtCreateUserProcess 函数参数的代码。
RTL_CREATE_USER_PROCESS:
PS_CREATE_INFO:
PS_ATTRIBUTE_LIST:
c++ - 使用 RtlCreateUserProcess 运行程序仅偶尔有效
免责声明:这个问题似乎被否决了,因为我应该使用普通的 Win32 API(CreateProcess、ShellExecute)。我知道这些 API,并且我知道RtlCreateUserProcess
不应该直接调用它们。然而,原生 API 是一个与安全性非常相关的话题,这就是我研究它的原因。
我正在尝试使用RtlCreateUserProcess
从 ntdll.dll 导出的函数在 Windows 上运行程序。我的代码可以运行 calc.exe,但是,在尝试运行 notepad.exe 后,我收到一条错误消息,内容为The ordinal 345 could not be located in dynamic link library "C:\Windows\SysWOW64\notepad.exe"
. 当试图运行其他程序时,它会显示各种类似的消息,总是与缺少一些序数或 DLL 有关。
我的示例代码如下所示:
不幸的是,没有太多关于使用这个功能的信息,所以我很感激任何关于如何正确使用这个功能的答案。
winapi - 如何修复 NtAllocateVirtualMemory 上的退出代码 0xc0000005 (STATUS_ACCESS_VIOLATION)?
我正在尝试使用ntdll.dll
. 我正在使用NtApi
和winapi
板条箱。
当我尝试分配时,我收到下一个错误:
退出代码:0xc0000005,STATUS_ACCESS_VIOLATION
我如何需要将指针发送到NtAllocateVirtualMemory()
?
为什么VirtualAllocEx()
有效?
我明白当我打电话时VirtualAllocEx()
,流程是kernel32.dll
-> ntdll.dll
,那么为什么当我将它发送到时这不起作用NtAllocateVirtualMemory()
?
main.rs
货运.toml
winapi - 有没有一种简单的方法来调用本机 NT API?
我正在使用直接接入 NT API(NtQueryDirectoryFile(..., FileBothDirectoryInformation)
等)的相当旧的代码。
允许用户模式应用程序调用这些函数的方法是众所周知的。在我的情况下,有人(很久以前)将相关的 DDK 声明(结构和函数)复制粘贴到单独的头文件中并手动生成ntdll.lib
以链接。
这有效,但是:
- 必须为每个新功能做这项手动工作并不理想
- 有可能引入一个微妙的错误(例如忘记强制正确的数据对齐)
- (相当大)
ntdll.lib
最终与源代码一起存储
我想知道使用更新的 SDK/DDK 是否有更好的方法?
笔记:
- 环境:VS2019 带
10.0.18362.0
Windows SDK - 我知道
winternl.h
——唉,它不包含我需要的所有功能