我一直在研究Windows内部,最近刚刚了解到系统调用,我想知道是否有可能使用这些系统调用像函数? 我知道他们并不是真的想被外部访问。
例如: NtUserEmptyClipboard
是Win32k.sys中的一个系统调用,它的地址是0x117f
如果我想像function一样使用这个调用,我怎么能这样做呢?
NtUserEmptyClipboard
是所谓的“Win32 API”之一, NtUserEmptyClipboard
是一个相应的“本地API”。
与Linux syscall(2)
,我们很少直接调用“本机API”。 我听说他们在ntdll.dll
而不是win32k.sys
。 但是我们应该能够像正常的DLL中定义的普通函数一样调用它们。
我强烈怀疑0x117f
是你正在寻找的地址 。 我怀疑这可能是你需要传递给GetProcAddress
。 但我不知道,因为这些东西在Windows版本中有所不同(这就是为什么普通人使用文档化功能)
本地API的主要部分是通过ntdll.dll的正常功能导出的。 你可以加载这个DLL到你的进程中,并像其他API函数一样调用这些函数。 只要你有正确的函数原型和参数,调用就可以正常工作。 他们在内部执行的是从用户模式到内核模式的转换,然后在系统服务描述符表(SSDT)中使用一个偏移量来查找内核模式存储器中函数的地址,然后调用该函数。 有一个开源项目http://nativetest.codeplex.com/ ,可以调用您可能会引用的本机api。
win32k.sys中的函数不会在ntdll.dll中显示。 据我所知,他们没有暴露在任何地方。 您列出的地址 – 我相信 – 实际上是SSDT的偏移量。 如果你真的需要调用这个函数,你将不得不从usermode转换到kernelmode,把函数的所有参数和SSDT偏移量放在正确的位置。
正如其他人所建议的,我会建议找到usermode API来帮助完成你想要做的事情。 FWIW,在user32.dll中,根据链接/转储输出,EmptyClipboard函数显示为直接转发到NtUserEmptyClipboard。
1731 DF 0002018A EmptyClipboard = _NtUserEmptyClipboard@0
你想要做什么很大程度上取决于你感兴趣的架构,但要知道的是, ntdll.dll
是每个系统调用的用户模式蹦床 – 也就是唯一一个实际上在一天结束时使系统调用是ntdll。
所以,我们在WinDbg中反汇编这些方法之一,打开任何旧的exe(我选择了记事本)。 首先,使用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
看起来是neato。 我们来拆开它:
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
放在了rcx
,把系统调用号码放到eax
,然后调用syscall
指令。 每个系统调用都有一个由Windows任意指定的编号(即,这个编号是ntdll和内核之间的秘密握手,每当微软需要时都会改变)
这些指令都不是“魔术”,你也可以直接在你的应用程序中执行它们(但是当然没有实际的理由 – 只是为了方便)