Windows x86-64 System Call Table (XP/2003/Vista/7/8/10/11 and Server)

33 walterbell 16 6/18/2025, 6:25:06 AM j00ru.vexillium.org ↗

Comments (16)

uncircle · 21m ago
I was wondering how the syscall mechanism works on Windows compared to Linux, and I found this delightful article: https://alice.climent-pommeret.red/posts/a-syscall-journey-i...

EDIT: also, wondering why the above article says SetMenu requires a syscall, which is not mentioned in OP, I found this: http://www.fengyuan.com/article/win32ksyscall.html - looks like many GUI operations on Windows NT/2000 were implemented in kernel. That can't have been very good for performance to constantly context-switch to draw a window, no?

ryao · 2h ago
I wonder how the DRM used in some video games that calls Windows system calls directly handles these changes. We know that some of it uses windows system calls directly because both Linux and Wine had to be patched to support it:

https://docs.kernel.org/admin-guide/syscall-user-dispatch.ht...

If I recall correctly, Jurassic World Evolution’s DRM is one of those that needed this to work.

e4m2 · 1h ago
There's a million and one ways to do it, here's just some of the ones I remember:

- https://www.mdsec.co.uk/2022/04/resolving-system-service-num...

- https://klezvirus.github.io/RedTeaming/AV_Evasion/NoSysWhisp...

- https://whiteknightlabs.com/2024/07/31/layeredsyscall-abusin...

Though I'm not sure which of these techniques, if any, would be most favored by a game DRM as I've never looked into it.

mike_hearn · 1h ago
The interesting thing about this is that some syscalls are versioned, even though the syscall interface is internal and private. There's NtLoadKey, NtLoadKey2, NtLoadKey3 and even NtLoadKeyEx.

This kind of versioning on public APIs, I understand, but syscalls are only meant to be invoked by ntdll. Why do they need more than one?

JdeBP · 31m ago
The consumers of the Native API are things like the original POSIX subsystem, the Interix POSIX subsystems, the OS/2 subsystem, the fourth POSIX subsystem used in WSLv1, NTVDMs, and of course the Win32 subsystem. Some of these were frozen long ago. The still live ones do not necessarily change in lockstep.

That said, for those particular API functions there is an interesting history that is, rather, about mitigating security holes:

* https://www.tiraniddo.dev/2020/05/silent-exploit-mitigations...

ethan_smith · 18m ago
The versioned syscalls exist to maintain binary compatibility with older applications while adding new functionality - when Microsoft needs to extend a syscall with new parameters, they create a new version rather than breaking existing internal callers that might be used by third-party applications reverse-engineering ntdll.
meibo · 55m ago
I can't tell you if that is actually the case here but most private Win32 API is actually public API since so many things are using it anyways. They never drew the line there and a lot of people go "well, they never changed this in the past, why would they now".
JdeBP · 39m ago
This is not the Win32 API, and Raymond Chen and others at Microsoft very much did draw a line when it came to people using the Native API of Windows NT.
mschuster91 · 12m ago
> This kind of versioning on public APIs, I understand, but syscalls are only meant to be invoked by ntdll. Why do they need more than one?

You got three common suffixes for function names in Windows. A and W relate to the encoding of the string parameters - A refers to the strings being encoded in plain ASCII, W to UTF-16.

And Ex, 2, 3, whatever - these refer to extensions with different parameters. Like, the "original" function may have had only two parameters or a tiny struct, but for more modern usecases they might have added a few parameters, expanded the struct or, even worse, re-arrange fields in the struct.

Now, of course they could have gone the Java/C++ path - basically, overload the function name with different parameters and have the "old" functions call whatever the most detailed constructor is and set default values for the newly expected parameters (or convert, if needed). But that doesn't work with C code at all, which is why the functions/syscalls have to have different names, and additionally the Java/C++ way imposes another function call with its related expenses while having dedicated functions/entrypoints allows for a tiny bit more performance, at the cost of sometimes significant code duplication.

And on top of all of that, MS has to take into account that there are a lot of third party code that doesn't use ntdll, user32 and god knows what else is supposed to be the actual API interface, but instead goes as close to the kernel as possible. Virus scanners, DRM solutions, anti-cheat measures, audit/compliance tools - these all hook themselves in everywhere they can. It's a routine source of issues with Windows updates...

trzeci · 1h ago
Dragon Sector's doing good!
cies · 1h ago
I count 506 on the Win list. 17 are no longer in use for recent version. So 489.

And 467 on the Linux list https://filippo.io/linux-syscall-table.

Ballpark the same number.

JdeBP · 1h ago
It's a fairly meaningless number.

Some operating systems have massive fan-in and fan-out on what is internally one single system call crossing the shell/kernel divide. Witness how much is done by sysctl() on the BSDs, for example. Whereas others will be more 1-to-1.

Then there's the fact that the Native API for Windows NT is structurally very different to the Linux API (as they are both different from, say, XNU). It's basically entirely coincidental that the numbers are even close, and there are no general conclusions that one can draw from such statistics.

Except, perhaps, a general but rather facile conclusion that these operating systems aren't running on 8-bit processor architectures. (-:

dooglius · 5m ago
I recall discussion (can't find now) that performance would be impacted for Linux if a syscall table lookup had to spill to a second page. That gives a limit of 512 64-bit pointers for syscalls we want to be high-performance, which may drive both OS's to start limiting new syscalls as they get close.

I don't know if there's more to this claim than just concern about an extra TLB entry though.

Surac · 2h ago
i do not see exactly the point in this empty table
ryao · 2h ago
The table is not empty. You need to pick the windows versions to show since the table would be so huge if it showed all of them that they are hidden by default. Click “show” in the table head.
senectus1 · 1h ago
click on the "show" at the headers...