本帖最后由 aswcy815174418 于 2021-10-11 07:33 编辑
Shadow SSDT这里面所有的函数都来自于一个win32k.sys,我看很多网上的办法是Attach Process(附加一个可以访问Shadow SSDT)的进程,如果逆过Attach Process,这个函数的本质就是切换Cr3.
自己的猜想: 自己手动切换cr3(一个可以访问Shadow SSDT),之后获取win32k.sys的dos头位置,获取到pde,然后切换回自己的驱动进程,修改驱动程序的pde,即可达到不调用api实现访问Shadow SSDT
[b]运行的函数头:void AffiliatedPhysical(); 从这个函数头开始看
至于获取可以访问Shadow SSDT的进程,比如explorere.exe就可以,获取这个进程的cr3,你可以先通过全局句柄表获取eprocess结构体
unsigned int GetDllBase(PVOID frm,int flag) {
UNICODE_STRING* BaseDllName = frm;
if (flag == 1) {
LPSTR FunName = frm;
UNICODE_STRING us;
ANSI_STRING as;
as.Length = strlen(FunName);
as.MaximumLength = strlen(FunName) + 1;
as.Buffer = FunName;
RtlAnsiStringToUnicodeString(&us, &as, TRUE);
BaseDllName = &us;
}
LDR_DATA_TABLE_ENTRY* pLdr = pDriverObject->DriverSection;
do {
//DbgPrint("\nDllName: %wZ\nDllBase: %x\n", &pLdr->BaseDllName, pLdr->DllBase);
if (!RtlCompareUnicodeString(BaseDllName, &pLdr->BaseDllName, TRUE)) {
return pLdr->DllBase;
}
pLdr = pLdr->InLoadOrderLinks.Blink;
} while (pLdr->DllBase);
return 0;
}
unsigned int* GetPDE(unsigned int VirtualAddr) {
unsigned int JudgePAE = 0;
_asm {
mov eax, cr0;
and eax, 0x10;
mov JudgePAE, eax;
}
if (JudgePAE) {
return 0xC0600000 + ((VirtualAddr >> 18) & 0x3ff8);
}
return 0xC0300000 + (VirtualAddr >> 22) * 4;
}
unsigned int* GetPTE(unsigned int VirtualAddr) {
unsigned int JudgePAE = 0;
_asm {
mov eax, cr0;
and eax, 0x10;
mov JudgePAE, eax;
}
if (JudgePAE) {
return 0xC0000000 + ((VirtualAddr >> 9) & 0x7ffff8);
}
return 0xC0000000 + (VirtualAddr >> 22) * 0x1000 + ((VirtualAddr << 10) >> 22) * 4;
}
unsigned int GetEProcess(LPSTR ImageFileName) {
unsigned int** PspCidTable;
_asm {
mov eax, dword ptr ds:[0xffdff000 + 0x34];
mov eax, dword ptr ds : [eax + 0x80];
mov eax, dword ptr ds : [eax];
and eax, 0xFFFFFFFC;
mov PspCidTable, eax;
}
int i = 0;
while (*PspCidTable) {
for (size_t j = 2; j < 0x800; j += 2) {
OBJECT_HEADER* Head = (PspCidTable[i][j] & 0xFFFFFFFE) - 0x18;
if (MmIsAddressValid(Head)) {
OBJECT_TYPE* TypeName = Head->Type;
if (!wcscmp(L"Process", TypeName->Name.Buffer)) {
unsigned char* Name = (PspCidTable[i][j] & 0xFFFFFFFE) + 0x174;
if (!strcmp(Name, ImageFileName)) {
return PspCidTable[i][j] & 0xFFFFFFFE;
}
}
}
}
i++;
PspCidTable++;
}
return 0;
}
//给驱动挂上win32k物理页
void AffiliatedPhysical() {
unsigned int Eprocess = GetEProcess("explorer.exe");
unsigned int rr3 = *(unsigned int*)(Eprocess + 0x18);
_asm {
cli;
mov eax, cr3;
push eax;
mov eax, rr3;
mov cr3, eax;
}
unsigned int PDE = *GetPDE(GetDllBase("win32k.sys", 1));
_asm {
pop eax;
mov cr3, eax;
sti;
}
*GetPDE(GetDllBase("win32k.sys", 1)) = PDE;
DbgPrint("挂载物理页成功了!\n");
}
|