From this question: How does the Windows Native API communicate with the kernel?

Here is an example of ZwClose(HANDLE Handle); system call in NTDLL.DLL in Windows 10 X86_64:

NtClose         proc near
mov     r10, rcx
mov     eax, 0Fh
test    byte ptr ds:7FFE0308h, 1
jnz     short loc_a
syscall
retn

loc_a:
int     2Eh
retn
NtClose         endp

My question is, why there is two different instruction syscall and int 0x2E in one subroutine? The 0xF value in EAX is the ID of ZwClose() and/or NtCose(). While debugging, code execution never goes to int 0x2E, syscall instruction is always executed and ds:7FFE0308h becomes zero.

up vote 6 down vote accepted

7FFE0308h is a pointer inside the KUSER_SHARED_DATA struct.

The pre-set address for access from kernel mode is defined symbolically in WDM.H as KI_USER_SHARED_DATA. It helps when debugging to remember that this is 0xFFDF0000 or 0xFFFFF780`00000000, respectively, in 32-bit and 64-bit Windows. Also defined is a convenient symbol, SharedUserData, which casts this constant address to a KUSER_SHARED_DATA pointer.

The read-only user-mode address for the shared data is 0x7FFE0000, both in 32-bit and 64-bit Windows.

Ref: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kuser_shared_data.htm

We see from that ref above that SharedUserData+0x308 is

0x0308 ULONG SystemCall

for Windows versions 1511 and higher.

So what does it do?

//
// On AMD64, this value is initialized to a nonzero value if the system
// operates with an altered view of the system service call mechanism.
//

ULONG SystemCall;

from recent ntddk.h

...not very helpful.

So what's the difference between int 2e and syscall in this context?

Ref: https://twitter.com/honorary_bot/status/966609444674162688

Might be a clue: 'int 2e' instruction can be trapped by vmx, syscall not

More info here: http://blog.amossys.fr/windows10_TH2_int2E_mystery.html


In the context of your question the ntdll.dll int 0x2e system calls probably have something to do with Virtualization Based Security. They have been present in Windows 10 since version 1511, after having been removed as a syscall method since Windows 8.

int 2Eh is used on 32bit OS to enter the kernel mode. On 64-bit, the same is obtained by using syscall. The check done on memory address 0x7ffe0300 is one of the ways to detect the bitness.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.