一、本文大纲
- 系统调用的两种方式:中断门和快速调用
- _KUSER_SHARED_DATA 结构
- 使用 cpuid 指令判断当前CPU是否支持快速调用
- 3环进0环需要更改的4个寄存器
- 以 ReadProcessMemory 为例说明系统调用全过程
- 重写 ReadProcessMemory 和 WriteProcessMemory
- int 0x2e 和 sysenter 都做了什么工作?
二、中断门和快速调用
以我的理解,系统调用,即从调用操作系统提供的3环API开始,到进0环,再到返回结果到3环的全过程。
系统调用有中断调用和快速调用两种方式,中断调用是通过中断门进0环,此过程需要查IDT表和TSS表;
快速调用则是使用 sysenter 指令进0环,这种方式不需要查内存,而是直接从CPU的MSR寄存器中获取所需数据,所以称为快速调用
三、_KUSER_SHARED_DATA 结构
7ffe0000
ffdf0000
此结构体由操作系统负责初始化,其偏移 0x300 处有一个 SystemCall 属性,是个函数指针。
nt!_KUSER_SHARED_DATA+0x000 TickCountLow : Uint4B+0x004 TickCountMultiplier : Uint4B+0x008 InterruptTime : _KSYSTEM_TIME+0x014 SystemTime : _KSYSTEM_TIME+0x020 TimeZoneBias : _KSYSTEM_TIME+0x02c ImageNumberLow : Uint2B+0x02e ImageNumberHigh : Uint2B+0x030 NtSystemRoot : [260] Uint2B+0x238 MaxStackTraceDepth : Uint4B+0x23c CryptoExponent : Uint4B+0x240 TimeZoneId : Uint4B+0x244 Reserved2 : [8] Uint4B+0x264 NtProductType : _NT_PRODUCT_TYPE+0x268 ProductTypeIsValid : UChar+0x26c NtMajorVersion : Uint4B+0x270 NtMinorVersion : Uint4B+0x274 ProcessorFeatures : [64] UChar+0x2b4 Reserved1 : Uint4B+0x2b8 Reserved3 : Uint4B+0x2bc TimeSlip : Uint4B+0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE+0x2c8 SystemExpirationDate : _LARGE_INTEGER+0x2d0 SuiteMask : Uint4B+0x2d4 KdDebuggerEnabled : UChar+0x2d5 NXSupportPolicy : UChar+0x2d8 ActiveConsoleId : Uint4B+0x2dc DismountCount : Uint4B+0x2e0 ComPlusPackage : Uint4B+0x2e4 LastSystemRITEventTickCount : Uint4B+0x2e8 NumberOfPhysicalPages : Uint4B+0x2ec SafeBootMode : UChar+0x2f0 TraceLogging : Uint4B+0x2f8 TestRetInstruction : Uint8B+0x300 SystemCall : Uint4B+0x304 SystemCallReturn : Uint4B+0x308 SystemCallPad : [3] Uint8B+0x320 TickCount : _KSYSTEM_TIME+0x320 TickCountQuad : Uint8B+0x330 Cookie : Uint4B
操作系统启动时,通过CPUID指令,判断CPU是否支持快速调用,根据判断结果