-
-
[原创]系统调用菜鸟学习笔记
-
发表于:
2010-6-11 19:05
12712
-
无聊之中拿起情景分析书看看....顺便做下笔记加深下印象
1. 从用户态跳转到内核态一般有三种方式:中断,异常,和自陷,除了这些还有调用门啦,快速系统调用啦什么的
2. 传统的windows是调用int 0x2e来切换到内核态的。从TSS中装入本线程的系统空间堆栈寄存器SS和堆栈指针ESP,在把用户空间的堆栈寄存器SS,堆栈指针ESP,标志位寄存器EFLAGS,代码段寄存器CS,EIP压入用户系统空间的堆栈;然后从IDT中以0x2e为索引找到相应的程序入口开始执行内核程序。返回就是上述逆过程
3. 快速系统调用sysenter指令实现。配套了3个寄存器。SYSENTER_CS_MSR,SYSENTER_EIP_MSR,SYSENTER_ESP_MSR。
SYSENTER_CS_MSR内容复制到段寄存器CS中
SYSENTER_EIP_MSR内容复制到寄存器EIP中
SYSENTER_CS_MSR内容+8写入堆栈段寄存器SS
SYSENTER_ESP_MSR的内容复制到堆栈指针ESP中
这3个寄存器的内容是在内核初始化的时候赋值的
SYSENTER_CS_MSR :Ke386Wrmsr(0x174,KGDT_R0_CODE,0);
SYSENTER_ESP_MSR:Ke386Wrmsr(0x175,(ULONG)KeGetCurrentPrcb->DpcStack,0);
SYSENTER_EIP_MSR:Ke386Wrmsr(0x176,(ULONG)KiFastCallEntry,0);
第3个参数为0,是意味着这3个寄存器为32位的。SYSENTER_CS_MSR被设置成KGDT_R0_CODE即0x8,设置堆栈段寄存器ss的就是0x10,就是KGDT_R0_DATA。
SYSENTER_ESP_MSR设置成PRCB中指针DpcStack的内容.这个是指向一个中立的不属于任何一个线程的堆栈,供内核执行DPC函数的使用的. SYSENTER_EIP_MSR设置成指向KiFastCallEntry,这是系统空间中快速调用的总入口
4. 执行sysexit退出时:
将CS设置成SYSENTER_CS_MSR的内容+16,就是KGDT_R3_CODE
把寄存器EDX的内容复制到EIP
把SS设置成SYSENTER_CS_MSR的内容+24,就是KGDT_R3_DATA
把寄存器ECX的内容复制到ESP
以ZwReadFile为例
nt!ZwReadFile:
804ffbf4 b8b7000000 mov eax,0B7h//功能号
804ffbf9 8d542404 lea edx,[esp+4]//参数的开始位置
804ffbfd 9c pushfd//标志寄存器
804ffbfe 6a08 push 8//KGDT_R0_CODE
804ffc00 e88ce80300 call nt!KiSystemService (8053e491)
804ffc05 c22400 ret 24h//9个参数,4*9
Call 8053e491进入这个函数后
Cpu自动压入以下信息:
用户空间的堆栈位置,包括堆栈段寄存器ss和堆栈指针esp的内容
Cpu中的标志寄存器EFLAGS的内容
用户空间的指令位置,包括代码段寄存器cs和指令指针eip的内容
当用户空间进入到系统空间时,cpu自动根据TR的指引从TSS中获取当前进程的SS和ESP两个寄存器的值,根据TR的指引从TSS获取当前线程的系统空间堆栈,再把好几个寄存器的内容压入这个堆栈,并且根据IDTR的指引从中断向量表中获取CS和EIP的值。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)