分析快速系统调用的位置
int main()
{
CreateFile(
L"C:\\1.txt",
FILE_ALL_ACCESS,
NULL,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
return 0;
}
直接在CreateFileW上下断点
进入之后,能够看到
进入之后,能够看到
这个SYSENTER就是三环世界的边缘地带了,OD就无法继续分析了。
在SYSENTER上按F7,就直接回到了上一层函数。
分析MSR 0x174 0x175 0x176
kd> rdmsr 0x174
msr[174] = 00000000`00000008 //新的CS
kd> rdmsr 0x175
msr[175] = 00000000`80792000 //新的ESP
kd> rdmsr 0x176
msr[176] = 00000000`83e91790 //新的EIP
分析MSR 0x176号中存储地址指向位置的代码
nt!KiFastCallEntry:
83e91790 b923000000 mov ecx,23h
83e91795 6a30 push 30h
83e91797 0fa1 pop fs //fs被修改,指向了KPCR
83e91799 8ed9 mov ds,cx
83e9179b 8ec1 mov es,cx
83e9179d 648b0d40000000 mov ecx,dword ptr fs:[40h]
83e917a4 8b6104 mov esp,dword ptr [ecx+4]
83e917a7 6a23 push 23h
83e917a9 52 push edx
83e917aa 9c pushfd
83e917ab 6a02 push 2
83e917ad 83c208 add edx,8
83e917b0 9d popfd
83e917b1 804c240102 or byte ptr [esp+1],2
83e917b6 6a1b push 1Bh
83e917b8 ff350403dfff push dword ptr ds:[0FFDF0304h]
83e917be 6a00 push 0
83e917c0 55 push ebp
83e917c1 53 push ebx
83e917c2 56 push esi
83e917c3 57 push edi
83e917c4 648b1d1c000000 mov ebx,dword ptr fs:[1Ch] //重要 得到KPCR自己
83e917cb 6a3b push 3Bh
83e917cd 8bb324010000 mov esi,dword ptr [ebx+124h] //重要 得到当前执行线程的ETHREAD
83e917d3 ff33 push dword ptr [ebx]
83e917d5 c703ffffffff mov dword ptr [ebx],0FFFFFFFFh
83e917db 8b6e28 mov ebp,dword ptr [esi+28h]
83e917de 6a01 push 1
83e917e0 83ec48 sub esp,48h
83e917e3 81ed9c020000 sub ebp,29Ch
83e917e9 c6863a01000001 mov byte ptr [esi+13Ah],1
83e917f0 3bec cmp ebp,esp
83e917f2 7597 jne nt!KiFastCallEntry2+0x49 (83e9178b)
83e917f4 83652c00 and dword ptr [ebp+2Ch],0
83e917f8 f64603df test byte ptr [esi+3],0DFh
83e917fc 89ae28010000 mov dword ptr [esi+128h],ebp
83e91802 0f8538feffff jne nt!Dr_FastCallDrSave (83e91640)
83e91808 8b5d60 mov ebx,dword ptr [ebp+60h]
83e9180b 8b7d68 mov edi,dword ptr [ebp+68h]
83e9180e 89550c mov dword ptr [ebp+0Ch],edx
83e91811 c74508000ddbba mov dword ptr [ebp+8],0BADB0D00h
83e91818 895d00 mov dword ptr [ebp],ebx
83e9181b 897d04 mov dword ptr [ebp+4],edi
83e9181e fb sti
83e9181f 8bf8 mov edi,eax //edi中存放了调用号
83e91821 c1ef08 shr edi,8 //X YYYY YYYY YYYY
//X YYYY
//1 0000
//X 0000
//如果SSDT的话,X就是0,整个这个数就是0
//如果ShadowSSDT的话,X就是1,整个这个数就是16
83e91824 83e710 and edi,10h
83e91827 8bcf mov ecx,edi
83e91829 03bebc000000 add edi,dword ptr [esi+0BCh] //重要 得到服务表,自动就适应了SSDT或者ShadowSSDT
83e9182f 8bd8 mov ebx,eax
83e91831 25ff0f0000 and eax,0FFFh //X YYYY YYYY YYYY
//0 1111 1111 1111
//0 YYYY YYYY YYYY
83e91836 3b4708 cmp eax,dword ptr [edi+8]
83e91839 0f8333fdffff jae nt!KiBBTUnexpectedRange (83e91572)
83e9183f 83f910 cmp ecx,10h
83e91842 751a jne nt!KiSystemServiceAccessTeb+0x12 (83e9185e)
83e91844 8b8e88000000 mov ecx,dword ptr [esi+88h]
83e9184a 33f6 xor esi,esi
nt!KiSystemServiceAccessTeb:
83e9184c 0bb1700f0000 or esi,dword ptr [ecx+0F70h]
83e91852 740a je nt!KiSystemServiceAccessTeb+0x12 (83e9185e)
83e91854 52 push edx
83e91855 50 push eax
83e91856 ff1594dafb83 call dword ptr [nt!KeGdiFlushUserBatch (83fbda94)]
83e9185c 58 pop eax
83e9185d 5a pop edx
83e9185e 64ff05b0060000 inc dword ptr fs:[6B0h]
83e91865 8bf2 mov esi,edx //把用户栈基址拷贝给了esi
83e91867 33c9 xor ecx,ecx
83e91869 8b570c mov edx,dword ptr [edi+0Ch] //这里得到的是参数大小表
83e9186c 8b3f mov edi,dword ptr [edi] //重要 得到服务表中的函数地址表
//这个表叫做系统服务调度表(SSDT)
83e9186e 8a0c10 mov cl,byte ptr [eax+edx] //得到参数所占用的字节数
83e91871 8b1487 mov edx,dword ptr [edi+eax*4] //重要 得到了函数地址
83e91874 2be1 sub esp,ecx //栈顶抬高这么大,准备拷贝参数
83e91876 c1e902 shr ecx,2
83e91879 8bfc mov edi,esp //内核栈是目的位置edi
83e9187b f6457202 test byte ptr [ebp+72h],2
83e9187f 7506 jne nt!KiSystemServiceAccessTeb+0x3b (83e91887)
83e91881 f6456c01 test byte ptr [ebp+6Ch],1
83e91885 740c je nt!KiSystemServiceCopyArguments (83e91893)
83e91887 3b3550d8fb83 cmp esi,dword ptr [nt!MmUserProbeAddress (83fbd850)]
83e9188d 0f832e020000 jae nt!KiSystemCallExit2+0xa5 (83e91ac1)
nt!KiSystemServiceCopyArguments:
83e91893 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] //拷贝参数
83e91895 f6456c01 test byte ptr [ebp+6Ch],1
83e91899 7416 je nt!KiSystemServiceCopyArguments+0x1e (83e918b1)
83e9189b 648b0d24010000 mov ecx,dword ptr fs:[124h]
83e918a2 8b3c24 mov edi,dword ptr [esp]
83e918a5 89993c010000 mov dword ptr [ecx+13Ch],ebx
83e918ab 89b92c010000 mov dword ptr [ecx+12Ch],edi
83e918b1 8bda mov ebx,edx //重要
83e918b3 f60588a6f88340 test byte ptr [nt!PerfGlobalGroupMask+0x8 (83f8a688)],40h
83e918ba 0f954512 setne byte ptr [ebp+12h]
83e918be 0f8580030000 jne nt!KiServiceExit2+0x179 (83e91c44)
83e918c4 ffd3 call ebx //重要 调用了真正的系统函数
KPCR(PROCESSPOR Control Region) 处理器控制域,其中存储了CPU相关的信息,每一核CPU都有一个。
FS寄存器,在用户层的时候,指向的是TEB,在内核层的时候,指向的是KPCR。
nt!_KPCR
+0x120 PrcbData : _KPRCB
+0x000 MinorVersion : ??
+0x002 MajorVersion : ??
+0x004 CurrentThread : ????
所以FS:[124]就是CurrentThread,当前运行线程的ETHREAD。
在ETHREAD的0xbc这个位置,存储的是一个叫做服务表的东西。
kd> dt _KTHREAD
nt!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 CycleTime : Uint8B
......
+0x0bc ServiceTable : Ptr32 Void