Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AltSyscalls by this technique does not apply to Windows 11 either 23H2 or 24H2 builds #18

Open
0xflux opened this issue Feb 11, 2025 · 2 comments

Comments

@0xflux
Copy link

0xflux commented Feb 11, 2025

Hey there.

First off - I love your work. I'm working on an EDR project of my own at the moment (in Rust) and I wanted to share some love to your work and blog post(s). Amazing stuff!

I just thought I would point out - I am doing some reversing of the kernel as my EDR is built around a W11 VM (2024); I have the ntoskrnl image for both Windows 11 23H2 and W11 24H2. My actual deployment target is 24H2 - and the Alt Syscalls technique does not work on either build by my research. Moreso to make you aware as you say it should work up to W11 23H2 in the blog and readme.

Windows 10 22H2

The disassembly is as follows (hopefully my annotations and variable renaming makes sense):

Step 1: Check for PreviousMode == KERNEL:

Image

Step 2: As per the original research, check arg4 == 1 and make a call to PspEnableAltSystemCallHandling.

Image

Windows 11 23H2 + 24H2

The disassembly between the two builds is slightly different, but overall the same - which is as follows:

Step 1: As before, previous mode is checked for Kernel/User mode:

Image

Step 2:

This time; the 4th parameter must match 0x14 (see the image 2 below), otherwise it returns STATUS_INFO_LENGTH_MISMATCH - this being the first difference to the 4th param being 1.

There is then some stuff in the middle I am yet to work out - it puts 4 bytes on the stack from what appears to be the 3rd field of a 20 byte structure (im guessing 8 x 8 x 4)

Image

Full match on 0x64:

Image

Re (3) in the above image - it makes a call to PspSyscallProviderOptIn, which eventually goes to PspLookupSyscallProviderByIdNoLock which as far as I can tell, looks to traverse a doubly-linked list of presumably some syscall provider structures; if the linked list points to itself, then it returns an error code STATUS_NOT_FOUND (The object was not found) - it seems as far as I can currently tell that the linked list there needs something inserted into it, with information about the Alt Syscall.

The function in question:

Image

Here is the memory with my debugger attached, with both (i presume) blink and flink pointing to the same node:

Image

It seems the Vergilius Project does not have the PspSyscallProviders struct documented :)

Final note

The label PspEnableAltSystemCallHandling does not exist in either Windows 11 build; and comparing the disassembly it seems Microsoft have deprecated that function in favour of something more complex. I did find some interesting new functions in the W11 builds that is not in the W10 build, PsRegisterSyscallProvider amongst others - but this looks to require some prerequisites around HyperGuard / PatchGuard which is taking me into an area I know little of. IIRC to use that function which does look to insert an item into the above mentioned linked list, VslVsmEnabled needs to be set to the correct bit.

I am actively researching this (as you can see from my terrible variable labels in the W11 decompilation) - and thought I would share the information for anyone else who is keen - but more so specifically for your repo & blog around asserting it should work for W11 builds, based on my research and deployment of similar code - it does not in fact work :)

Xacone added a commit to Xacone/xacone.github.io that referenced this issue Feb 12, 2025
Xacone added a commit that referenced this issue Feb 12, 2025
@Xacone
Copy link
Owner

Xacone commented Feb 12, 2025

Hi!

Thank you for your detailed description! Indeed there seems to have been quite a few changes on Windows 11. The difference you describe seems to be linked to NtSetInformationProcess, but I've noticed that it's not the only one. I had assumed that as long as PsRegisterAltSystemCallHandler was exported + the PsAltSystemCallHandlers array is present on Win11 22H2 & 23H2 then it should be fine.

At no time did I think that Microsoft would keep the array and the (exported) function that fills it without the array being solicited at any moment 🙆‍♂️.

xrefs to PsAltSystemCallHandlers on Win10 22H2 (KiSystemServiceUser -> PsAltSystemCallDispatch -> PsAltSystemCallHandlers[8]):

Image

xrefs to PsAltSystemCallHandlers on Win11 23H2:

Image

So mea culpa, and I'll try to look for more on this as soon as I have time.

I've changed the range in the blogpost/readme for the time being, until I figure it out more clearly.

I suggest you leave this issue open and discuss any findings there.

@0xflux
Copy link
Author

0xflux commented Feb 12, 2025

I'll keep researching this in my spare time, I'll update this issue to let you know if I make any progress, likewise if you could do the same that would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants