从这个问题开始:Windows Native API如何与内核通信?
这是Windows 10 X86_64中NTDLL.DLL中ZwClose(HANDLE Handle);系统调用的示例:

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

我问题是,为什么在一个子例程中有两个不同的指令syscallint 0x2E? EAX中的0xF值是ZwClose()和/或NtCose()的ID。在调试时,代码执行永远不会转到int 0x2E,始终执行syscall指令,而ds:7FFE0308h变为零。

#1 楼

7FFE0308hKUSER_SHARED_DATA结构内部的指针。

从内核模式访问的预设地址在WDM.H中象征性地定义为KI_USER_SHARED_DATA。在调试时记住32位和64位Windows中分别为0xFFDF0000或0xFFFFF780`00000000会有所帮助。还定义了一个方便的符号SharedUserData,它将此常量地址强制转换为KUSER_SHARED_DATA指针。
在32位和64位Windows中,共享数据的只读用户模式地址均为0x7FFE0000。 br />
引用:https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kuser_shared_data.htm
我们从上面的引用中看到SharedUserData + 0x308是

0x0308 ULONG SystemCall

用于Windows 1511及更高版本。
那么它有什么用?
//
// 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;

来自最新的ntddk.h
...不是很有帮助。
那么在这种情况下int 2e和syscall有什么区别?
参考:https://twitter.com/honorary_bot/status/966609444674162688

可能是一个线索:'int 2e'指令可能会被vmx捕获,而不会被系统调用

更多信息,请参见:http://blog.amossys.fr/windows10_TH2_int2E_mystery.html

在您遇到问题时,ntdll.dll int 0x2e系统调用可能与Vir有关基于Tualization的安全性。从Windows 11版本1511开始,它们已在Windows 10中出现,从Windows 8开始已作为syscall方法删除。

#2 楼

在32位OS上使用int 2Eh进入内核模式。在64位上,可以通过使用syscall获得相同的结果。对内存地址0x7ffe0300进行的检查是检测位数的方法之一。