Reputation: 2555
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.
For instance: NtUserEmptyClipboard
is a system call in Win32k.sys, and it's address is 0x117f
If I wanted to use this call like a function, how could I do so?
Upvotes: 6
Views: 12280
Reputation: 74654
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.
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:
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:
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)
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)
Upvotes: 12
Reputation: 1306
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.
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.
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.
1731 DF 0002018A EmptyClipboard = _NtUserEmptyClipboard@0
Upvotes: 0
Reputation: 8011
EmptyClipboard
is one of so-called "Win32 API" and NtUserEmptyClipboard
is a corresponding "native 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.
Upvotes: 2
Reputation: 179799
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)
Upvotes: 0