0x00基本資訊
系統:windows 10 21h2
工具:ida 7.7 , windbg 10
3環寫一個win32k 函式 看訪問流程
0x01分析
例如:3環函式
FlattenPath(x)
會呼叫到 win32u.dll 的 NtGdiFlattenPath eax=12a0 ssdt 表的下標地址就是 2a0 就是他的對映地址
.text:0000000180006430 public NtGdiFlattenPath .text:0000000180006430 NtGdiFlattenPath proc near ; DATA XREF: .rdata:000000018000CE4D↓o .text:0000000180006430 ; .rdata:off_18000F178↓o ... .text:0000000180006430 mov r10, rcx .text:0000000180006433 mov eax, 12A0h .text:0000000180006438 test byte ptr ds:7FFE0308h, 1 .text:0000000180006440 jnz short loc_180006445 .text:0000000180006442 syscall ; Low latency system call .text:0000000180006444 retn
windbg檢視rdmsr 看到KiSystemCall64 地址
rdmsr 0xC0000082
下斷點注意不要在 KiSystemCall64 地址下斷點 會報錯 3行彙編是堆疊切換 不要下斷點
.text:00000001404088C0 ; __unwind { // KiSystemServiceHandler .text:00000001404088C0 swapgs .text:00000001404088C3 mov gs:10h, rsp .text:00000001404088CC mov rsp, gs:1A8h .text:00000001404088D5 push 2Bh ; '+'
可以在KiSystemCall64 偏移15位置下斷點 就可以斷下
ba e1 KiSystemCall64+15
直接分析到 KiSystemServiceStart 取下標
.text:0000000140408C20 KiSystemServiceStart: ; DATA XREF: KiServiceInternal+5A↑o .text:0000000140408C20 ; .data:0000000140C00340↓o .text:0000000140408C20 mov [rbx+90h], rsp .text:0000000140408C27 mov edi, eax .text:0000000140408C29 shr edi, 7 .text:0000000140408C2C and edi, 20h .text:0000000140408C2F and eax, 0FFFh ; 取下標
獲取FlattenPath 0環地址
.text:0000000140408C5E loc_140408C5E: ; CODE XREF: KiSystemCall64+389↑j .text:0000000140408C5E cmp eax, [r10+rdi+10h] .text:0000000140408C63 jnb loc_140409195 .text:0000000140408C69 mov r10, [r10+rdi] .text:0000000140408C6D movsxd r11, dword ptr [r10+rax*4] ; 獲取地址
.text:0000000140408D90 KiSystemServiceCopyEnd: ; CODE XREF: KiSystemCall64+413↑j .text:0000000140408D90 ; DATA XREF: KiSystemServiceHandler+27↑o ... .text:0000000140408D90 test cs:KiDynamicTraceMask, 1 .text:0000000140408D9A jnz loc_140409233 .text:0000000140408DA0 test dword ptr cs:PerfGlobalGroupMask+8, 40h .text:0000000140408DAA jnz loc_1404092A7 .text:0000000140408DB0 mov rax, r10 .text:0000000140408DB3 call rax .text:0000000140408DB5 nop dword ptr [rax]
call rax 下斷點 也可以直接下偏移斷點
ba e1 KiSystemServiceCopyEnd+0x20
nt!_guard_retpoline_indirect_rax 跟進去
call nt!_guard_retpoline_indirect_rax (fffff803`36c1b2e0)
繼續f11 一個ret 返回就可以跳到 win32k!NtGdiFlattenPath:
fffff803`36c1b2ff e81c000000 call nt!_guard_retpoline_indirect_rax+0x40 (fffff803`36c1b320)
這裡的
ffffd004`2246b268 e833f00800 call ffffd004`224fa2a0
也是直接f11 和上邊一樣
成功到實際彙編程式碼 這就看到一個函式核心實現了 可以分析除錯了
win32kfull!NtGdiFlattenPath: ffffd004`238dde70 4053 push rbx ffffd004`238dde72 4881ecb0000000 sub rsp,0B0h ffffd004`238dde79 488bd1 mov rdx,rcx ffffd004`238dde7c 488d4c2420 lea rcx,[rsp+20h] ffffd004`238dde81 e88e85dcff call win32kfull!DCOBJ::DCOBJ (ffffd004`236a6414) ffffd004`238dde86 488b4c2420 mov rcx,qword ptr [rsp+20h] ffffd004`238dde8b 4885c9 test rcx,rcx ffffd004`238dde8e 7507 jne win32kfull!NtGdiFlattenPath+0x27 (ffffd004`238dde97)
當然最方便的是 3環下斷點 直接步過到核心 進行除錯
bp win32kfull!NtGdiFlattenPath
記住要記載符號 win32kfull.sys 可以用.reload 命令