Ximonite Posted October 30, 2020 Posted October 30, 2020 (edited) This information is specific to Windows 2000, but how the Native API Functions work and how to find the code for them is similar on other versions of Windows. Table with every Native API function: https://j00ru.vexillium.org/syscalls/nt/32/ Summary of what Native API Functions are and how they work: Native API Functions are functions stored in kernel-space but can be called by user-space applications. User-space applications will usually call forwarded exports in kernel32 that point to exports in ntdll. The code an export will eventually reach in ntdll will look like this: mov eax, ##h lea edx, [esp+4] int 2Eh retn 2Ch A software interrupt is used to transfer code execution to one of the addresses in the System Service Descriptor Table (also known as the KiServiceTable). The KiServiceTable is contained in ntoskrnl and the address of the KiServiceTable is copied to an exported value called KeServiceDescriptorTable. This is the relevant code: INIT:005535EE mov ds:KeServiceDescriptorTable, offset off_472228 This is the most reliable way to find the address of the KiServiceTable. The address may not be 472228, but the beginning of the KiServiceTable will always have this comment at the end of the first line: ; DATA XREF: sub_55351A+D4↓o Finding the code for a certain Native API Function: If the name of the Native API Function starts with "Nt", then the export in ntoskrnl probably points to the actual function code. Finding the function code may be as simple as that, but most of the time, it isn't. There are a few Nt exports that do not point to the actual function code. In this case, it will point to the same code execution transfer code found in ntdll, but inside of ntoskrnl. These functions will also have a matching function with the same name except for "Zw" instead of "Nt" at the beginning. The export with Zw at the beginning will point to the code that transfers code execution to an address in the KiServiceTable. If the function is one of the few Nt functions which have exports that don't point to the actual function code, or is only a Zw function, then finding the KiServiceTable will be required. To find the KiServiceTable, find the line of code above that copies the KiServiceTable to KeServiceDescriptorTable in ntoskrnl. The address 5535EE will most likely be where this code is. In the example code above, the KiServiceTable is located at address 472228. The KiServiceTable will look like this (only the first 16 lines shown here): off_472228 dd offset sub_4C5C12 ; DATA XREF: sub_55351A+D4↓o dd offset sub_4FA4EE dd offset sub_4FD362 dd offset sub_4FA518 dd offset sub_4FD398 dd offset sub_45BE3E dd offset sub_4FD3D8 dd offset sub_4FD418 dd offset NtAddAtom dd offset sub_4F63E6 dd offset NtAdjustPrivilegesToken dd offset sub_4E5660 dd offset sub_4E5616 dd offset NtAllocateLocallyUniqueId dd offset sub_44AB84 dd offset NtAllocateUuids The first address will correspond with value 00h in this code: mov eax, ##h lea edx, [esp+4] int 2Eh retn 2Ch The next will correspond with 01h, then 02h, etc. Edited November 21, 2020 by Ximonite Added table with all Native API functions 2
windows2 Posted October 30, 2020 Posted October 30, 2020 Thank you for all this information. Continue sir
win32 Posted October 31, 2020 Posted October 31, 2020 This still holds true for x64 Windows, where x86 and x64 versions of an ntdll function lead to one ntoskrnl function. So now I need to determine why the NtQueryInformationProcess implementation was good enough for x64 but not x86 K32* functions on Vista. So much to learn! And also user32/win32k should have a similar relationship for many of the former's functions, but what I've seen so far in win32k is ambiguous. There are offsets leading to tables like that, but they're scattered all over the place and not all of them lead to a function.
Mov AX, 0xDEAD Posted October 31, 2020 Posted October 31, 2020 17 hours ago, win32 said: And also user32/win32k should have a similar relationship for many of the former's functions, but what I've seen so far in win32k is ambiguous. There are offsets leading to tables like that, but they're scattered all over the place and not all of them lead to a function. win32k declare own ring3->ring0 service table for user32 and gdi32 see KeAddSystemServiceTable() inside win32k 1
win32 Posted November 1, 2020 Posted November 1, 2020 (edited) OK, on Windows Vista x64 it is w32pServiceTable. I was looking at the 8.1 x64 version earlier and checked w32pServiceTable but it seemed all odd to me there. Windows 2000 has no w32pServiceTable, though there is also a call to ntoskrnl.KeAddSystemServiceTable somewhere in its win32k. Right above this is push offset off_A0170400 ;the offset in 5.0.2195.7399 anyway. The user32/gdi32 stubs seem to follow a similar pattern to ntdll ones, but the values being copied to eax seem to start at 1000h instead of 0. On Windows 2000 it seems that gdi32 takes some priority over user32 in the table. Edited November 1, 2020 by win32
Ximonite Posted November 2, 2020 Author Posted November 2, 2020 Something I want to do is port some Windows XP Native API functions to Windows 2000. Since every entry in the KiServiceTable corresponds to a function, I wonder if the KiServiceTable can be expanded or if there's a different way to add these functions to ntdll, since the functions could call ntoskrnl functions (NtModifyBootEntry does).
win32 Posted November 5, 2020 Posted November 5, 2020 (edited) On 11/2/2020 at 2:29 PM, Ximonite said: I wonder if the KiServiceTable can be expanded or if there's a different way to add these functions to ntdll, since the functions could call ntoskrnl functions (NtModifyBootEntry does). How important/easily refactorable is the code immediately below the current end to the KiServiceTable? IDA spazzes out on my copies of win2k's ntoskrnl, but right below it on my win2k3 version is a snippet that does get lots of calls to it though. win32k in Vista seems to have a function that declares the end of its service table. But there isn't one on 2000 ntoskrnl so I think you can just move code around and add stuff to the table without harm (actually that link shows there is a ServiceLimit, but I think it would be easy to change and is not its own function seemingly). Alternatively, you could change the offset that is used by KiServiceTable and recreate it somewhere else where it isn't bound by code. But it would be a painstaking process. If you can simply move (in the assembly sense of the term, since it's a copy as opposed to a proper move - why is it mov and not cpy?) around an export table while leaving it intact, perhaps someone could write a program that can move a service/dispatch table. this is what I'll probably read at next breakfast: https://resources.infosecinstitute.com/topic/hooking-system-service-dispatch-table-ssdt/ Edited November 5, 2020 by win32
Ximonite Posted November 5, 2020 Author Posted November 5, 2020 (edited) On 11/5/2020 at 12:16 AM, win32 said: How important/easily refactorable is the code immediately below the current end to the KiServiceTable? IDA spazzes out on my copies of win2k's ntoskrnl, but right below it on my win2k3 version is a snippet that does get lots of calls to it though. Here is what I found right after the KiServiceTable: dword_472614 dd 0FBh ; DATA XREF: sub_55351A+FD↓r unk_472618 db 18h ; DATA XREF: sub_55351A+102↓o db 20h db 2Ch db 2Ch db 40h db 2Ch db 40h db 44h db 0Ch db 18h db 18h db 08h db 04h db 04h db 0Ch db 10h The dword value is the amount of entries in the KiServiceTable. The other values below (only the first 16 shown) are the amount of bytes popped from the stack at the end of each function. Edited November 9, 2020 by Ximonite Removed "+ 4" because it's not accurate.
win32 Posted November 5, 2020 Posted November 5, 2020 On Server 2003, they were moved to somewhere else in .text, decoupled from KiServiceTable, so I'd think those would be movable in 2000 as well. Also doesn't seem like a pain to refactor either, so you're lucky.
win32 Posted December 26, 2020 Posted December 26, 2020 (edited) I found this article very interesting to the subject of implementing system services, even if it's about the WRK: http://web.archive.org/web/20090707233000/http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=28 And also check these out: https://j00ru.vexillium.org/syscalls/nt/64/ https://j00ru.vexillium.org/syscalls/win32k/32/ https://j00ru.vexillium.org/syscalls/win32k/64/ Edited December 26, 2020 by win32
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now