I have been doing research into Windows internals, and have just recently learned about system calls and I am wondering if it is possible to use these system calls like functions? I understand they aren't really meant to be accessed externally.
我一直在研究Windows内部,并且刚刚学习了系统调用,我想知道是否可以像函数一样使用这些系统调用?我知道他们并不是真正意义上的外部访问。
For instance: NtUserEmptyClipboard
is a system call in Win32k.sys, and it's address is 0x117f
例如:NtUserEmptyClipboard是Win32k.sys中的系统调用,它的地址是0x117f
If I wanted to use this call like a function, how could I do so?
如果我想像函数一样使用这个调用,我怎么能这样做?
4 个解决方案
#1
2
EmptyClipboard
is one of so-called "Win32 API" and NtUserEmptyClipboard
is a corresponding "native API".
EmptyClipboard是所谓的“Win32 API”之一,NtUserEmptyClipboard是相应的“本机API”。
Unlike Linux syscall(2)
, we are rarely supposed to directly call "native API". I heard they are in ntdll.dll
rather than win32k.sys
. But we should be able to invoke them just like normal functions defined in a normal DLL.
与Linux系统调用(2)不同,我们很少直接调用“本机API”。我听说他们在ntdll.dll而不是win32k.sys。但是我们应该能够像普通DLL中定义的普通函数一样调用它们。
- Is there any way to call the Windows Native API functions from the user mode?
有没有办法从用户模式调用Windows Native API函数?
#2
2
What you want to do depends heavily on the architecture you're interested, but the thing to know is, that ntdll.dll
is the user-mode trampoline for every syscall - i.e. the only one who actually makes syscalls at the end of the day is ntdll.
你想要做的事情在很大程度上取决于你感兴趣的架构,但要知道的是,ntdll.dll是每个系统调用的用户模式蹦床 - 也就是那天唯一一个真正开始系统调用的人是ntdll。
So, let's disassemble one of these methods in WinDbg, by opening up any old exe (I picked notepad). First, use x ntdll!*
to find the symbols exported by 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)
...
So, let's pick one at random, NtReadFile
looks neato. Let's disassemble it:
所以,让我们随机选择一个,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
Here, we see that we stuff away rcx
, put the syscall number into eax
, then call the syscall
instruction. Every syscall has a number that is assigned arbitrarily by Windows (i.e. this number is a secret handshake between ntdll and the kernel, and changes whenever Microsoft wants)
在这里,我们看到我们填写rcx,将系统调用号放入eax,然后调用syscall指令。每个系统调用都有一个由Windows任意分配的编号(即这个编号是ntdll和内核之间的秘密握手,并且只要微软想要改变)
None of these instructions are "magic", you could execute them in your app directly too (but there's no practical reason to do so, of course - just for funsies)
这些说明都不是“神奇的”,您也可以直接在您的应用中执行它们(但是没有实际的理由这样做,当然 - 只是为了测试)
#3
0
I strongly doubt that 0x117f
is the address you're looking for. I suspect it might be the value which you need to pass to GetProcAddress
. But I don't know for sure, since those things vary across Windows versions (that's why ordinary people use documented functions instead)
我强烈怀疑0x117f是你正在寻找的地址。我怀疑它可能是您需要传递给GetProcAddress的值。但我不确定,因为这些内容因Windows版本而异(这就是普通人使用文档化功能的原因)
#4
0
The main part of the native API is exported via normal functions from ntdll.dll. You can load this dll into your process and call these functions just like any other API functions. As long as you have the right function prototypes and parameters, the calls will work just fine. What they do internally is transition from usermode to kernelmode and then they use an offset into the system service descriptor table (SSDT) to find the address of the function in kernel mode memory, and then the function is called. There is an open source project http://nativetest.codeplex.com/ that makes calls to the native api that you might refer to.
本机API的主要部分是通过ntdll.dll的常规函数导出的。您可以将此dll加载到您的进程中,并像调用任何其他API函数一样调用这些函数。只要您拥有正确的函数原型和参数,调用就可以正常工作。他们在内部做的是从usermode转换到kernelmode,然后他们使用偏移到系统服务描述符表(SSDT)中来查找内核模式内存中函数的地址,然后调用该函数。有一个开源项目http://nativetest.codeplex.com/,它可以调用您可能引用的本机API。
The functions in win32k.sys are not exposed in ntdll.dll. As far as I can tell they are not exposed anywhere. The address you have listed - I believe - is actually an offset into the SSDT. If you really needed to call this function, you would have to make the transition from usermode to kernelmode yourself, putting all the parameters for the function and the SSDT offset into the right places.
win32k.sys中的函数未在ntdll.dll中公开。据我所知,他们没有暴露在任何地方。您列出的地址 - 我相信 - 实际上是SSDT的偏移量。如果你真的需要调用这个函数,你必须自己从usermode转换到kernelmode,把函数的所有参数和SSDT偏移放到正确的位置。
As others have recommended, I would suggest to find the usermode API to help accomplish what you want to do. FWIW, in user32.dll the function EmptyClipboard appears to forward directly to NtUserEmptyClipboard, according to the link /dump output.
正如其他人所推荐的那样,我建议找到usermode API来帮助完成你想要做的事情。 FWIW,在user32.dll中,根据链接/转储输出,函数EmptyClipboard似乎直接转发到NtUserEmptyClipboard。
1731 DF 0002018A EmptyClipboard = _NtUserEmptyClipboard@0
#1
2
EmptyClipboard
is one of so-called "Win32 API" and NtUserEmptyClipboard
is a corresponding "native API".
EmptyClipboard是所谓的“Win32 API”之一,NtUserEmptyClipboard是相应的“本机API”。
Unlike Linux syscall(2)
, we are rarely supposed to directly call "native API". I heard they are in ntdll.dll
rather than win32k.sys
. But we should be able to invoke them just like normal functions defined in a normal DLL.
与Linux系统调用(2)不同,我们很少直接调用“本机API”。我听说他们在ntdll.dll而不是win32k.sys。但是我们应该能够像普通DLL中定义的普通函数一样调用它们。
- Is there any way to call the Windows Native API functions from the user mode?
有没有办法从用户模式调用Windows Native API函数?
#2
2
What you want to do depends heavily on the architecture you're interested, but the thing to know is, that ntdll.dll
is the user-mode trampoline for every syscall - i.e. the only one who actually makes syscalls at the end of the day is ntdll.
你想要做的事情在很大程度上取决于你感兴趣的架构,但要知道的是,ntdll.dll是每个系统调用的用户模式蹦床 - 也就是那天唯一一个真正开始系统调用的人是ntdll。
So, let's disassemble one of these methods in WinDbg, by opening up any old exe (I picked notepad). First, use x ntdll!*
to find the symbols exported by 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)
...
So, let's pick one at random, NtReadFile
looks neato. Let's disassemble it:
所以,让我们随机选择一个,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
Here, we see that we stuff away rcx
, put the syscall number into eax
, then call the syscall
instruction. Every syscall has a number that is assigned arbitrarily by Windows (i.e. this number is a secret handshake between ntdll and the kernel, and changes whenever Microsoft wants)
在这里,我们看到我们填写rcx,将系统调用号放入eax,然后调用syscall指令。每个系统调用都有一个由Windows任意分配的编号(即这个编号是ntdll和内核之间的秘密握手,并且只要微软想要改变)
None of these instructions are "magic", you could execute them in your app directly too (but there's no practical reason to do so, of course - just for funsies)
这些说明都不是“神奇的”,您也可以直接在您的应用中执行它们(但是没有实际的理由这样做,当然 - 只是为了测试)
#3
0
I strongly doubt that 0x117f
is the address you're looking for. I suspect it might be the value which you need to pass to GetProcAddress
. But I don't know for sure, since those things vary across Windows versions (that's why ordinary people use documented functions instead)
我强烈怀疑0x117f是你正在寻找的地址。我怀疑它可能是您需要传递给GetProcAddress的值。但我不确定,因为这些内容因Windows版本而异(这就是普通人使用文档化功能的原因)
#4
0
The main part of the native API is exported via normal functions from ntdll.dll. You can load this dll into your process and call these functions just like any other API functions. As long as you have the right function prototypes and parameters, the calls will work just fine. What they do internally is transition from usermode to kernelmode and then they use an offset into the system service descriptor table (SSDT) to find the address of the function in kernel mode memory, and then the function is called. There is an open source project http://nativetest.codeplex.com/ that makes calls to the native api that you might refer to.
本机API的主要部分是通过ntdll.dll的常规函数导出的。您可以将此dll加载到您的进程中,并像调用任何其他API函数一样调用这些函数。只要您拥有正确的函数原型和参数,调用就可以正常工作。他们在内部做的是从usermode转换到kernelmode,然后他们使用偏移到系统服务描述符表(SSDT)中来查找内核模式内存中函数的地址,然后调用该函数。有一个开源项目http://nativetest.codeplex.com/,它可以调用您可能引用的本机API。
The functions in win32k.sys are not exposed in ntdll.dll. As far as I can tell they are not exposed anywhere. The address you have listed - I believe - is actually an offset into the SSDT. If you really needed to call this function, you would have to make the transition from usermode to kernelmode yourself, putting all the parameters for the function and the SSDT offset into the right places.
win32k.sys中的函数未在ntdll.dll中公开。据我所知,他们没有暴露在任何地方。您列出的地址 - 我相信 - 实际上是SSDT的偏移量。如果你真的需要调用这个函数,你必须自己从usermode转换到kernelmode,把函数的所有参数和SSDT偏移放到正确的位置。
As others have recommended, I would suggest to find the usermode API to help accomplish what you want to do. FWIW, in user32.dll the function EmptyClipboard appears to forward directly to NtUserEmptyClipboard, according to the link /dump output.
正如其他人所推荐的那样,我建议找到usermode API来帮助完成你想要做的事情。 FWIW,在user32.dll中,根据链接/转储输出,函数EmptyClipboard似乎直接转发到NtUserEmptyClipboard。
1731 DF 0002018A EmptyClipboard = _NtUserEmptyClipboard@0