4

我一直在研究 Windows 内部,最近才了解系统调用,我想知道是否可以像函数一样使用这些系统调用?我知道它们并不是真的要从外部访问。

例如:NtUserEmptyClipboard是Win32k.sys中的一个系统调用,它的地址是0x117f

如果我想像函数一样使用这个调用,我该怎么做?

4

4 回答 4

7

您想要做什么在很大程度上取决于您感兴趣的架构,但要知道的是,这ntdll.dll是每个系统调用的用户模式蹦床 - 即在一天结束时真正进行系统调用的唯一一个是 ntdll。

因此,让我们通过打开任何旧的 exe(我选择记事本)来反汇编 WinDbg 中的这些方法之一。首先,使用x ntdll!*查找ntdll导出的符号:

0:000> x ntdll!*
00007ff9`ed1aec20 ntdll!RtlpMuiRegCreateLanguageList (void)
00007ff9`ed1cf194 ntdll!EtwDeliverDataBlock (void)
00007ff9`ed20fed0 ntdll!shortsort_s (void)
00007ff9`ed22abbf ntdll!RtlUnicodeStringToOemString$fin$0 (void)
00007ff9`ed1e9af0 ntdll!LdrpAllocateDataTableEntry (void)
...

所以,让我们随机挑选一个,NtReadFile看起来很整洁。让我们拆解它:

0:000> uf ntdll!NtReadFile

ntdll!NtReadFile:
00007ff9`ed21abe0 4c8bd1          mov     r10,rcx
00007ff9`ed21abe3 b805000000      mov     eax,5
00007ff9`ed21abe8 0f05            syscall
00007ff9`ed21abea c3              ret

在这里,我们看到我们rcx把 syscall 号放入eax,然后调用syscall指令。每个系统调用都有一个由 Windows 任意分配的数字(即,这个数字是 ntdll 和内核之间的秘密握手,微软需要随时更改)

这些指令都不是“魔法”,您也可以直接在您的应用程序中执行它们(但当然没有实际理由这样做 - 只是为了好玩)

于 2014-06-19T05:19:09.640 回答
2

EmptyClipboard是所谓的“Win32 API”之一,NtUserEmptyClipboard是对应的“本机API”。

与 Linux 不同syscall(2),我们很少应该直接调用“原生 API”。我听说他们在ntdll.dll而不是win32k.sys。但是我们应该能够像在普通 DLL 中定义的普通函数一样调用它们。

于 2014-02-06T10:13:10.983 回答
0

本机 API 的主要部分是通过 ntdll.dll 中的普通函数导出的。您可以将此 dll 加载到您的进程中并像任何其他 API 函数一样调用这些函数。只要你有正确的函数原型和参数,调用就可以正常工作。他们在内部所做的是从用户模式转换到内核模式,然后他们使用系统服务描述符表 (SSDT) 中的偏移量在内核模式内存中查找函数的地址,然后调用该函数。有一个开源项目http://nativetest.codeplex.com/可以调用您可能引用的本机 api。

win32k.sys 中的函数没有暴露在 ntdll.dll 中。据我所知,它们没有暴露在任何地方。您列出的地址 - 我相信 - 实际上是 SSDT 的偏移量。如果你真的需要调用这个函数,你必须自己从用户模式转换到内核模式,把函数的所有参数和 SSDT 偏移量放在正确的位置。

正如其他人所建议的那样,我建议找到用户模式 ​​API 来帮助完成您想做的事情。FWIW,根据链接 /dump 输出,在 user32.dll 中,函数 EmptyClipboard 似乎直接转发到 NtUserEmptyClipboard。

1731   DF 0002018A EmptyClipboard = _NtUserEmptyClipboard@0
于 2014-06-19T04:52:13.487 回答
0

我强烈怀疑这0x117f是您要查找的地址。我怀疑这可能是您需要传递给GetProcAddress. 但我不确定,因为这些东西因 Windows 版本而异(这就是为什么普通人改用文档化函数的原因)

于 2014-02-06T09:54:10.937 回答