老掉牙的话题了,不过这是学习研究系统的基础。
简单的说说windows系统调用,我们编写win32程序的时候为了完成特定的功能就要去调用win32应用程序接口,就是win32 API,windows通过win32 API调用界面所定义的库函数,这些函数基本上都是系统dll中导出的,然后调用流程一直往系统底层走,知道通过某些特殊的命令进入内核进而完成系统调用,当然不是每一个API都能进入系统调用流程。
这里以ReadFile函数作为研究对象,这个API是kernel32导出的,通过windbg跟踪调用可以直白的看出函数内部调用了NtReadFile,内涵源代码提供了NtReadFile函数,但是用户空间的程序是不可能直接调用内核函数的,其实这个NtReadFile是用户空间提供的一个函数。
以NtReadFile为例:
lkd> u ntdll!ntreadfile
ntdll!NtReadFile:
7c92d9b0 b8b7000000 mov eax,0B7h
7c92d9b5 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d9ba ff12 call dword ptr [edx]
7c92d9bc c22400 ret 24h
7c92d9bf 90 nop
lkd> dd SharedUserData!SystemCallStub
7ffe0300 7c92e4f0 7c92e4f4 00000000 00000000
7ffe0310 00000000 00000000 00000000 00000000
7ffe0320 00000000 00000000 00000000 00000000
7ffe0330 fb1fc0d5 00000000 00000000 00000000
7ffe0340 00000000 00000000 00000000 00000000
7ffe0350 00000000 00000000 00000000 00000000
7ffe0360 00000000 00000000 00000000 00000000
7ffe0370 00000000 00000000 00000000 00000000
lkd> u 7c92e4f0
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 ret
[摘自windows内核情景分析代码-reactOS]
ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegister(IN ULONG_PTR Context)
{
//设置MSR寄存器
//CS被设置成0x8, 那么SS就是0x8+0x8 = x010
Ke386Wrmsr(0x174, 0x8, 0);
//ESP被设置成一个中立的不属于任何线程的堆栈,作为过渡的系统空间堆栈
Ke386Wrmsr(0x175, (ULONG)KeGetCurrentPrcb->DpcStack, 0);
//EIP设置为系统快速调用总入口KiFastCallEntry
Ke386Wrmsr(0x176, (ULONG)KiFastCallEntry, 0);
Retun 0;
}
lkd> u nt!kifastcallentry
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
lkd> !idt 3
Dumping IDT:
03: 8053f6e4 nt!KiTrap03
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!