Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.htmlhtml
Windows系統調用中API從3環到0環(下)ios
若是對API在三環的部分不瞭解的,能夠查看 Windows系統調用中的API三環部分(依據分析重寫ReadProcessMemory函數
函數
上篇:Windows系統調用中API從3環到0環(上)spa
這篇文章分爲上下兩篇,其中上篇初步講解大致輪廓,下篇着重經過實驗來探究其內部實現,最終分析兩個函數(快速調用與系統中斷),來實現經過系統中斷直接調用內核函數。操作系統
1、INT 0x2E進0環指針
.text : 77F070C0 // 以前調用該函數時 mov eax, 0x115,向eax傳入一個函數號
.text : 77F070C0 lea edx, [esp + arg_4] // 當前參數的指針存儲在 edx中
.text : 77F070C4 int 2Eh; // 經過中斷門的形式進入到內核中code
1)在GDT表中查看0x2ehhtm
在保護模式的門這一節中,咱們瞭解到當發生中斷時,操做系統會查找idt表,根據中斷號在idt表中找到中斷門描述符,從中斷門描述符中讀取CS:EIP的信息。blog
以後,SS EIP 經過搜索GDT表,該表中存放着各個TSS描述符(每一個進程一個TSS,內核一個TSS,TSS存放各類寄存器用於任務切換),來查找內核的 SS ESP。索引
如圖:咱們經過windbg來查找出該地址 gdt+2e*8
根據中斷門描述符屬性將 83e8ee00`00082fee 拆分拼接以後可知SS:08 / EIP:83e82fee
2)查看 EIP:83e82fee 這個函數
kd> u 83e82fee
nt!KiSystemService:
83e82fee 6a00 push 0
83e82ff0 55 push ebp
83e82ff1 53 push ebx
83e82ff2 56 push esi
83e82ff3 57 push edi
83e82ff4 0fa0 push fs
83e82ff6 bb30000000 mov ebx,30h
83e82ffb 668ee3 mov fs,bx
該 nt!KiSystemService函數是真正的內核函數,並非ntdll.dll模塊下,其存在於ntoskrnl.exe / ntkrnlpa.exe中(根據分頁模式不一樣選用不一樣的程序)
2、經過 systenter進入0環
MSR寄存器存着進入內核的 CS、ESP、EIP的寄存器的值,SS=IA32_SYSENTER_CS+8。
1)windbg查看這個MSR寄存器的值
rdmsr 174 //查看CS
rdmsr 175 //查看ESP
rdmsr 176 //查看EIP
2)查看EIP這個函數
kd> u 83e830c0
nt!KiFastCallEntry:
83e830c0 b923000000 mov ecx,23h
83e830c5 6a30 push 30h
83e830c7 0fa1 pop fs
83e830c9 8ed9 mov ds,cx
83e830cb 8ec1 mov es,cx
83e830cd 648b0d40000000 mov ecx,dword ptr fs:[40h]
83e830d4 8b6104 mov esp,dword ptr [ecx+4]
83e830d7 6a23 push 23h
其是調用nt!KiFastCallEntry這個函數,跟nt!KiSystemService同樣,該函數是真正的內核函數。
3、經過中斷來重寫ReadProcessMemory函數(經過快速調用時的實現能夠查看這篇Windows系統調用中的API三環部分(依據分析重寫ReadProcessMemory函數))
1 #include "pch.h" 2 #include <iostream> 3 #include <algorithm> 4 #include <Windows.h> 5 void ReadMemory(HANDLE hProcess, PVOID pAddr, PVOID pBuffer, DWORD dwSize, DWORD *dwSizeRet) 6 { 7 8 _asm 9 { 10 11 lea eax, [ebp + 0x14] 12 push eax 13 push[ebp + 0x14] 14 push[ebp + 0x10] 15 push[ebp + 0xc] 16 push[ebp + 8] 17 mov eax, 0x115 18 mov edx,esp 19 int 0x2e 20 add esp, 20 21 } 22 } 23 int main() 24 { 25 HANDLE hProcess = 0; 26 int t = 123; 27 DWORD pBuffer; 28 //hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0,a); 29 ReadMemory((HANDLE)-1, (PVOID)&t, &pBuffer, sizeof(int), 0); 30 printf("%X\n", pBuffer); 31 ReadProcessMemory((HANDLE)-1, &t, &pBuffer, sizeof(int), 0); 32 printf("%X\n", pBuffer); 33 34 getchar(); 35 return 0; 36 }