一、问题
- 进0环后,原来的寄存器存在哪里?
- 如何根据系统调用号(eax中存储)找到要执行的内核函数?
- 调用时参数是存储到3环的堆栈,如何传递给内核函数?
- 2种调用方式是如何返回到3环的?
在开始分析之前必须了解以下结构
二、TRAP_FRAME
_KTRAP_FRAME(每个线程一个) 用于进0环时保存环境
三、_KPCR
_KPCR(存储在CPU中)并且一个核一个
kd> dt _KPCR
nt!_KPCR
+0x000 NtTib : _NT_TIB
+0x01c SelfPcr : Ptr32 _KPCR
+0x020 Prcb : Ptr32 _KPRCB
+0x024 Irql : UChar
+0x028 IRR : Uint4B
+0x02c IrrActive : Uint4B
+0x030 IDR : Uint4B
+0x034 KdVersionBlock : Ptr32 Void
+0x038 IDT : Ptr32 _KIDTENTRY
+0x03c GDT : Ptr32 _KGDTENTRY
+0x040 TSS : Ptr32 _KTSS
+0x044 MajorVersion : Uint2B
+0x046 MinorVersion : Uint2B
+0x048 SetMember : Uint4B
+0x04c StallScaleFactor : Uint4B
+0x050 DebugActive : UChar
+0x051 Number : UChar
+0x052 Spare0 : UChar
+0x053 SecondLevelCacheAssociativity : UChar
+0x054 VdmAlert : Uint4B
+0x058 KernelReserved : [14] Uint4B
+0x090 SecondLevelCacheSize : Uint4B
+0x094 HalReserved : [16] Uint4B
+0x0d4 InterruptMode : Uint4B
+0x0d8 Spare1 : UChar
+0x0dc KernelReserved2 : [17] Uint4B
+0x120 PrcbData : _KPRCB
其中NtTib(第一个成员)和_KPRCB(最后一个成员)KPCR的子结构
kd> dt _NT_TIB
ntdll!_NT_TIB
+0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD //ExceptionList是指向异常处理链表(EXCEPTION_REGISTRATION结构)的一个指针。
+0x004 StackBase : Ptr32 Void
+0x008 StackLimit : Ptr32 Void
+0x00c SubSystemTib : Ptr32 Void
+0x010 FiberData : Ptr32 Void
+0x010 Version : Uint4B
+0x014 ArbitraryUserPointer : Ptr32 Void
+0x018 Self : Ptr32 _NT_TIB //结构体指针 指向自己
kd> dt _KPRCB
ntdll!_KPRCB
+0x000 MinorVersion : Uint2B
+0x002 MajorVersion : Uint2B
+0x004 CurrentThread : Ptr32 _KTHREAD //当前CPU所执行线程的_ETHREAD
+0x008 NextThread : Ptr32 _KTHREAD //下一个_ETHREAD
+0x00c IdleThread : Ptr32 _KTHREAD //当所以线程都执行完了CPU就可以执行这个
+0x010 Number : Char //CPU编号
+0x011 Reserved : Char
+0x012 BuildType : Uint2B
+0x014 SetMember : Uint4B
+0x018 CpuType : Char
+0x019 CpuID : Char
+0x01a CpuStep : Uint2B //CPU子版本号
+0x01c ProcessorState : _KPROCESSOR_STATE //CPU状态
+0x33c KernelReserved : [16] Uint4B
+0x37c HalReserved : [16] Uint4B
+0x3bc PrcbPad0 : [92] UChar
+0x418 LockQueue : [16] _KSPIN_LOCK_QUEUE
+0x498 PrcbPad1 : [8] UChar
+0x4a0 NpxThread : Ptr32 _KTHREAD //Npx浮点处理器 最后一次用过浮点的线程
+0x4a4 InterruptCount : Uint4B //中断计数 统计信息 没什么实际意义 自己调试用的
+0x4a8 KernelTime : Uint4B //统计信息
+0x4ac UserTime : Uint4B //统计信息
+0x4b0 DpcTime : Uint4B //统计信息
+0x4b4 DebugDpcTime : Uint4B //统计信息
+0x4b8 InterruptTime : Uint4B //统计信息
+0x4bc AdjustDpcThreshold : Uint4B
+0x4c0 PageColor : Uint4B
+0x4c4 SkipTick : Uint4B
+0x4c8 MultiThreadSetBusy : UChar
+0x4c9 Spare2 : [3] UChar
+0x4cc ParentNode : Ptr32 _KNODE
+0x4d0 MultiThreadProcessorSet : Uint4B
+0x4d4 MultiThreadSetMaster : Ptr32 _KPRCB
+0x4d8 ThreadStartCount : [2] Uint4B
+0x4e0 CcFastReadNoWait : Uint4B
+0x4e4 CcFastReadWait : Uint4B
+0x4e8 CcFastReadNotPossible : Uint4B
+0x4ec CcCopyReadNoWait : Uint4B
+0x4f0 CcCopyReadWait : Uint4B
+0x4f4 CcCopyReadNoWaitMiss : Uint4B
+0x4f8 KeAlignmentFixupCount : Uint4B
+0x4fc KeContextSwitches : Uint4B
+0x500 KeDcacheFlushCount : Uint4B
+0x504 KeExceptionDispatchCount : Uint4B
+0x508 KeFirstLevelTbFills : Uint4B
+0x50c KeFloatingEmulationCount : Uint4B
+0x510 KeIcacheFlushCount : Uint4B
+0x514 KeSecondLevelTbFills : Uint4B
+0x518 KeSystemCalls : Uint4B
+0x51c SpareCounter0 : [1] Uint4B
+0x520 PPLookasideList : [16] _PP_LOOKASIDE_LIST
+0x5a0 PPNPagedLookasideList : [32] _PP_LOOKASIDE_LIST
+0x6a0 PPPagedLookasideList : [32] _PP_LOOKASIDE_LIST
+0x7a0 PacketBarrier : Uint4B
+0x7a4 ReverseStall : Uint4B
+0x7a8 IpiFrame : Ptr32 Void
+0x7ac PrcbPad2 : [52] UChar
+0x7e0 CurrentPacket : [3] Ptr32 Void
+0x7ec TargetSet : Uint4B
+0x7f0 WorkerRoutine : Ptr32 void
+0x7f4 IpiFrozen : Uint4B
+0x7f8 PrcbPad3 : [40] UChar
+0x820 RequestSummary : Uint4B
+0x824 SignalDone : Ptr32 _KPRCB
+0x828 PrcbPad4 : [56] UChar
+0x860 DpcListHead : _LIST_ENTRY
+0x868 DpcStack : Ptr32 Void
+0x86c DpcCount : Uint4B
+0x870 DpcQueueDepth : Uint4B
+0x874 DpcRoutineActive : Uint4B
+0x878 DpcInterruptRequested : Uint4B
+0x87c DpcLastCount : Uint4B
+0x880 DpcRequestRate : Uint4B
+0x884 MaximumDpcQueueDepth : Uint4B
+0x888 MinimumDpcRate : Uint4B
+0x88c QuantumEnd : Uint4B
+0x890 PrcbPad5 : [16] UChar
+0x8a0 DpcLock : Uint4B
+0x8a4 PrcbPad6 : [28] UChar
+0x8c0 CallDpc : _KDPC
+0x8e0 ChainedInterruptList : Ptr32 Void
+0x8e4 LookasideIrpFloat : Int4B
+0x8e8 SpareFields0 : [6] Uint4B
+0x900 VendorString : [13] UChar
+0x90d InitialApicId : UChar
+0x90e LogicalProcessorsPerPhysicalProcessor : UChar//每个物理处理器有几个逻辑处理器
+0x910 MHz : Uint4B//频率
+0x914 FeatureBits : Uint4B
+0x918 UpdateSignature : _LARGE_INTEGER
+0x920 NpxSaveArea : _FX_SAVE_AREA
+0xb30 PowerState : _PROCESSOR_POWER_STATE
四、_ETHREAD
kd> dt _ETHREAD
nt!_ETHREAD
+0x000 Tcb : _KTHREAD
+0x1c0 CreateTime : _LARGE_INTEGER
+0x1c0 NestedFaultCount : Pos 0, 2 Bits
+0x1c0 ApcNeeded : Pos 2, 1 Bit
+0x1c8 ExitTime : _LARGE_INTEGER
+0x1c8 LpcReplyChain : _LIST_ENTRY
+0x1c8 KeyedWaitChain : _LIST_ENTRY
+0x1d0 ExitStatus : Int4B
+0x1d0 OfsChain : Ptr32 Void
+0x1d4 PostBlockList : _LIST_ENTRY
+0x1dc TerminationPort : Ptr32 _TERMINATION_PORT
+0x1dc ReaperLink : Ptr32 _ETHREAD
+0x1dc KeyedWaitValue : Ptr32 Void
+0x1e0 ActiveTimerListLock : Uint4B
+0x1e4 ActiveTimerListHead : _LIST_ENTRY
+0x1ec Cid : _CLIENT_ID
+0x1f4 LpcReplySemaphore : _KSEMAPHORE
+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
+0x208 LpcReplyMessage : Ptr32 Void
+0x208 LpcWaitingOnPort : Ptr32 Void
+0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION
+0x210 IrpList : _LIST_ENTRY
+0x218 TopLevelIrp : Uint4B
+0x21c DeviceToVerify : Ptr32 _DEVICE_OBJECT
+0x220 ThreadsProcess : Ptr32 _EPROCESS
+0x224 StartAddress : Ptr32 Void
+0x228 Win32StartAddress : Ptr32 Void
+0x228 LpcReceivedMessageId : Uint4B
+0x22c ThreadListEntry : _LIST_ENTRY
+0x234 RundownProtect : _EX_RUNDOWN_REF
+0x238 ThreadLock : _EX_PUSH_LOCK
+0x23c LpcReplyMessageId : Uint4B
+0x240 ReadClusterSize : Uint4B
+0x244 GrantedAccess : Uint4B
+0x248 CrossThreadFlags : Uint4B
+0x248 Terminated : Pos 0, 1 Bit
+0x248 DeadThread : Pos 1, 1 Bit
+0x248 HideFromDebugger : Pos 2, 1 Bit
+0x248 ActiveImpersonationInfo : Pos 3, 1 Bit
+0x248 SystemThread : Pos 4, 1 Bit
+0x248 HardErrorsAreDisabled : Pos 5, 1 Bit
+0x248 BreakOnTermination : Pos 6, 1 Bit
+0x248 SkipCreationMsg : Pos 7, 1 Bit
+0x248 SkipTerminationMsg : Pos 8, 1 Bit
+0x24c SameThreadPassiveFlags : Uint4B
+0x24c ActiveExWorker : Pos 0, 1 Bit
+0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit
+0x24c MemoryMaker : Pos 2, 1 Bit
+0x250 SameThreadApcFlags : Uint4B
+0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
+0x250 LpcExitThreadCalled : Pos 1, 1 Bit
+0x250 AddressSpaceOwner : Pos 2, 1 Bit
+0x254 ForwardClusterOnly : UChar
+0x255 DisablePageFaultClustering : UChar
+0x258 KernelStackReference : Uint4B
_ETHREAD的第一个成员结构如下
kd> dt _KTHREAD
nt!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 Teb : Ptr32 Void
+0x024 TlsArray : Ptr32 Void
+0x028 KernelStack : Ptr32 Void
+0x02c DebugActive : UChar
+0x02d State : UChar
+0x02e Alerted : [2] UChar
+0x030 Iopl : UChar
+0x031 NpxState : UChar
+0x032 Saturation : Char
+0x033 Priority : Char
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : Uint4B
+0x050 IdleSwapBlock : UChar
+0x051 VdmSafe : UChar
+0x052 Spare0 : [2] UChar
+0x054 WaitStatus : Int4B
+0x058 WaitIrql : UChar
+0x059 WaitMode : Char
+0x05a WaitNext : UChar
+0x05b WaitReason : UChar
+0x05c WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : Uint4B
+0x06c BasePriority : Char
+0x06d DecrementCount : UChar
+0x06e PriorityDecrement : Char
+0x06f Quantum : Char
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : Ptr32 Void
+0x0d4 KernelApcDisable : Uint4B
+0x0d8 UserAffinity : Uint4B
+0x0dc SystemAffinityActive : UChar
+0x0dd PowerState : UChar
+0x0de NpxIrql : UChar
+0x0df InitialNode : UChar
+0x0e0 ServiceTable : Ptr32 Void
+0x0e4 Queue : Ptr32 _KQUEUE
+0x0e8 ApcQueueLock : Uint4B
+0x0f0 Timer : _KTIMER
+0x118 QueueListEntry : _LIST_ENTRY
+0x120 SoftAffinity : Uint4B
+0x124 Affinity : Uint4B
+0x128 Preempted : UChar
+0x129 ProcessReadyQueue : UChar
+0x12a KernelStackResident : UChar
+0x12b NextProcessor : UChar
+0x12c CallbackStack : Ptr32 Void
+0x130 Win32Thread : Ptr32 Void
+0x134 TrapFrame : Ptr32 _KTRAP_FRAME
+0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x140 PreviousMode : Char
+0x141 EnableStackSwap : UChar
+0x142 LargeStack : UChar
+0x143 ResourceIndex : UChar
+0x144 KernelTime : Uint4B
+0x148 UserTime : Uint4B
+0x14c SavedApcState : _KAPC_STATE
+0x164 Alertable : UChar
+0x165 ApcStateIndex : UChar
+0x166 ApcQueueable : UChar
+0x167 AutoAlignment : UChar
+0x168 StackBase : Ptr32 Void
+0x16c SuspendApc : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry : _LIST_ENTRY
+0x1b8 FreezeCount : Char
+0x1b9 SuspendCount : Char
+0x1ba IdealProcessor : UChar
+0x1bb DisableBoost : UChar
五、从头开始逆向分析ReadProcessMemory
ReadProcessMemory
.text:7C8021D0 public ReadProcessMemory
.text:7C8021D0 ReadProcessMemory proc near ; CODE XREF: GetProcessVersion+2F12Fp
.text:7C8021D0 ; GetProcessVersion+2F14Ep ...
.text:7C8021D0
.text:7C8021D0 hProcess = dword ptr 8
.text:7C8021D0 lpBaseAddress = dword ptr 0Ch
.text:7C8021D0 lpBuffer = dword ptr 10h
.text:7C8021D0 nSize = dword ptr 14h
.text:7C8021D0 lpNumberOfBytesRead= dword ptr 18h
.text:7C8021D0
.text:7C8021D0 mov edi, edi
.text:7C8021D2 push ebp ; 压入ebp
.text:7C8021D3 mov ebp, esp ; 提升堆栈
.text:7C8021D5 lea eax, [ebp+nSize] ; 取nSize的值放到eax
.text:7C8021D8 push eax ; 压栈nSize的地址
.text:7C8021D9 push [ebp+nSize] ; 压栈nSize
.text:7C8021DC push [ebp+lpBuffer] ; 压栈lpBuffer
.text:7C8021DF push [ebp+lpBaseAddress] ; 压栈lpBaseAddress
.text:7C8021E2 push [ebp+hProcess] ; 压栈hProcess
.text:7C8021E5 call ds:NtReadVirtualMemory ; 调用NtReadVirtualMemory
.text:7C8021EB mov ecx, [ebp+lpNumberOfBytesRead] ; 取lpNumberOfBytesRead的值放到ecx
.text:7C8021EE test ecx, ecx ; 判断lpNumberOfBytesRead是否是0
.text:7C8021F0 jnz short loc_7C8021FD ; lpNumberOfBytesRead不为0则跳转
NtReadVirtualMemory
.text:7C92D9E0 ; NtReadVirtualMemory
.text:7C92D9E0
.text:7C92D9E0 public ZwReadVirtualMemory
.text:7C92D9E0 ZwReadVirtualMemory proc near ; CODE XREF: LdrFindCreateProcessManifest+1CCp
.text:7C92D9E0 ; LdrCreateOutOfProcessImage+7Cp ...
.text:7C92D9E0 mov eax, 0BAh ; eax存储调用号
.text:7C92D9E5 mov edx, 7FFE0300h ; edx存储SystemCall的地址
.text:7C92D9EA call dword ptr [edx] ; 调用SystemCall
.text:7C92D9EC retn 14h ; 5个参数 返回0x14
.text:7C92D9EC ZwReadVirtualMemory endp
7FFE0300h
kd> dt _KUSER_SHARED_DATA 0x7ffe0000
ntdll!_KUSER_SHARED_DATA
+0x000 TickCountLow : 0x1752
+0x004 TickCountMultiplier : 0xfa00000
+0x008 InterruptTime : _KSYSTEM_TIME
+0x014 SystemTime : _KSYSTEM_TIME
+0x020 TimeZoneBias : _KSYSTEM_TIME
+0x02c ImageNumberLow : 0x14c
+0x02e ImageNumberHigh : 0x14c
+0x030 NtSystemRoot : [260] 0x43
+0x238 MaxStackTraceDepth : 0
+0x23c CryptoExponent : 0
+0x240 TimeZoneId : 0
+0x244 Reserved2 : [8] 0
+0x264 NtProductType : 1 ( NtProductWinNt )
+0x268 ProductTypeIsValid : 0x1 ''
+0x26c NtMajorVersion : 5
+0x270 NtMinorVersion : 1
+0x274 ProcessorFeatures : [64] ""
+0x2b4 Reserved1 : 0x7ffeffff
+0x2b8 Reserved3 : 0x80000000
+0x2bc TimeSlip : 0
+0x2c0 AlternativeArchitecture : 0 ( StandardDesign )
+0x2c8 SystemExpirationDate : _LARGE_INTEGER 0x0
+0x2d0 SuiteMask : 0x110
+0x2d4 KdDebuggerEnabled : 0x3 ''
+0x2d5 NXSupportPolicy : 0x2 ''
+0x2d8 ActiveConsoleId : 0
+0x2dc DismountCount : 0
+0x2e0 ComPlusPackage : 0xffffffff
+0x2e4 LastSystemRITEventTickCount : 0x14215
+0x2e8 NumberOfPhysicalPages : 0x3ff6c
+0x2ec SafeBootMode : 0 ''
+0x2f0 TraceLogging : 0
+0x2f8 TestRetInstruction : 0xc3
+0x300 SystemCall : 0x7c92e4f0
+0x304 SystemCallReturn : 0x7c92e4f4
+0x308 SystemCallPad : [3] 0
+0x320 TickCount : _KSYSTEM_TIME
+0x320 TickCountQuad : 0
+0x330 Cookie : 0x62cd6fce
KiFastSystemCall
kd> u 0x7c92e4f0
ntdll!KiFastSystemCall:
7c92e4f0 8bd4 mov edx,esp
7c92e4f2 0f34 sysenter
ntdll!KiFastSystemCallRet:
7c92e4f4 c3 ret
7c92e4f5 8da42400000000 lea esp,[esp]
7c92e4fc 8d642400 lea esp,[esp]
ntdll!KiIntSystemCall:
7c92e500 8d542408 lea edx,[esp+8]
7c92e504 cd2e int 2Eh
7c92e506 c3
sysenter需要从msr寄存器中取出cs,esp,eip
kd> rdmsr 174 //cs
msr[174] = 00000000`00000008
kd> rdmsr 175 //esp
msr[175] = 00000000`f7a15000
kd> rdmsr 176 //eip
msr[176] = 00000000`8053e540 //EIP指向KiFastCallEntry的地址
kd> u 8053e540 L20
nt!KiFastCallEntry:
8053e540 b923000000 mov ecx,23h
8053e545 6a30 push 30h
8053e547 0fa1 pop fs
8053e549 8ed9 mov ds,cx
8053e54b 8ec1 mov es,cx
8053e54d 8b0d40f0dfff mov ecx,dword ptr ds:[0FFDFF040h]
8053e553 8b6104 mov esp,dword ptr [ecx+4]
8053e556 6a23 push 23h
8053e558 52 push edx
8053e559 9c pushfd
_KiFastCallEntry
.text:00466540 _KiFastCallEntry: ; DATA XREF: KiLoadFastSyscallMachineSpecificRegisters(x)+24o
.text:00466540 ; _KiTrap01+72o
.text:00466540 B9 23 00 00 00 mov ecx, 23h
.text:00466545 6A 30 push 30h
.text:00466547 0F A1 pop fs ; 重新加载fs, 0x30 = GDT[6] = ffc093df`f0000001
.text:00466547 ; Base:FFDFF000
.text:00466547 ;
.text:00466547 ; 加载后fs[0] = KPCR结构体首地址
.text:00466549 8E D9 mov ds, cx ; 加载ds,es --》 0x23 GDT[4] = 00cff300`0000ffff
.text:0046654B 8E C1 mov es, cx ; DPL:3 都是3环的数据段
.text:0046654D 8B 0D 40 F0 DF FF mov ecx, ds:0FFDFF040h ; KPCR+0x40 = TSS
.text:00466553 8B 61 04 mov esp, [ecx+4] ; ESP = TSS.ESP0
.text:00466556 6A 23 push 23h ; _KTRAP_FRAME.HardwareSegSs = 0x23
.text:00466558 52 push edx ; _KTRAP_FRAME.HardwareEsp = edx = 3环ESP
.text:00466559 9C pushf ; 这里IDA写错了,32位系统9C应该是pushfd,pushf只能压入eflags的低16位
.text:00466559 ; _KTRAP_FRAME.EFlags = EFlags
.text:00466559 ; ESP0: _KTRAP_FRAME.EFlags-4
.text:0046655A
.text:0046655A loc_46655A: ; CODE XREF: _KiSystemService+96j
.text:0046655A 6A 02 push 2 ; _KTRAP_FRAME.EFlags
.text:0046655A ; ESP0: _KTRAP_FRAME.EFlags-8
.text:0046655C 83 C2 08 add edx, 8 ; EDX = ESP + 8 指向参数
.text:0046655F 9D popf ; EFLAG = 0x02 清空0环所有标志位
.text:0046655F ; ESP0: _KTRAP_FRAME.EFlags-4
.text:00466560 80 4C 24 01 02 or [esp+0A4h+var_A3], 2 ; = or [esp+1],2 用来改EFlags
.text:00466565 6A 1B push 1Bh ; _KTRAP_FRAME.SegCs = 0x1B
.text:00466567 FF 35 04 03 DF FF push dword ptr ds:0FFDF0304h ; _KTRAP_FRAME.Eip = _KUSER_SHARED_DATA.SystemCallReturn
.text:0046656D 6A 00 push 0 ; _KTRAP_FRAME.ErrCode = 0
.text:0046656F 55 push ebp ; _KTRAP_FRAME.Ebp = ebp
.text:00466570 53 push ebx ; _KTRAP_FRAME.Ebx = ebx
.text:00466571 56 push esi ; _KTRAP_FRAME.Ebx = esi
.text:00466572 57 push edi ; _KTRAP_FRAME.Edi = edi
.text:00466573 8B 1D 1C F0 DF FF mov ebx, ds:0FFDFF01Ch ; ebx = _KPCR.SelfPcr(Ptr32 _KPCR)指向本结构体
.text:00466579 6A 3B push 3Bh ; _KTRAP_FRAME.SegFs = 0x3B
.text:0046657B 8B B3 24 01 00 00 mov esi, [ebx+124h] ; esi = _KPCR._KPRCB.CurrentThread
.text:00466581 FF 33 push dword ptr [ebx] ; _KTRAP_FRAME.ExceptionList = _KPCR.NtTib.ExceptionList
.text:00466583 C7 03 FF FF FF FF mov dword ptr [ebx], 0FFFFFFFFh ; _KPCR.NtTib.ExceptionList = -1
.text:00466589 8B 6E 18 mov ebp, [esi+18h] ; ebp = _KPCR._KPRCB.CurrentThread.InitialStack
.text:0046658C 6A 01 push 1 ; _KTRAP_FRAME.PreviousPreviousMode = 1 从3环来
.text:0046658E 83 EC 48 sub esp, 48h ; ESP指向_KTRAP_FRAME头
.text:00466591 81 ED 9C 02 00 00 sub ebp, 29Ch
.text:00466597 C6 86 40 01 00 00 01 mov byte ptr [esi+140h], 1 ; CurrentThread.PreviousMode = 1
.text:0046659E 3B EC cmp ebp, esp ; 不影响操作数的sub ebp,esp,并且影响EFLAGS
.text:004665A0 75 9A jnz short loc_46653C ; ebp和esp不相等就跳
.text:004665A2 83 65 2C 00 and dword ptr [ebp+2Ch], 0 ; _KTRAP_FRAME.Dr7 = 0
.text:004665A6 F6 46 2C FF test byte ptr [esi+2Ch], 0FFh
.text:004665AA 89 AE 34 01 00 00 mov [esi+134h], ebp ; CurrentThread.TrapFrame = EBP 指向_KTRAP_FRAME
.text:004665B0 0F 85 4A FE FF FF jnz Dr_FastCallDrSave ; 若DebugActive == 1,则跳转
.text:004665B6
.text:004665B6 loc_4665B6: ; CODE XREF: Dr_FastCallDrSave+10j
.text:004665B6 ; Dr_FastCallDrSave+7Cj
.text:004665B6 8B 5D 60 mov ebx, [ebp+60h] ; Ebx = _KTRAP_FRAME.Ebp
.text:004665B9 8B 7D 68 mov edi, [ebp+68h] ; Edi = _KTRAP_FRAME.Eip
.text:004665BC 89 55 0C mov [ebp+0Ch], edx ; _KTRAP_FRAME.DbgArgPointer = edx (3环esp)
.text:004665BF C7 45 08 00 0D DB BA mov dword ptr [ebp+8], 0BADB0D00h ; _KTRAP_FRAME.DbgArgMark = 0xBADB0D00
.text:004665C6 89 5D 00 mov [ebp+0], ebx ; _KTRAP_FRAME.DbgEbp = edx
.text:004665C9 89 7D 04 mov [ebp+4], edi ; _KTRAP_FRAME.DbgEip = edi
.text:004665CC FB sti ; 恢复中断
六、总结
- sysenter虽然从msr寄存器中取出cs,esp,eip,但取出的esp并没有使用,而是重新从TSS.EBP0中取,指向_KTRAP_FRAME的HardwareSegSS(后面几个8086的直接跳过)
- 三环的fs:[0]指向_TEB,零环的fs:[0]指向_KPCR
- PreviousMode = 1表示从3环来,PreviousMode = 0表示从0环来
or [esp+0A4h+var_A3], 2
指令的作用是将3环的EFlags的IF位置1,即启用中断- 文中的乱码全为
- 开头的问题,等下一篇文章再回答