天道酬勤,学无止境

kernel-mode

NtCreateProcess 和 ZwCreateProcess 有什么区别?(What is the difference between NtCreateProcess and ZwCreateProcess?)

问题 NtCreateProcess和ZwCreateProcess有什么区别? 在 ntdll.dll 中, NtCreateProcess和ZwCreateProcess都指向完全相同的地址 回答1 在用户模式下,Nt 和 Zw API 组是相同的。 在内核模式下,它们是不同的。 Nt API 包含实际的实现。 Zw API 使用系统调用机制并确保它在内核模式下调用,并且如果参数包含用户模式地址,则无需检查参数。 否则,您可以在用户模式下使用带有内核参数的 API,这并不好。 所以它只是一个安全机制。 回答2 除了已经给出的答案(我不想鹦鹉学舌)之外,我认为最好的答案可以在 OSR Online 上找到:这里。 或者,您可以阅读有关 Native API 的书籍,例如 Gary Nebbett 的一本名为“Windows NT/2000 Native API Reference”的书籍,他在这个问题上花了一些篇幅,或者您可以使用 WinDbg(发音为“wind-bag” ) 你自己。

2022-01-15 08:03:41    分类:技术分享    windows   winapi   createprocess   kernel-mode   ntdll

What is the difference between NtCreateProcess and ZwCreateProcess?

What is the difference between NtCreateProcess and ZwCreateProcess? In ntdll.dll, both NtCreateProcess and ZwCreateProcess point to exactly the same address

2022-01-15 04:40:41    分类:问答    windows   winapi   createprocess   kernel-mode   ntdll

在 Windows 10 驱动程序中将内核空间虚拟地址映射到用户空间虚拟地址(Mapping Kernel-Space Virtual Address to User-Space Virtual Address in Windows 10 Driver)

问题 我正在 Windows 10(64 位)中编写内核模式驱动程序,其主要目的是从 DMA 读取,我想知道是否不是将内存块从内核空间复制到用户空间中分配的缓冲区,我可以以某种方式将地址暴露给用户空间(当然不是物理地址),并节省内存复制操作。 也许是这样的: 分配一块连续的物理内存(并将物理地址映射到内核空间中的虚拟地址)。 将内核空间中的虚拟地址映射到用户空间中的虚拟地址。 顺便说一句,由于只有一个内核空间,并且用户空间与系统中运行的进程一样多(对吗?),我必须使用某种句柄来调用进程,以便获得相应进程中的虚拟地址... 谢谢你的时间! 回答1 对于您的 (2),使用 AccessMode = UserMode 的 MmMapLockedPagesSpecifyCache() 怎么样? 请注意重要的警告,“例程返回在驱动程序运行的进程上下文中有效的用户地址”,因此您需要确保在执行时驱动程序正在用户模式应用程序的进程中运行映射,即在直接处理来自用户模式代码的调用的驱动程序代码中进行映射,例如DeviceIoControl()。 另请注意,要使用此功能,您需要提供描述物理页面的 MDL,并且必须锁定这些页面。

2022-01-14 22:34:22    分类:技术分享    c   windows-10   driver   memory-mapping   kernel-mode

Mapping Kernel-Space Virtual Address to User-Space Virtual Address in Windows 10 Driver

I'm writing a kernel mode driver in Windows 10 (64-bit), whose main purpose is to read from a DMA, and I was wondering if instead of copying blocks of memory from the kernel space to buffers allocated in the user space, I could somehow expose an address to the user space (of course not the physical address), and save on the memory copy operation. Perhaps something like this: Allocating a block of continuous physical memory (and mapping the physical address to a virtual address in the kernel space). Mapping the virtual address in the kernel space to a virtual address in the user space. By the

2022-01-11 12:02:00    分类:问答    c   windows-10   driver   memory-mapping   kernel-mode

从内核模式返回到用户模式(Returning from kernel mode to user mode)

问题 我对 Unix 内核中的模式切换的理解有点困惑。 我在这里给出我的理解并将其打开以供讨论/更正。 在从用户模式转换到内核模式时,处理器在每个进程用户堆栈和每个进程内核堆栈之间进行切换。 然后user-per-process堆栈段选择器和堆栈指针存储在内核堆栈中,然后eip指令指针(用户态返回地址)和其他硬件寄存器被压入内核堆栈 当内核必须返回到用户模式时, trapret代码将存储在内核堆栈中的所有值弹出回硬件寄存器。 但是当iret从内核堆栈中弹出 eip 时,应该执行的下一条指令是用户模式下的返回地址。 发生这种情况时不会完全弹出内核堆栈的其他值。 其余的值( %cs, %eflags, %esp, %ss )如何恢复? 内核堆栈中的用户堆栈指针是如何弹回 %esp 的? 回答1 iret恢复所有这些东西 iret指令非常复杂。 引用英特尔架构手册: 当从与被中断过程不同的特权级别执行中断或异常处理程序的返回时,处理器执行以下操作: 执行权限检查。 将 CS 和 EIP 寄存器恢复到中断或异常之前的值。 恢复 EFLAGS 寄存器。 将 SS 和 ESP 寄存器恢复到中断或异常之前的值,导致堆栈切换回被中断过程的堆栈。 恢复被中断程序的执行。

