搜索PG Context
这边直接抄zhouhe的代码
NTSTATUS ScanBigPool()
{
PSYSTEM_BIGPOOL_INFORMATION pBigPoolInfo;
ULONG64 ReturnLength = 0;
NTSTATUS status;
ULONG i = 0;
int num = 0;
pBigPoolInfo = (PSYSTEM_BIGPOOL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, sizeof(SYSTEM_BIGPOOL_INFORMATION), 'ttt');
status = ZwQuerySystemInformation(0x42/*SystemBigPoolInformation*/, pBigPoolInfo, sizeof(SYSTEM_BIGPOOL_INFORMATION), &ReturnLength);
//DbgPrint("pBigPoolInfo->Count - %d \n", pBigPoolInfo->Count);
//DbgPrint("ReturnLength - %p \n", ReturnLength);
ExFreePool(pBigPoolInfo);
pBigPoolInfo = (PSYSTEM_BIGPOOL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, ReturnLength + 0x1000, 'ttt');
if (!pBigPoolInfo)
return STATUS_UNSUCCESSFUL;
status = ZwQuerySystemInformation(0x42, pBigPoolInfo, ReturnLength + 0x1000, &ReturnLength);
if (status != STATUS_SUCCESS)
{
DPRINT("query BigPoolInfo failed: %p\n", status);
return status;
}
DPRINT("pBigPoolInfo: %p\n", pBigPoolInfo);
for (i = 0; i < pBigPoolInfo->Count; i++)
{
PVOID addr = pBigPoolInfo->AllocatedInfo[i].VirtualAddress;
ULONG64 size = (ULONG64)pBigPoolInfo->AllocatedInfo[i].SizeInBytes;
PULONG64 ppte = (PULONG64)GetPteAddress(addr);
ULONG64 pte = *ppte;
PULONG64 ppde = (PULONG64)GetPdeAddress(addr);
ULONG64 pde = *ppde;
if (size >= 0x7000)
{
if (pde & 0x80) {//big page
}
else {
if ((pte & 0x8000000000000000) == 0 && (pte & 1)) {
pte |= 0x8000000000000000;
*ppte = pte;
DPRINT("addr: %p, size: %p, pte: %p, nom\n", addr, size, pte);
num += 1;
}
}
}
}
DPRINT("num: %d\n", num);
ExFreePool(pBigPoolInfo);
return status;
}
搜大页 并且更改PTE属性,让其不可执行,并Hook Idt 0e
pop rax
push rbp
sub rsp,158h
lea rbp,[rsp+80h]
mov byte ptr [rbp-55h],1
mov qword ptr [rbp-50h],rax
push rax
push rcx
push rdx
push rbx
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
pushfq
lea r15,[rbp - 80h]
mov r14,[r15+160h]
cmp r14,11h
jnz Lable1
mov rax,[r15 + 168h]
mov eax,[rax]
cmp eax, 1131482eh
jnz Lable1
sub rsp,32
mov rax,g_ProxyFunction
mov rcx,r15
call rax
add rsp,32
jmp Lable2
Lable1:
popfq
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rbx
pop rdx
pop rcx
pop rax
jmp g_Jmp
Lable2:
popfq
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rbx
pop rdx
pop rcx
pop rax
add rsp,158h
pop rbp
add rsp,8
iretq
cmp eax, 1131482eh 就是判断这个地址数据是不是xor qword ptr cs:[rcx],rdx
PG Context 解密
0: kd> u 0xFFFFB6814510205E
ffffb681`4510205e 0e ???
ffffb681`4510205f 4600be223e975a add byte ptr [rsi+5A973E22h],r15b
ffffb681`45102066 7cee jl ffffb681`45102056
ffffb681`45102068 b501 mov ch,1
ffffb681`4510206a 0b4d98 or ecx,dword ptr [rbp-68h]
ffffb681`4510206d b4ac mov ah,0ACh
ffffb681`4510206f ec in al,dx
ffffb681`45102070 696ba5c3a32e1a imul ebp,dword ptr [rbx-5Bh],1A2EA3C3h
要解密时
0: kd> u 0xFFFFB6814510205E
ffffb681`4510205e 2e483111 xor qword ptr cs:[rcx],rdx
ffffb681`45102062 52 push rdx
ffffb681`45102063 bb1737246a mov ebx,6A243717h
ffffb681`45102068 e490 in al,90h
ffffb681`4510206a 52 push rdx
ffffb681`4510206b bb1727246a mov ebx,6A242717h
ffffb681`45102070 e4a0 in al,0A0h
ffffb681`45102072 52 push rdx
调试 PG Context
如果想调试 PG Context 可以在这个地址下个硬件断点
0: kd> g
Breakpoint 3 hit
ffffb681`4510205e 2e483111 xor qword ptr cs:[rcx],rdx
0: kd> t
ffffb681`45102062 48315108 xor qword ptr [rcx+8],rdx
0: kd> t
ffffb681`45102066 48315110 xor qword ptr [rcx+10h],rdx
0: kd> t
ffffb681`4510206a 48315118 xor qword ptr [rcx+18h],rdx
0: kd> t
ffffb681`4510206e 48315120 xor qword ptr [rcx+20h],rdx
0: kd> t
ffffb681`45102072 48315128 xor qword ptr [rcx+28h],rdx
0: kd> t
ffffb681`45102076 48315130 xor qword ptr [rcx+30h],rdx
0: kd> t
ffffb681`4510207a 48315138 xor qword ptr [rcx+38h],rdx
0: kd> t
ffffb681`4510207e 48315140 xor qword ptr [rcx+40h],rdx
0: kd> t
ffffb681`45102082 48315148 xor qword ptr [rcx+48h],rdx
0: kd> t
ffffb681`45102086 48315150 xor qword ptr [rcx+50h],rdx
0: kd> t
ffffb681`4510208a 48315158 xor qword ptr [rcx+58h],rdx
0: kd> t
ffffb681`4510208e 48315160 xor qword ptr [rcx+60h],rdx
0: kd> t
ffffb681`45102092 48315168 xor qword ptr [rcx+68h],rdx
0: kd> t
ffffb681`45102096 48315170 xor qword ptr [rcx+70h],rdx
0: kd> t
ffffb681`4510209a 48315178 xor qword ptr [rcx+78h],rdx
0: kd> t
ffffb681`4510209e 4883c178 add rcx,78h
0: kd> t
ffffb681`451020a2 48315108 xor qword ptr [rcx+8],rdx
0: kd> t
ffffb681`451020a6 48315110 xor qword ptr [rcx+10h],rdx
0: kd> t
ffffb681`451020aa 48315118 xor qword ptr [rcx+18h],rdx
0: kd> t
ffffb681`451020ae 48315120 xor qword ptr [rcx+20h],rdx
0: kd> t
ffffb681`451020b2 48315128 xor qword ptr [rcx+28h],rdx
0: kd> t
ffffb681`451020b6 48315130 xor qword ptr [rcx+30h],rdx
0: kd> t
ffffb681`451020ba 48315138 xor qword ptr [rcx+38h],rdx
0: kd> t
ffffb681`451020be 48315140 xor qword ptr [rcx+40h],rdx
0: kd> t
ffffb681`451020c2 48315148 xor qword ptr [rcx+48h],rdx
0: kd> t
ffffb681`451020c6 4883e978 sub rcx,78h
0: kd> t
ffffb681`451020ca 3111 xor dword ptr [rcx],edx
0: kd> t
ffffb681`451020cc 488bc2 mov rax,rdx
0: kd> t
ffffb681`451020cf 488bd1 mov rdx,rcx
0: kd> t
ffffb681`451020d2 8b8ac4000000 mov ecx,dword ptr [rdx+0C4h]
0: kd> t
ffffb681`451020d8 4885c0 test rax,rax
0: kd> t
ffffb681`451020db 7411 je ffffb681`451020ee
0: kd> t
ffffb681`451020dd 483184cac0000000 xor qword ptr [rdx+rcx*8+0C0h],rax
0: kd> t
ffffb681`451020e5 48d3c8 ror rax,cl
0: kd> t
ffffb681`451020e8 480fbbc0 btc rax,rax
0: kd> t
ffffb681`451020ec e2ef loop ffffb681`451020dd
0: kd> t
ffffb681`451020dd 483184cac0000000 xor qword ptr [rdx+rcx*8+0C0h],rax
0: kd> p
ffffb681`451020e5 48d3c8 ror rax,cl
0: kd> p
ffffb681`451020e8 480fbbc0 btc rax,rax
0: kd> p
ffffb681`451020ec e2ef loop ffffb681`451020dd
0: kd> p
ffffb681`451020ee 8b82e8070000 mov eax,dword ptr [rdx+7E8h]
0: kd> t
ffffb681`451020f4 4803c2 add rax,rdx
0: kd> t
ffffb681`451020f7 4883ec28 sub rsp,28h
0: kd> t
ffffb681`451020fb ffd0 call rax
这里会让硬件断点和单步失效 需要nop
INITKDBG:0000000140A0CDEB loc_140A0CDEB: ; CODE XREF: sub_140A0CD10+D3↑j
INITKDBG:0000000140A0CDEB 0F 01 4D 07 sidt fword ptr [rbp+57h+var_50]
INITKDBG:0000000140A0CDEF 0F 01 5D F7 lidt fword ptr [rbp+57h+var_60]
INITKDBG:0000000140A0CDF3 41 0F 23 FF mov dr7, r15
INITKDBG:0000000140A0CDF7 0F 01 5D 07 lidt fword ptr [rbp+57h+var_50]
INITKDBG:0000000140A0CDFB
INITKDBG:0000000140A0CDFB loc_140A0CDFB: ; CODE XREF: sub_140A0CD10+D9↑j
INITKDBG:0000000140A0CDFB FB sti
INITKDBG:0000000140A0CDFC
INITKDBG:0000000140A0CDFC loc_140A0CDFC: ; CODE XREF: sub_140A0CD10+44↑j
INITKDBG:0000000140A0CDFC 81 87 28 08 00 00 20 06 00 00 add dword ptr [rdi+828h], 620h
INITKDBG:0000000140A0CE06 48 8D 8F 20 06 00 00 lea rcx, [rdi+620h]
INITKDBG:0000000140A0CE0D 8B B7 C4 00 00 00 mov esi, [rdi+0C4h]
处理 PG Context
由于判断了异常地址是不是xor qword ptr cs:[rcx],rdx 当然也可能不是pg Context 所以要准确的话 可以去解密代码
所以这边可以retn处理 至少在我目前虚拟机快照下没问题
PULONG64 Pte = (PULONG64)GetPteAddress((PVOID)Frame->Rip);
*Pte &= ~0x8000000000000000;
DPRINT("Rip: %p\n", Frame->Rip);
*(UCHAR*)Frame->Rip = 0XC3;
后续处理
由于pg Context是接力式调用 所以打断后就不会有下文了,当然还不止是这些 有些pg Context是搜索不到的