windbg跟踪NtOpenProcess

过程: OpenProcess->NtOpenProcess->KiFastSystemCall->sysenter

kd> u ntdll!NtOpenProcess
ntdll!ZwOpenProcess:
7c92d5fe b87a000000      mov     eax,7Ah
7c92d603 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d608 ff12            call    dword ptr [edx] //进入SystemCall eax装载的是函数调用号
7c92d60a c21000          ret     10h
7c92d60d 90              nop

嗯,NtOpenProcess调用了SharedUserData!SystemCallStub (7ffe0300)


而SharedUserData是一个数据结构
#define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA)


每个进程用户空间的0x7ffe0000都以只读方式映射到相同的物理页面上,而这个物理页面上就是KUSER_SHARED_DATA结构的数据 [0x7ffe0300]=[KUSER_SHARED_DATA偏移0x300处]=SystemCall=KiFastSystemCall


验证一下
kd> dd 7ffe0300
7ffe0300  7c92e510 7c92e514 00000000 00000000


kd> u 7c92e510
ntdll!KiFastSystemCall:
7c92e510 8bd4            mov     edx,esp // 把栈指针(ESP)放到EDX中,可以传递参数,也作为从内核模式返回时的栈地址。再执行SYSENTER指令。 


7c92e512 0f34            sysenter 




当执行SYSENTER指令时,CPU进入系统态,并且: 


把寄存器SYSENTER_CS_MSR的内容复制到段寄存器CS中。 
把寄存器SYSENTER_EIP_MSR的内容复制到寄存器EIP中。 
把寄存器SYSENTER_CS_MSR的内容+8写入堆栈段寄存器SS中。 
把寄存器SYSENTER_ESP_MSR的内容复制到堆栈指针ESP中。 
这样,只要预先设置好三个MSR寄存器的内容中,CPU在执行SYSENTER后就可以进入系统空间并从预定的地址执行程序,同时开始使用系统空间的堆栈。通过WinDbg中rdmsr命令可以查看到MSR寄存器的内容,可以看到SYSENTER_EIP_MSR指向nt!KiFastCallEntry,这就是系统空间中快速系统调用的总入口。nt!KiFastCallEntry中再进入nt!KiSystemService。 

kd> rdmsr 176 //#define SYSENTER_EIP_MSR=176
msr[176] = 00000000`804df6f0 
进入内核中首先执行EIP指向的代码804df6f0->KiFastCallEntry
kd> u 804df6f0
nt!KiFastCallEntry:
804df6f0 b923000000      mov     ecx,23h
804df6f5 6a30            push    30h
804df6f7 0fa1            pop     fs
804df6f9 8ed9            mov     ds,cx
804df6fb 8ec1            mov     es,cx
804df6fd 8b0d40f0dfff    mov     ecx,dword ptr ds:[0FFDFF040h]
804df703 8b6104          mov     esp,dword ptr [ecx+4]
804df706 6a23            push    23h



你可能感兴趣的:(数据结构,c,user)