2021-12-24 17:14:34    分类:技术分享    operating-system   system-calls   context-switch   kernel-mode

Returning from kernel mode to user mode

I'm a bit confused about the understanding of a mode switch in Unix kernel. I give my understanding here and open it for discussion/correction. While transitioning from user mode to kernel mode, the processor makes a switch between the per-process-user-stack and the per-process-kernel-stack. Then the user-per-process stack segment selector and stack pointer is stored in the kernel stack and then the eip instruction pointer (return address at user mode) and other hardware registers are pushed on to the kernel stack When the kernel has to return to user mode, the trapret code pops all values

2021-12-11 15:47:16    分类:问答    operating-system   system-calls   context-switch   kernel-mode

在运行时从 linux 内核模块获取内核版本(Getting kernel version from linux kernel module at runtime)

问题 如何从 linux 内核模块代码(内核模式)中获取有关正在运行的内核版本的运行时信息? 回答1 按照惯例,Linux 内核模块加载机制不允许加载未针对正在运行的内核编译的模块,因此您所指的“运行内核”很可能在内核模块编译时就已经知道了。 为了检索版本字符串常量,旧版本要求您包含<linux/version.h> 、其他<linux/utsrelease.h>和较新的<generated/utsrelease.h> 。 如果您真的想在运行时获取更多信息,那么linux/utsname.h中的utsname()函数是最标准的运行时接口。 虚拟/proc/version procfs 节点的实现使用utsname()->release 。 如果要在编译时根据内核版本来调节代码,可以使用预处理器块,例如: #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) ... #else ... #endif 它允许您与主要/次要版本进行比较。 回答2 您一次只能安全地为任何一个内核版本构建一个模块。 这意味着在运行时从模块询问是多余的。 您可以在构建时找到这一点,通过查看最近内核中UTS_RELEASE的值,该值位于<generated/utsrelease.h>以及其他方法。 回答3 为什么我不能为任何版本构建内核模块? 因为内核模块 API

2021-12-07 17:57:33    分类:技术分享    linux-kernel   kernel-module   kernel-mode

如何在递归模式下使用 NtQueryDirectoryFile 检索完整的文件名?(How retrieve complete filename with NtQueryDirectoryFile in recursive mode?)

问题 我正在使用此代码递归遍历所有文件和目录。 现在我想知道如何提取完整的文件名(路径 + 文件名 + 扩展名)? 以下行(也出现在参考代码中)仅给出文件名 + 扩展名(没有目录名)。 DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName); 谢谢你。 回答1 如果我们不想简单地枚举文件夹/文件,而是想要全名,则需要编写适当的代码。 例如: #define ALLOCSIZE PAGE_SIZE // int nLevel, PSTR prefix for debug only void ntTraverse(POBJECT_ATTRIBUTES poa, int nLevel, PSTR prefix) { if (IoGetRemainingStackSize() < PAGE_SIZE) { DbgPrint("no stack!\n"); return ; } if (!nLevel) { DbgPrint("!nLevel\n"); return ; } HANDLE hFile; NTSTATUS status; IO_STATUS_BLOCK iosb; UNICODE_STRING ObjectName, *pObjectName = poa->ObjectName

2021-12-06 13:15:24    分类:技术分享    c++   windows   driver   kernel-mode   nt

为什么 call_usermodehelper 大部分时间都失败?(Why does call_usermodehelper fail most of the times?)

问题 从内核模块中,我试图使用 call_usermodehelper 函数来执行一个可执行文件 sha1,它将文件作为参数并将文件的 SHA1 哈希和写入另一个文件(命名输出)。 可执行文件完美运行。 int result=-1; name = "/home/file" char *hargv[] = {"/home/sha1", name,NULL }; char *henvp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; result = call_usermodehelper("/home/sha1", hargv, henvp, 1); 但大多数时候 call_usermodehelper 返回 -14 并且无法执行可执行文件。 可能是什么原因? 有时它可以工作,但是创建的输出文件被锁定(与直接运行 sha1 时发生的情况不同),我必须运行 chown 才能正确使用它。 如何防止这种情况发生? 无论如何在没有 call_usermodehelper 的情况下执行此操作? 回答1 call_usermodehelper的最后一个参数实际上是某种枚举: #define UMH_NO_WAIT 0 /* don't wait at all */ #define UMH_WAIT_EXEC 1 /*

2021-12-01 00:03:05    分类:技术分享    linux   linux-kernel   kernel-module   kernel-mode   user-mode-linux

Why does call_usermodehelper fail most of the times?

From a kernel module, I am trying to use call_usermodehelper function to execute an executable sha1 which takes a file as argument and writes the SHA1 hash sum of the file to another file (named output). The executable works perfectly. int result=-1; name = "/home/file" char *hargv[] = {"/home/sha1", name,NULL }; char *henvp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; result = call_usermodehelper("/home/sha1", hargv, henvp, 1); But most of the times call_usermodehelper returns -14 and fails to execute the executable. What could be the reason? Sometimes it works, but then the

2021-11-20 23:56:14    分类:问答    linux   linux-kernel   kernel-module   kernel-mode   user-mode-linux