赞
踩
双机调试配置参看我的另一篇文章[原创]内核学习-双机调试环境搭建-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com,基于xp sp3系统
分析ReadProcessMemory了解系统调用
ida打开kernel32.dll(ReadProcessMemory函数在这个dll里)
参数压栈,call NTReadVirtualMemory,跳转至loc_7C802204
loc_7C802204调用了sub_7C8093FD
sub_7C8093FD内部调用了另一个函数RtlNtStatusToDosError
这个函数的作用是设置错误号
从sub_7C8093FD出来后,将eax清零,跳转到loc_7C8021F9
返回
当调用ReadProcessMemory失败时,返回结果为0,若NtReadVirtualMemory返回结果大于等于0,返回结果为1
ReadProcessMemory函数在kernel32.dll中只是调用了NtReadVirtualMemory,然后设置了返回值
在ntdll.dll中,Ntdll.dll
:大多数API都会通过这个DLL进入内核(0环)
.text:7C92D9E0 mov eax, 0BAh 系统调用号,对应操作系统内核中某个函数的编号
.text:7C92D9E5 mov edx, 7FFE0300h 函数地址,该函数决定了我们用什么方式进0环
.text:7C92D9EA call dword ptr [edx]
.text:7C92D9EC retn 14h
真正读取进程内存的函数在0环实现,我们所用的函数只是系统提供给我们的函数接口
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 : ntdll.dll!KiFastSystemCall()/ ntdll.dll!KiIntSystemCall() +0x304 SystemCallReturn : Uint4B +0x308 SystemCallPad : [3] Uint8B +0x320 TickCount : _KSYSTEM_TIME +0x320 TickCountQuad : Uint8B +0x330 Cookie : Uint4B
该数据结构是三环与零环的共享内存。
它们使用固定的地址值映射,_KUSER_SHARED_DATA结构区域在User层和Kernel层地址分别为:
User
:0x7ffe0000
Kernnel
:0xffdf0000
指向的是同一个物理页,但是在user层是只读,在kernel层是可读可写的。
此结构体由操作系统负责初始化,其偏移 0x300 处有一个 SystemCall 属性,是个函数指针。
sysenter 指令可用于特权级 3 的用户代码调用特权级 0 的系统内核代码,而 SYSEXIT 指令则用于特权级 0 的系统代码返回用户空间中。sysenter 指令可以在 3,2,1 这三个特权级别调用(Linux 中只用到了特权级 3),而 SYSEXIT 指令只能从特权级 0 调用。
描述:当操作系统初始化时,其会通过CPUID指令查询当前CPU是否支持快速调用,如果支持则这里填写通过快速调用进入零环,否则通过中断进入零环。
可以设置eax=1,执行cpuid指令,处理器的特征信息被放在ecx和edx寄存器中,其中edx包含了一个SEP位(第11位),该位指明了当前处理器知否支持sysenter/sysexit指令,SEP=1,说明当前CPU支持 sysenter / sysexit 指令。以此来自行查看前处理器是否支持sysenter/sysexit指令。
当CPU支持快读调用,SystemCall 指向 ntdll.dll!KiFastSystemCall()
当CPU不支持快速调用,SystemCall 指向 ntdll.dll!KiIntSystemCall()
所有的API进内核时,统一的中断号为0x2e
在执行KiIntSystemCall函数前,系统调用号已被写入EAX。
在IDT表中找到0x2E号门描述符:2E 右移3位(或者乘8)得到 0x170,加上 r idtr
获取的IDT基址,可以计算出 2E号中断对应的描述符:8053ee000008e481
门描述符:8053ee00
0008e481
指向地址:8053e481
CS:门描述符的段选择子部分(0008)(系统代码段)
查看eip
kd> u 8053e481
TSS描述符是 80008b04`200020ab,所以TSS的地址就是 80042000
所以ESP = 8054acf0, SS= 0010
小结:
- 固定中断号为0x2E
- CS/EIP由门描述符提供,ESP/SS由TSS提供
- 进入0环后执行的内核函数:NT!KiSystemService
进入0环后执行的内核函数NT!KiSystemService
mov edx,esp 三环栈顶值传给edx,此时eax中已经是系统调用号
sysenter指令 寄存器数据传递
sysenter 是从 MSR 寄存器里读取 CS,ESP,EIP(MSR寄存器里的值,则是系统启动时就已经填好)
相关的MSR寄存器的值
可以通过RDMSR/WRMST来进行读写(操作系统使用WRMST写该寄存器):
kd> rdmsr 174 //查看CS
kd> rdmsr 175 //查看ESP
kd> rdmsr 176 //查看EIP
查看eip所在地址的反汇编:
SS
= IA32_SYSENTER_CS + 8
3环进0环的两种方式,分别是中断门和快速调用,CPU支持快速调用,那么_KUSER_SHARED_DATA 结构体的 SystemCall 属性指向的函数是 KiFastSystemCall,执行 KiFastSystemCall,使用快速调用的方式进0环;如果不支持,那么SystemCall 指向的函数是KiIntSystemCall,执行 KiIntSystemCall,使用中断门的方式进0环。
KiFastSystemCall:KiIntSystemCall:
两个函数的共同点:
1.更改4个寄存器:SS CS EIP ESP,进入0环。
两个函数的区别:
1.快速调用不需要访问内存,而中断门需要读TSS和IDT表
2.int 0x2e 和 sysenter 指令进0环后,分别调用了两个函数 KiSystemService 和 KiFastCallEntry。
int 0x2e进0环后调用函数KiSystemService
_Trap_Frame 和0环栈密切相关。用户定义中断进0环,涉及提权时,CPU会把5个寄存器的值压入0环堆栈。EIP CS SS EFLAG ESP
线程切换时会修改TSS表,确保每个线程执行时,TSS里的ESP,SS都对应当前线程。
基本概念:
_KTRAP_FRAME
nt!_KTRAP_FRAME +0x000 DbgEbp : Uint4B +0x004 DbgEip : Uint4B +0x008 DbgArgMark : Uint4B +0x00c DbgArgPointer : Uint4B +0x010 TempSegCs : Uint4B +0x014 TempEsp : Uint4B +0x018 Dr0 : Uint4B +0x01c Dr1 : Uint4B +0x020 Dr2 : Uint4B +0x024 Dr3 : Uint4B +0x028 Dr6 : Uint4B +0x02c Dr7 : Uint4B +0x030 SegGs : Uint4B +0x034 SegEs : Uint4B +0x038 SegDs : Uint4B +0x03c Edx : Uint4B +0x040 Ecx : Uint4B +0x044 Eax : Uint4B +0x048 PreviousPreviousMode : Uint4B +0x04c ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD +0x050 SegFs : Uint4B +0x054 Edi : Uint4B +0x058 Esi : Uint4B +0x05c Ebx : Uint4B +0x060 Ebp : Uint4B +0x064 ErrCode : Uint4B +0x068 Eip : Uint4B +0x06c SegCs : Uint4B +0x070 EFlags : Uint4B +0x074 HardwareEsp : Uint4B +0x078 HardwareSegSs : Uint4B +0x07c V86Es : Uint4B +0x080 V86Ds : Uint4B +0x084 V86Fs : Uint4B +0x088 V86Gs : Uint4B
_KPCR
KPCR(Processor Control Region)是CPU控制区的意思,每个CPU都有一个KPCR结构。描述cpu状态
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
_NT_TIB
主要存储了SEH结构化异常链表和一个指向自己的指针。
nt!_NT_TIB
+0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+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
_KPRCB
nt!_KPRCB +0x000 MinorVersion : Uint2B +0x002 MajorVersion : Uint2B +0x004 CurrentThread : Ptr32 _KTHREAD +0x008 NextThread : Ptr32 _KTHREAD +0x00c IdleThread : Ptr32 _KTHREAD +0x010 Number : Char +0x011 Reserved : Char +0x012 BuildType : Uint2B +0x014 SetMember : Uint4B +0x018 CpuType : Char +0x019 CpuID : Char +0x01a CpuStep : Uint2B +0x01c ProcessorState : _KPROCESSOR_STATE +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 +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
存储的是线程相关的信息
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
_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 Spare0 : [3] 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
中断门进0环后,新的ESP指向偏移 0x068(Eip)处!!!
通过中断门的方式进入内核的时候,SS CS EIP ESP EFLAG的值已经存在 _KTRAP_FRAME中了。
.text:00407631 ; =============== S U B R O U T I N E ======================================= .text:00407631 .text:00407631 .text:00407631 _KiSystemService proc near ; CODE XREF: ZwAcceptConnectPort(x,x,x,x,x,x)+Cp .text:00407631 ; ZwAccessCheck(x,x,x,x,x,x,x,x)+Cp ... .text:00407631 .text:00407631 var_104 = dword ptr -104h .text:00407631 var_100 = dword ptr -100h .text:00407631 var_D0 = dword ptr -0D0h .text:00407631 var_CC = dword ptr -0CCh .text:00407631 var_C8 = dword ptr -0C8h .text:00407631 var_B0 = dword ptr -0B0h .text:00407631 var_AC = dword ptr -0ACh .text:00407631 var_A8 = dword ptr -0A8h .text:00407631 var_A3 = byte ptr -0A3h .text:00407631 var_73 = byte ptr -73h .text:00407631 arg_0 = dword ptr 4 .text:00407631 arg_64 = dword ptr 68h .text:00407631 arg_69 = byte ptr 6Dh .text:00407631 .text:00407631 push 0 ; _KTRAP_FRAME 0x064 ErrCode 错误码置为0; .text:00407633 push ebp ; 保存3环寄存器的值 .text:00407634 push ebx .text:00407635 push esi .text:00407636 push edi .text:00407637 push fs .text:00407639 mov ebx, 30h ;30h段选择子 0011 0000:索引为6,GDT表,运行级别为0环 .text:0040763E mov fs, bx ; 设置 fs 为 0x30 .text:0040763E ; 根据段选择子查GDT表得到对应的段描述符 ffc093df`f0000001 .text:0040763E ; fs.base = ffdff000,指向当前CPU的KPCR结构 .text:00407640 assume fs:nothing .text:00407640 push dword ptr ds:0FFDFF000h ; 保存旧的 ExceptionList,然后把新的清成-1,_KPCR+0X00->_NT_TIB->ExecotionList .text:00407646 mov dword ptr ds:0FFDFF000h, 0FFFFFFFFh .text:00407650 mov esi, ds:0FFDFF124h ; esi 指向 CurrentThread(0FFDFF124h:_KPCR+0x124=_KPCR+0x120+0x004->_KPRCB+0X004->CurrentThread) .text:00407656 push dword ptr [esi+140h] ; 保存 CurrentThread.PreviousMode .text:00407656 ; PreviousMode = 0 表示从0环调用过来 .text:00407656 ; PreviousMode != 0 表示从3环调用过来 .text:0040765C sub esp, 48h ; esp 指向 _KTRAP_FRAME .text:0040765F mov ebx, [esp+68h+arg_0];arg_0:4,[esp+6c]->Segcs(三环原来的cs的值) .text:00407663 and ebx, 1 ;0环最低位为0,3环最低位为1 .text:00407666 mov [esi+140h], bl ; 旧CS 与 1 的结果存入 PreviousMode .text:0040766C mov ebp, esp ; ebp 指向 _KTRAP_FRAME .text:0040766E mov ebx, [esi+134h] ;_ETHREAD+0x00+0x134->_KTHERAD+0x134-> TrapFrame .text:00407674 mov [ebp+3Ch], ebx ; [ebp+3Ch]:_KTRAP_FRAME.Edx , ebx是指向原来的TrapFrame .text:00407677 mov [esi+134h], ebp ;_ETHREAD+0x00+0x134->_KTHERAD+0x134-> TrapFrame 指向当前 _KTRAP_FRAME .text:0040767D cld ; df = 0 .text:0040767E mov ebx, [ebp+60h] ;[ebp+60h]:_KTRAP_FRAME.EBP(3环ebp) ,ebp 指向 _KTRAP_FRAME .text:00407681 mov edi, [ebp+68h] ;[ebp+68h]:_KTRAP_FRAME.EIP(3环eip) .text:00407684 mov [ebp+0Ch], edx ; _KTRAP_FRAME.DbgArgPointer = edx .text:00407684 ; 这一步是保存3环API参数指针 .text:00407687 mov dword ptr [ebp+8], 0BADB0D00h; _KTRAP_FRAME.DbgArgMark .text:0040768E mov [ebp+0], ebx ; _KTRAP_FRAME.DbgEbp = _KTRAP_FRAME.Ebp .text:00407691 mov [ebp+4], edi ; _KTRAP_FRAME.DbgEip = _KTRAP_FRAME.Eip .text:00407694 test byte ptr [esi+2Ch], 0FFh;_ETHREAD+0x00+0x2c->_KTHERAD+0x2c->DebugActive , .text:00407698 jnz Dr_kss_a ; 测试 CurrentThread.DebugActive .text:0040769E ; 如果处于调试状态(结果不为-1),跳转,跳转后的代码主要是保存调试相关的寄存器(DR0-DR7)到 _KTRAP_FRAME.DR0-_KTRAP_FRAME.DR7 .text:0040769E .text:0040769E loc_4664EF: ; CODE XREF: Dr_kss_a+10j .text:0040769E ; Dr_kss_a+7Cj .text:0040769E sti ; 关闭中断 .text:0040769F jmp loc_407781 .text:0040769F _KiSystemService endp
解析:00407631 --00407637:设置_KTRAP_FRAME结构体的下图中的成员
00407639 :fs.base = ffdff000,指向当前CPU的KPCR结构
在3环fs指向TEB结构,进入0环,fs指向KPCR结构体(通过段描述符),
00407650:esi 指向CurrentThread(当前cpu所执行线程的_ETHREAD)
00407656 : push dword ptr [esi+140h]:_ETHREAD+0x00+0x140->_KTHERAD+0x140-> PreviousMode(原来的先前模式)
00407640 压栈 ExceptionList->ExceptionList
00407656 压栈 PreviousMode->PreviousPreviousMode
0040765C:sub esp, 48h ;提升48h后 esp指向 _KTRAP_FRAME
00407698 jnz Dr_kss_a;保存调试相关的寄存器(DR0-DR7)到 _KTRAP_FRAME.DR0-_KTRAP_FRAME.DR7
.text:0040752C Dr_kss_a proc near ; CODE XREF: _KiSystemService+67↓j .text:0040752C test dword ptr [ebp+70h], 20000h .text:00407533 jnz short loc_407542 .text:00407535 test dword ptr [ebp+6Ch], 1 .text:0040753C jz loc_40769E .text:00407542 .text:00407542 loc_407542: ; CODE XREF: Dr_kss_a+7↑j .text:00407542 mov ebx, dr0 .text:00407545 mov ecx, dr1 .text:00407548 mov edi, dr2 .text:0040754B mov [ebp+18h], ebx .text:0040754E mov [ebp+1Ch], ecx .text:00407551 mov [ebp+20h], edi .text:00407554 mov ebx, dr3 .text:00407557 mov ecx, dr6 .text:0040755A mov edi, dr7 .text:0040755D mov [ebp+24h], ebx .text:00407560 mov [ebp+28h], ecx .text:00407563 xor ebx, ebx .text:00407565 mov [ebp+2Ch], edi .text:00407568 mov dr7, ebx .text:0040756B mov edi, large fs:20h .text:00407572 mov ebx, [edi+2F8h] .text:00407578 mov ecx, [edi+2FCh] .text:0040757E mov dr0, ebx .text:00407581 mov dr1, ecx .text:00407584 mov ebx, [edi+300h] .text:0040758A mov ecx, [edi+304h] .text:00407590 mov dr2, ebx .text:00407593 mov dr3, ecx .text:00407596 mov ebx, [edi+308h] .text:0040759C mov ecx, [edi+30Ch] .text:004075A2 mov dr6, ebx .text:004075A5 mov dr7, ecx .text:004075A8 jmp loc_40769E .text:004075A8 Dr_kss_a endp .text:004075A8 .text:004075A8 ; --------------------------------------------------------------------------- .text:004075AD align 10h .text:004075B0 .text:004075B0 ; =============== S U B R O U T I N E =======================================
0040769F jmp loc_407781;可以发现跳转到了_KiFastCallEntry函数内部(不同的方式保存寄存器,但是最后执行的代码是一样的),因为_KiIntSystemCall与KiFastSystemCall对于寄存器的处理不同,所以需要使用_KiFastCallEntry,KiSystemService两个函数填充_KTRAP_FRAME结构体。
.text:004076F0 ; =============== S U B R O U T I N E ======================================= .text:004076F0 .text:004076F0 .text:004076F0 _KiFastCallEntry proc near ; DATA XREF: _KiTrap01+6F↓o .text:004076F0 ; KiLoadFastSyscallMachineSpecificRegisters(x)+24↓o .text:004076F0 .text:004076F0 var_B = byte ptr -0Bh .text:004076F0 .text:004076F0 ; FUNCTION CHUNK AT .text:004076C8 SIZE 00000023 BYTES .text:004076F0 ; FUNCTION CHUNK AT .text:00407990 SIZE 00000014 BYTES .text:004076F0 .text:004076F0 mov ecx, 23h .text:004076F5 push 30h .text:004076F7 pop fs .text:004076F9 mov ds, ecx .text:004076FB mov es, ecx .text:004076FD mov ecx, ds:0FFDFF040h .text:00407703 mov esp, [ecx+4] .text:00407706 push 23h .text:00407708 push edx .text:00407709 pushf .text:0040770A .text:0040770A loc_40770A: ; CODE XREF: _KiFastCallEntry2+22↑j .text:0040770A push 2 .text:0040770C add edx, 8 .text:0040770F popf .text:00407710 or [esp+0Ch+var_B], 2 .text:00407715 push 1Bh .text:00407717 push dword ptr ds:0FFDF0304h .text:0040771D push 0 .text:0040771F push ebp .text:00407720 push ebx .text:00407721 push esi .text:00407722 push edi .text:00407723 mov ebx, ds:0FFDFF01Ch .text:00407729 push 3Bh .text:0040772B mov esi, [ebx+124h] .text:00407731 push dword ptr [ebx] .text:00407733 mov dword ptr [ebx], 0FFFFFFFFh .text:00407739 mov ebp, [esi+18h] .text:0040773C push 1 .text:0040773E sub esp, 48h .text:00407741 sub ebp, 29Ch .text:00407747 mov byte ptr [esi+140h], 1 .text:0040774E cmp ebp, esp .text:00407750 jnz loc_4076C8 .text:00407756 and dword ptr [ebp+2Ch], 0 .text:0040775A test byte ptr [esi+2Ch], 0FFh .text:0040775E mov [esi+134h], ebp .text:00407764 jnz Dr_FastCallDrSave .text:0040776A .text:0040776A loc_40776A: ; CODE XREF: Dr_FastCallDrSave+10↑j .text:0040776A ; Dr_FastCallDrSave+7C↑j .text:0040776A mov ebx, [ebp+60h] .text:0040776D mov edi, [ebp+68h] .text:00407770 mov [ebp+0Ch], edx .text:00407773 mov dword ptr [ebp+8], 0BADB0D00h .text:0040777A mov [ebp+0], ebx .text:0040777D mov [ebp+4], edi .text:00407780 sti .text:00407781 .text:00407781 loc_407781: ; CODE XREF: _KiBBTUnexpectedRange+18↑j .text:00407781 ; _KiSystemService+6E↑j .text:00407781 mov edi, eax .text:00407783 shr edi, 8 .text:00407786 and edi, 30h .text:00407789 mov ecx, edi .text:0040778B add edi, [esi+0E0h] .text:00407791 mov ebx, eax .text:00407793 and eax, 0FFFh .text:00407798 cmp eax, [edi+8] .text:0040779B jnb _KiBBTUnexpectedRange .text:004077A1 cmp ecx, 10h .text:004077A4 jnz short loc_4077C0 .text:004077A6 mov ecx, ds:0FFDFF018h .text:004077AC xor ebx, ebx .text:004077AE .text:004077AE loc_4077AE: ; DATA XREF: _KiTrap0E+110↓o .text:004077AE or ebx, [ecx+0F70h] .text:004077B4 jz short loc_4077C0 .text:004077B6 push edx .text:004077B7 push eax .text:004077B8 call ds:_KeGdiFlushUserBatch .text:004077BE pop eax .text:004077BF pop edx .text:004077C0 .text:004077C0 loc_4077C0: ; CODE XREF: _KiFastCallEntry+B4↑j .text:004077C0 ; _KiFastCallEntry+C4↑j .text:004077C0 inc dword ptr ds:0FFDFF638h .text:004077C6 mov esi, edx .text:004077C8 mov ebx, [edi+0Ch] .text:004077CB xor ecx, ecx .text:004077CD mov cl, [eax+ebx] .text:004077D0 mov edi, [edi] .text:004077D2 mov ebx, [edi+eax*4] .text:004077D5 sub esp, ecx .text:004077D7 shr ecx, 2 .text:004077DA mov edi, esp .text:004077DC cmp esi, ds:_MmUserProbeAddress .text:004077E2 jnb loc_407990 .text:004077E8 .text:004077E8 loc_4077E8: ; CODE XREF: _KiFastCallEntry+2A4↓j .text:004077E8 ; DATA XREF: _KiTrap0E+106↓o .text:004077E8 rep movsd .text:004077EA call ebx .text:004077EC .text:004077EC loc_4077EC: ; CODE XREF: _KiFastCallEntry+2AF↓j .text:004077EC ; DATA XREF: _KiTrap0E+126↓o ... .text:004077EC mov esp, ebp .text:004077EE .text:004077EE loc_4077EE: ; CODE XREF: _KiBBTUnexpectedRange+38↑j .text:004077EE ; _KiBBTUnexpectedRange+43↑j .text:004077EE mov ecx, ds:0FFDFF124h .text:004077F4 mov edx, [ebp+3Ch] .text:004077F7 mov [ecx+134h], edx .text:004077F7 _KiFastCallEntry endp .text:004077F7 .text:004077FD .text:004077FD ; =============== S U B R O U T I N E =======================================
sysenter 指令进0环后调用KiFastCallEntry
.text:00466540 _KiFastCallEntry: ; DATA XREF: KiLoadFastSyscallMachineSpecificRegisters(x)+24o .text:00466540 ; _KiTrap01+72o .text:00466540 mov ecx, 23h ;让ecx存储023h(三环描述符) .text:00466545 push 30h .text:00466547 pop fs ; fs = 0x30, ffc093df`f0000001, 0环数据段 .text:00466549 mov ds, ecx ; ds = 0x23, 00cff300`0000ffff, 3环数据段 .text:0046654B mov es, ecx ; es = 0x23(es辅助ds) .text:0046654D mov ecx, ds:0FFDFF040h;将TSS地址存储在ecx中 fs:[40h] .text:00466553 mov esp, [ecx+4] ; esp = _KPCR.TSS.Esp0,切换到0环堆栈 .text:00466556 push 23h ; _KTRAP_FRAME.HardwareSegSs = 0x23,保存旧ss .text:00466558 push edx ; _KTRAP_FRAME.HardwareEsp = edx, edx是3环栈顶,参数指针 .text:00466559 pushf ; _KTRAP_FRAME.EFlags = EFlags,保存3环eflag寄存器 .text:0046655A .text:0046655A loc_46655A: ; CODE XREF: _KiSystemService+96j .text:0046655A push 2 ;将0环eflag寄存器存储在栈中 .text:0046655C add edx, 8 ; edx 指向3环API参数 .text:0046655F popf ; EFlags = 0x02,即清空0环所有标志位 .text:0046655F ; 此时 esp 指向 EFlags .text:00466560 or [esp+0A4h+var_A3], 2 ; _KTRAP_FRAME.EFlags 即3环 EFlags 的 IF = 1 .text:00466565 push 1Bh ; _KTRAP_FRAME.SegCs = 0x1B, 3环代码段 .text:00466567 push dword ptr ds:0FFDF0304h ; _KTRAP_FRAME.Eip = _KUSER_SHARED_DATA.SystemCallReturn .text:0046656D push 0 ; _KTRAP_FRAME.ErrCode = 0 .text:0046656F push ebp ; _KTRAP_FRAME.Ebp = ebp .text:00466570 push ebx ; _KTRAP_FRAME.Ebx = ebx .text:00466571 push esi ; _KTRAP_FRAME.Esi = esi .text:00466572 push edi ; _KTRAP_FRAME.Edi = edi .text:00466573 mov ebx, ds:0FFDFF01Ch ; ebx = _KPCR.SelfPcr,即 ebx 指向 _KPCR .text:00466579 push 3Bh ; _KTRAP_FRAME.SegFs = 0x3B .text:0046657B mov esi, [ebx+124h] ; esi = _KPCR._KPRCB.CurrentThread .text:00466581 push dword ptr [ebx] ; _KTRAP_FRAME.ExceptionList = _KPCR.NtTib.ExceptionList .text:00466583 mov dword ptr [ebx], 0FFFFFFFFh ; _KPCR.NtTib.ExceptionList = -1 .text:00466589 mov ebp, [esi+18h] ; ebp = _KPCR._KPRCB.CurrentThread.InitialStack .text:0046658C push 1 ; _KTRAP_FRAME.PreviousPreviousMode = 1,表示从3环来 .text:0046658E sub esp, 48h ; esp 指向 _KTRAP_FRAME .text:00466591 sub ebp, 29Ch .text:00466597 mov byte ptr [esi+140h], 1 ; CurrentThread.PreviousMode = 1,表示从3环调用来 .text:0046659E cmp ebp, esp .text:004665A0 jnz short loc_46653C ; 如果 ebp != esp,跳转到异常处理 .text:004665A0 ; 正常情况下,esp,ebp 均指向 _KTRAP_FRAME .text:004665A2 and dword ptr [ebp+2Ch], 0 ; _KTRAP_FRAME.Dr7 = 0 .text:004665A6 test byte ptr [esi+2Ch], 0FFh .text:004665AA mov [esi+134h], ebp ; CurrentThread.TrapFrame = ebp,即指向当前 _KTRAP_FRAME .text:004665B0 jnz Dr_FastCallDrSave ; 如果DebugActive == 1(被调试),那么跳转到 Dr_FastCallDrSave .text:004665B0 ; Dr_FastCallDrSave 的功能是保存调试寄存器 .text:004665B6 .text:004665B6 loc_4665B6: ; CODE XREF: Dr_FastCallDrSave+10j .text:004665B6 ; Dr_FastCallDrSave+7Cj .text:004665B6 mov ebx, [ebp+60h] .text:004665B9 mov edi, [ebp+68h] .text:004665BC mov [ebp+0Ch], edx ; _KTRAP_FRAME.DbgArgPointer = edx, 保存3环参数指针 .text:004665BF mov dword ptr [ebp+8], 0BADB0D00h .text:004665C6 mov [ebp+0], ebx ; _KTRAP_FRAME.DbgEbp = _KTRAP_FRAME.Ebp .text:004665C9 mov [ebp+4], edi ; _KTRAP_FRAME.DbgEip = _KTRAP_FRAME.Eip .text:004665CC sti
原来的寄存器存储到了 _Trap_Frame 结构体里,3环API参数指针通过EDX传给0环
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。