SSDT简介
调用NTDLL下的系统服务存根函数时,会指定一个系统服务号,在内核下,会通过_KeServiceDescriptorTable查找到指定的系统服务例程。这个过程就是系统服务分发,系统服务分发主要通过SSDT表进行分发,系统可支持多个SSDT表,根据传入的系统服务号进行拆分,0-11位是号的索引,12位是表的索引号
typedef struct _KSERVICE_TABLE_DESCRIPTOR { //SDT结构
PULONG_PTR Base; //系统服务例程构成的地址数组
PULONG Count; //计数器数组,对应了相应的系统服务调用次数
ULONG Limit; //SDT中服务例程的个数
PUCHAR Number; //参数的字节数
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
举例来说,Windows 应用程序调用Windows API 函数CreateFile 来创建文件,此API 函数实际
上是CreateFileW,位于kernel32.dll 模块中。CreateFileW 函数又进一步调用ntdll.dll 中的
NtCreateFile 函数。Ntdll.dll 中的NtCreateFile 函数是一个存根函数,它只是简单地将创建
文件的请求转交给内核中的NtCreateFile 函数。为了做到这一点,它通过ntdll.dll 中的
KiIntSystemCall 或KiFastSystemCall 函数执行“int 2e”或sysenter 指令,以便切换到内核
模式下,
首先分析系统调用的第一种方式——KiFastCallEntry
KiFastCallEntry 逆向
KiFastCallEntry 是系统调用
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 arg_F6C= dword ptr 0F70h
.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 B9 23 00 00 00 mov ecx, 23h ; '#'
.text:004076F5 6A 30 push 30h ; '0'
.text:004076F7 0F A1 pop fs ; 修改FS 0x30
.text:004076F9 8E D9 mov ds, ecx
.text:004076FB 8E C1 mov es, ecx ; 修改ds,es寄存器 0x23
.text:004076FD 8B 0D 40 F0 DF FF mov ecx, ds:0FFDFF040h ; 获取tss
.text:00407703 8B 61 04 mov esp, [ecx+4] ; 取出R0esp
.text:00407706 6A 23 push 23h ; '#'
.text:00407708 52 push edx ; R3esp
.text:00407709 9C pushf ; 构建陷阱桢
.text:00407709
.text:0040770A
.text:0040770A loc_40770A: ; CODE XREF: _KiFastCallEntry2+22↑j
.text:0040770A 6A 02 push 2
.text:0040770C 83 C2 08 add edx, 8 ; 获取参数
.text:0040770F 9D popf ; eflags = 2
.text:00407710 80 4C 24 01 02 or byte ptr [esp+1], 2 ; (eflags ==esp +4)or 2
.text:00407710 ; 设置旧的eflags第二位为1
.text:00407715 6A 1B push 1Bh ; cs
.text:00407717 FF 35 04 03 DF FF push dword ptr ds:0FFDF0304h ; SystemCallReturn
.text:0040771D 6A 00 push 0 ; errcode
.text:0040771F 55 push ebp
.text:00407720 53 push ebx
.text:00407721 56 push esi
.text:00407722 57 push edi
.text:00407723 8B 1D 1C F0 DF FF mov ebx, ds:0FFDFF01Ch ; kpcr 0x1c == SelfPcr
.text:00407723 ; EBX==_KPCR
.text:00407729 6A 3B push 3Bh ; ';' ; SegFS
.text:0040772B 8B B3 24 01 00 00 mov esi, [ebx+_KPCR.PrcbData.CurrentThread] ; _KPRCB+4 CurrentThread
.text:00407731 FF 33 push [ebx+_KPCR.NtTib.ExceptionList] ; PUSH OldExceptionList
.text:00407733 C7 03 FF FF FF FF mov [ebx+_KPCR.NtTib.ExceptionList], 0FFFFFFFFh ; NewExceptionList == -1
.text:00407739 8B 6E 18 mov ebp, [esi+_KTHREAD.InitialStack] ; 记录栈的原始位置
.text:0040773C 6A 01 push 1 ; previouspreviousmode 先前模式
.text:0040773C ; 1表示以前是用户态
.text:0040773E 83 EC 48 sub esp, 48h ; 栈顶提升至陷阱桢头部
.text:00407741 81 ED 9C 02 00 00 sub ebp, 29Ch ; esp==ebp
.text:00407747 C6 86 40 01 00 00 01 mov [esi+_KTHREAD.PreviousMode], 1 ; 设置PreviousMode=1 先前模式 用户态
.text:0040774E 3B EC cmp ebp, esp ; 判断是否esp,ebp相等
.text:00407750 0F 85 72 FF FF FF jnz loc_4076C8 ; Invalid Opcode
.text:00407750 ; KiTrap06
.text:00407750
.text:00407756 83 65 2C 00 and [ebp+_KTRAP_FRAME.Dr7], 0 ; Dr7 = 0
.text:0040775A F6 46 2C FF test [esi+_KTHREAD.DebugActive], 0FFh ; 判断是否是调试状态
.text:0040775A ; 如果这里是调试状态,则DebugActive不等于0
.text:0040775E 89 AE 34 01 00 00 mov [esi+_KTHREAD.TrapFrame], ebp ; 更新当前线程的陷阱桢
.text:00407764 0F 85 46 FE FF FF jnz Dr_FastCallDrSave
.text:00407764
.text:0040776A
.text:0040776A loc_40776A: ; CODE XREF: Dr_FastCallDrSave+10↑j
.text:0040776A ; Dr_FastCallDrSave+7C↑j
.text:0040776A 8B 5D 60 mov ebx, [ebp+_KTRAP_FRAME._Ebp] ; ebx=ebp
.text:0040776D 8B 7D 68 mov edi, [ebp+_KTRAP_FRAME._Eip] ; edi=eip
.text:00407770 89 55 0C mov [ebp+_KTRAP_FRAME.DbgArgPointer], edx ; 参数放入DbgArgPointer
.text:00407773 C7 45 08 00 0D DB BA mov [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h
.text:0040777A 89 5D 00 mov [ebp+_KTRAP_FRAME.DbgEbp], ebx ; DbgEbp=ebp
.text:0040777D 89 7D 04 mov [ebp+_KTRAP_FRAME.DbgEip], edi ; DbgEip=eip
.text:00407780 FB sti ;
.text:00407780 ; SDT表,低十二位是系统服务索引,12-13是表的索引
.text:00407780
.text:00407781
.text:00407781 loc_407781: ; CODE XREF: _KiBBTUnexpectedRange+18↑j
.text:00407781 ; _KiSystemService+6E↑j
.text:00407781 8B F8 mov edi, eax ; 索引号
.text:00407783 C1 EF 08 shr edi, 8 ; 获取表位
.text:00407786 83 E7 30 and edi, 30h ; 判断是第几个表
.text:00407789 8B CF mov ecx, edi ; ecx 获取表的偏移
.text:0040778B 03 BE E0 00 00 00 add edi, [esi+_KTHREAD.ServiceTable] ; edi = 服务表
.text:00407791 8B D8 mov ebx, eax ; 索引号
.text:00407793 25 FF 0F 00 00 and eax, 0FFFh ; 获取后12位 服务号
.text:00407793 ; sdt结构8-16位为个数
.text:00407798 3B 47 08 cmp eax, [edi+KSERVICE_TABLE_DESCRIPTOR.Limit] ; 和个数进行判断
.text:0040779B 0F 83 41 FD FF FF jnb _KiBBTUnexpectedRange
.text:0040779B
.text:004077A1 83 F9 10 cmp ecx, 10h ; 判断是否是UI表
.text:004077A4 75 1A jnz short loc_4077C0 ; 不是GUI则跳转
.text:004077A4
.text:004077A6 8B 0D 18 F0 DF FF mov ecx, ds:0FFDFF018h
.text:004077AC 33 DB xor ebx, ebx ; 清空ebx
.text:004077AC
.text:004077AE
.text:004077AE loc_4077AE: ; DATA XREF: _KiTrap0E+110↓o
.text:004077AE 0B 99 70 0F 00 00 or ebx, [ecx+(_KPCR.PrcbData.ProcessorState.ContextFrame.FloatSave.DataSelector+0E00h)]
.text:004077B4 74 0A jz short loc_4077C0 ; _KPCRB->0x518 KeSystemCall增加1
.text:004077B4
.text:004077B6 52 push edx
.text:004077B7 50 push eax
.text:004077B8 FF 15 64 32 48 00 call ds:_KeGdiFlushUserBatch
.text:004077B8
.text:004077BE 58 pop eax
.text:004077BF 5A pop edx
.text:004077BF
.text:004077C0
.text:004077C0 loc_4077C0: ; CODE XREF: _KiFastCallEntry+B4↑j
.text:004077C0 ; _KiFastCallEntry+C4↑j
.text:004077C0 FF 05 38 F6 DF FF inc dword ptr ds:0FFDFF638h ; _KPCRB->0x518 KeSystemCall增加1
.text:004077C6 8B F2 mov esi, edx ; R3esp
.text:004077C8 8B 5F 0C mov ebx, [edi+KSERVICE_TABLE_DESCRIPTOR.Number] ; 每个系统服务参数字节数表的基地址
.text:004077CB 33 C9 xor ecx, ecx ; ecx=0
.text:004077CD 8A 0C 18 mov cl, [eax+ebx] ; 获取参数的字节数
.text:004077D0 8B 3F mov edi, [edi] ; 取出函数表
.text:004077D2 8B 1C 87 mov ebx, [edi+eax*4] ; 取出使用的函数地址
.text:004077D5 2B E1 sub esp, ecx ; 提升堆栈需要使用的字节数
.text:004077D7 C1 E9 02 shr ecx, 2 ; 因为每个参数是4字节,计算个数
.text:004077DA 8B FC mov edi, esp
.text:004077DC 3B 35 D4 8B 48 00 cmp esi, ds:_MmUserProbeAddress ; 判断esp是否是正常R3地址
.text:004077DC ; _MmUserProbeAddress是一个全局变量,是用户程序能访问地址的最大范围
.text:004077E2 0F 83 A8 01 00 00 jnb loc_407990 ; 访问冲突错误
.text:004077E2
.text:004077E8
.text:004077E8 loc_4077E8: ; CODE XREF: _KiFastCallEntry+2A4↓j
.text:004077E8 ; DATA XREF: _KiTrap0E+106↓o
.text:004077E8 F3 A5 rep movsd ; 获取参数
.text:004077EA FF D3 call ebx ; 调用函数
Dr_FastCallDrSave
.text:004075C6 loc_4075C6: ; CODE XREF: Dr_FastCallDrSave+7↑j
.text:004075C6 0F 21 C3 mov ebx, dr0
.text:004075C9 0F 21 C9 mov ecx, dr1
.text:004075CC 0F 21 D7 mov edi, dr2
.text:004075CF 89 5D 18 mov [ebp+_KTRAP_FRAME.Dr0], ebx
.text:004075D2 89 4D 1C mov [ebp+_KTRAP_FRAME.Dr1], ecx
.text:004075D5 89 7D 20 mov [ebp+_KTRAP_FRAME.Dr2], edi
.text:004075D8 0F 21 DB mov ebx, dr3
.text:004075DB 0F 21 F1 mov ecx, dr6
.text:004075DE 0F 21 FF mov edi, dr7
.text:004075E1 89 5D 24 mov [ebp+_KTRAP_FRAME.Dr3], ebx
.text:004075E4 89 4D 28 mov [ebp+_KTRAP_FRAME.Dr6], ecx
.text:004075E7 33 DB xor ebx, ebx
.text:004075E9 89 7D 2C mov [ebp+_KTRAP_FRAME.Dr7], edi
.text:004075EC 0F 23 FB mov dr7, ebx
.text:004075EF 64 8B 3D 20 00 00 00 mov edi, large fs:20h ; NT Process ID
.text:004075F6 8B 9F F8 02 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr0]
.text:004075FC 8B 8F FC 02 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr1]
.text:00407602 0F 23 C3 mov dr0, ebx
.text:00407605 0F 23 C9 mov dr1, ecx
.text:00407608 8B 9F 00 03 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr2]
.text:0040760E 8B 8F 04 03 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr3]
.text:00407614 0F 23 D3 mov dr2, ebx
.text:00407617 0F 23 D9 mov dr3, ecx
.text:0040761A 8B 9F 08 03 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr6]
.text:00407620 8B 8F 0C 03 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr7]
.text:00407626 0F 23 F3 mov dr6, ebx
.text:00407629 0F 23 F9 mov dr7, ecx
.text:0040762C E9 39 01 00 00 jmp loc_40776A ; ebx=ebp
.text:0040762C
.text:0040762C Dr_FastCallDrSave endp
接下来分析系统调用的第二种方式int 2e
因为通过int 2e中断门的方式进入内核
系统会让KiSystemService接管,并进行处理
_KiSystemService 逆向
.text:00407631 _KiSystemService proc near ; CODE XREF: ZwAcceptConnectPort(x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheck(x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckAndAuditAlarm(x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckByType(x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckByTypeAndAuditAlarm(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckByTypeResultList(x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckByTypeResultListAndAuditAlarm(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAccessCheckByTypeResultListAndAuditAlarmByHandle(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAddAtom(x,x,x)+C↑p
.text:00407631 ; ZwAddBootEntry(x,x)+C↑p
.text:00407631 ; ZwAdjustGroupsToken(x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAdjustPrivilegesToken(x,x,x,x,x,x)+C↑p
.text:00407631 ; ZwAlertResumeThread(x,x)+C↑p
.text:00407631 ; ZwAlertThread(x)+C↑p
.text:00407631 ; ZwAllocateLocallyUniqueId(x)+C↑p ...
.text:00407631
.text:00407631 arg_0= dword ptr 4
.text:00407631
.text:00407631 6A 00 push 0
.text:00407633 55 push ebp ; 构建陷阱桢
.text:00407634 53 push ebx
.text:00407635 56 push esi
.text:00407636 57 push edi
.text:00407637 0F A0 push fs
.text:00407639 BB 30 00 00 00 mov ebx, 30h ; '0' ; 修改fs为30
.text:0040763E 8E E3 mov fs, ebx
.text:00407640 FF 35 00 F0 DF FF push dword ptr ds:0FFDFF000h ; fs:[0]
.text:00407646 C7 05 00 F0 DF FF FF FF FF FF mov dword ptr ds:0FFDFF000h, 0FFFFFFFFh ; ExceptionLink
.text:00407650 8B 35 24 F1 DF FF mov esi, ds:0FFDFF124h ; CurrentThread
.text:00407656 FF B6 40 01 00 00 push dword ptr [esi+_KTHREAD.PreviousMode] ; push先前模式
.text:0040765C 83 EC 48 sub esp, 48h ; __________________陷阱桢
.text:0040765F 8B 5C 24 6C mov ebx, [esp+_KTRAP_FRAME.SegCs]
.text:00407663 83 E3 01 and ebx, 1 ; 清空cs前面
.text:00407666 88 9E 40 01 00 00 mov [esi+_KTHREAD.PreviousMode], bl ; 先前模式=1
.text:0040766C 8B EC mov ebp, esp ; ebp = ESP -> _KPRAP_FARME
.text:0040766E 8B 9E 34 01 00 00 mov ebx, [esi+_KTHREAD.TrapFrame]
.text:00407674 89 5D 3C mov [ebp+_KTRAP_FRAME._Edx], ebx ; 保存陷阱桢
.text:00407677 89 AE 34 01 00 00 mov [esi+_KTHREAD.TrapFrame], ebp ; 陷阱桢置线程陷阱桢内保存
.text:0040767D FC cld
.text:0040767E 8B 5D 60 mov ebx, [ebp+_KTRAP_FRAME._Ebp] ; ebx = Old ebp
.text:00407681 8B 7D 68 mov edi, [ebp+_KTRAP_FRAME._Eip] ; edi = Old eip (返回地址)
.text:00407684 89 55 0C mov [ebp+_KTRAP_FRAME.DbgArgPointer], edx ; DbgArgPointer 参数
.text:00407687 C7 45 08 00 0D DB BA mov [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h
.text:0040768E 89 5D 00 mov [ebp+_KTRAP_FRAME.DbgEbp], ebx ; DbgEbp = old ebp
.text:00407691 89 7D 04 mov [ebp+_KTRAP_FRAME.DbgEip], edi ; DbgEip = old eip (返回地址)
.text:00407694 F6 46 2C FF test [esi+_KTHREAD.DebugActive], 0FFh ; 判断是否是调试状态(如果是调试状态不为0)
.text:00407698 0F 85 8E FE FF FF jnz Dr_kss_a ; 调试状态 跳转
.text:00407698
.text:0040769E
.text:0040769E loc_40769E: ; CODE XREF: Dr_kss_a+10↑j
.text:0040769E ; Dr_kss_a+7C↑j
.text:0040769E FB sti
.text:0040769F E9 DD 00 00 00 jmp loc_407781 ; 索引号
loc_407781
.text:00407781 8B F8 mov edi, eax ; 索引号
.text:00407783 C1 EF 08 shr edi, 8 ; 获取表位
.text:00407786 83 E7 30 and edi, 30h ; 判断是第几个表
.text:00407789 8B CF mov ecx, edi ; ecx 获取表的偏移
.text:0040778B 03 BE E0 00 00 00 add edi, [esi+_KTHREAD.ServiceTable] ; edi = 服务表
.text:00407791 8B D8 mov ebx, eax ; 索引号
.text:00407793 25 FF 0F 00 00 and eax, 0FFFh ; 获取后12位 服务号
.text:00407793 ; sdt结构8-16位为个数
.text:00407798 3B 47 08 cmp eax, [edi+KSERVICE_TABLE_DESCRIPTOR.Limit] ; 和个数进行判断
.text:0040779B 0F 83 41 FD FF FF jnb _KiBBTUnexpectedRange
.text:0040779B
.text:004077A1 83 F9 10 cmp ecx, 10h ; 判断是否是UI表
.text:004077A4 75 1A jnz short loc_4077C0 ; 不是GUI则跳转
.text:004077A4
.text:004077A6 8B 0D 18 F0 DF FF mov ecx, ds:0FFDFF018h
.text:004077AC 33 DB xor ebx, ebx ; 清空ebx
.text:004077AC
.text:004077AE
.text:004077AE loc_4077AE: ; DATA XREF: _KiTrap0E+110↓o
.text:004077AE 0B 99 70 0F 00 00 or ebx, [ecx+(_KPCR.PrcbData.ProcessorState.ContextFrame.FloatSave.DataSelector+0E00h)]
.text:004077B4 74 0A jz short loc_4077C0 ; _KPCRB->0x518 KeSystemCall增加1
.text:004077B4
.text:004077B6 52 push edx
.text:004077B7 50 push eax
.text:004077B8 FF 15 64 32 48 00 call ds:_KeGdiFlushUserBatch
.text:004077B8
.text:004077BE 58 pop eax
.text:004077BF 5A pop edx
.text:004077BF
.text:004077C0
.text:004077C0 loc_4077C0: ; CODE XREF: _KiFastCallEntry+B4↑j
.text:004077C0 ; _KiFastCallEntry+C4↑j
.text:004077C0 FF 05 38 F6 DF FF inc dword ptr ds:0FFDFF638h ; _KPCRB->0x518 KeSystemCall增加1
.text:004077C6 8B F2 mov esi, edx ; R3esp
.text:004077C8 8B 5F 0C mov ebx, [edi+KSERVICE_TABLE_DESCRIPTOR.Number] ; 每个系统服务参数字节数表的基地址
.text:004077CB 33 C9 xor ecx, ecx ; ecx=0
.text:004077CD 8A 0C 18 mov cl, [eax+ebx] ; 获取参数的字节数
.text:004077D0 8B 3F mov edi, [edi] ; 取出函数表
.text:004077D2 8B 1C 87 mov ebx, [edi+eax*4] ; 取出使用的函数地址
.text:004077D5 2B E1 sub esp, ecx ; 提升堆栈需要使用的字节数
.text:004077D7 C1 E9 02 shr ecx, 2 ; 因为每个参数是4字节,计算个数
.text:004077DA 8B FC mov edi, esp
.text:004077DC 3B 35 D4 8B 48 00 cmp esi, ds:_MmUserProbeAddress ; 判断esp是否是正常R3地址
.text:004077DC ; _MmUserProbeAddress是一个全局变量,是用户程序能访问地址的最大范围
.text:004077E2 0F 83 A8 01 00 00 jnb loc_407990 ; 访问冲突错误
.text:004077E2
.text:004077E8
.text:004077E8 loc_4077E8: ; CODE XREF: _KiFastCallEntry+2A4↓j
.text:004077E8 ; DATA XREF: _KiTrap0E+106↓o
.text:004077E8 F3 A5 rep movsd ; 获取参数
.text:004077EA FF D3 call ebx ; 调用函数
Dr_kss_a
text:0040752C F7 45 70 00 00 02 00 test [ebp+_KTRAP_FRAME.EFlags], 20000h
.text:00407533 75 0D jnz short loc_407542 ; 如果是虚拟模式 跳转
.text:00407533
.text:00407535 F7 45 6C 01 00 00 00 test [ebp+_KTRAP_FRAME.SegCs], 1
.text:0040753C 0F 84 5C 01 00 00 jz loc_40769E ; 判断是不是用户态
.text:0040753C
.text:00407542
.text:00407542 loc_407542: ; CODE XREF: Dr_kss_a+7↑j
.text:00407542 0F 21 C3 mov ebx, dr0
.text:00407545 0F 21 C9 mov ecx, dr1
.text:00407548 0F 21 D7 mov edi, dr2
.text:0040754B 89 5D 18 mov [ebp+_KTRAP_FRAME.Dr0], ebx
.text:0040754E 89 4D 1C mov [ebp+_KTRAP_FRAME.Dr1], ecx
.text:00407551 89 7D 20 mov [ebp+_KTRAP_FRAME.Dr2], edi
.text:00407554 0F 21 DB mov ebx, dr3
.text:00407557 0F 21 F1 mov ecx, dr6
.text:0040755A 0F 21 FF mov edi, dr7
.text:0040755D 89 5D 24 mov [ebp+_KTRAP_FRAME.Dr3], ebx
.text:00407560 89 4D 28 mov [ebp+_KTRAP_FRAME.Dr6], ecx
.text:00407563 33 DB xor ebx, ebx
.text:00407565 89 7D 2C mov [ebp+_KTRAP_FRAME.Dr7], edi
.text:00407568 0F 23 FB mov dr7, ebx
.text:0040756B 64 8B 3D 20 00 00 00 mov edi, large fs:_KPCR.Prcb ; prcb ->_KPRCB
.text:00407572 8B 9F F8 02 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr0]
.text:00407578 8B 8F FC 02 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr1]
.text:0040757E 0F 23 C3 mov dr0, ebx
.text:00407581 0F 23 C9 mov dr1, ecx
.text:00407584 8B 9F 00 03 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr2]
.text:0040758A 8B 8F 04 03 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr3]
.text:00407590 0F 23 D3 mov dr2, ebx
.text:00407593 0F 23 D9 mov dr3, ecx
.text:00407596 8B 9F 08 03 00 00 mov ebx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr6]
.text:0040759C 8B 8F 0C 03 00 00 mov ecx, [edi+_KPRCB.ProcessorState.SpecialRegisters.KernelDr7]
.text:004075A2 0F 23 F3 mov dr6, ebx
.text:004075A5 0F 23 F9 mov dr7, ecx
.text:004075A8 E9 F1 00 00 00 jmp loc_40769E
.text:004075A8
.text:004075A8 Dr_kss_a endp
两种进入内核的方式