PCHAR MiProtectionToString[] = {
"MM_ZERO_ACCESS", // 0 // this value is not used.
"MM_READONLY", // 1
"MM_EXECUTE", // 2
"MM_EXECUTE_READ", // 3
"MM_READWRITE", // 4 // bit 2 is set if this is writable.
"MM_WRITECOPY", // 5
"MM_EXECUTE_READWRITE", // 6
"MM_EXECUTE_WRITECOPY", // 7
"MM_NOCACHE" // 8
};
#if 1
#undef MmPrint
#define MmPrint(x)
#endif
VALIDITY_CHECK_STATUS
MmIsAddressValidExNotPae(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS Return = VCS_INVALID;
MMPTE* Pde = MiGetPdeAddress(Pointer);
MmPrint(("PDE is 0x%08x\n", Pde));
if( Pde->u.Hard.Valid )
{
MmPrint(("PDE entry is valid, PTE PFN=%08x\n", Pde->u.Hard.PageFrameNumber));
MMPTE* Pte = MiGetPteAddress(Pointer);
MmPrint(("PTE is 0x%08x\n", Pte));
if( Pte->u.Hard.Valid )
{
MmPrint(("PTE entry is valid, PFN=%08x\n", Pte->u.Hard.PageFrameNumber));
Return = VCS_VALID;
}
else
{
//
// PTE is not valid
//
MMPTE pte = *Pte;
MmPrint(("Got invalid PTE [%08x]: Proto=%d,Transition=%d,Protection=0x%x,PageFilePFN=0x%x\n",
pte.u.Long,
pte.u.Soft.Prototype,
pte.u.Soft.Transition,
pte.u.Soft.Protection,
pte.u.Soft.PageFileHigh));
if( pte.u.Long )
{
if( pte.u.Soft.Prototype == 1 )
{
MmPrint(("PTE entry is not valid, points to prototype PTE.\n"));
// more accurate check should be performed here for pointed prototype PTE!
Return = VCS_PROTOTYPE;
}
else // not a prototype PTE
{
if( pte.u.Soft.Transition != 0 )
{
//
// This is a transition page. Consider it invalid.
//
MmPrint(("PTE entry is not valid, points to transition page.\n"));
Return = VCS_TRANSITION;
}
else if (pte.u.Soft.PageFileHigh == 0)
{
//
// Demand zero page
//
MmPrint(("PTE entry is not valid, points to demand-zero page.\n"));
Return = VCS_DEMANDZERO;
}
else
{
//
// Pagefile PTE
//
if( pte.u.Soft.Transition == 0 )
{
MmPrint(("PTE entry is not valid, VA is paged out (PageFile offset=%08x)\n",
pte.u.Soft.PageFileHigh));
Return = VCS_PAGEDOUT;
}
else
{
MmPrint(("PTE entry is not valid, Refault\n"));
}
}
}
}
else
{
MmPrint(("PTE entry is completely invalid\n"));
}
}
}
else
{
MmPrint(("PDE entry is not valid\n"));
}
return Return;
}
上面传说中老外写的.
ULONG IsValidAddr( ULONG uAddr )
{
ULONG uInfo;
ULONG uCr4;
ULONG uPdeAddr;
ULONG uPteAddr;
_asm
{
cli
push eax
_emit 0x0F
_emit 0x20
_emit 0xE0//mov eax,cr4
mov [uCr4], eax
pop eax
}
_asm sti
uInfo = uCr4 & 0x20;//判断是否PAE模式
if( uInfo != 0 )
uPdeAddr = (uAddr>>21)*8+0xC0600000;//
else
//先算PDE 相当于上面代码的#define MiGetPdeAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE))
uPdeAddr = (uAddr>>22)*4+0xc0300000;
KdPrint(("uPdeAddr pde:%.8X\n",uPdeAddr));
if( (*(PULONG)uPdeAddr & 0x1) != 0 )
{
if( (*(PULONG)uPdeAddr & 0x80) != 0 )//
{
KdPrint(("uPdeAddr and ok\n"));
return VALID_PAGE;
}
else
{
if( uInfo != 0 )
{
uPteAddr = (uAddr>>12)*8+0xc0000000;
}
else
{
//算PTE#define MiGetPteAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))
uPteAddr = (uAddr>>12)*4+0xc0000000;
}
KdPrint(("uPteAddr pte:%.8X\n",uPteAddr));
if( (*(PULONG)uPteAddr & 0x1) != 0 )
return VALID_PAGE;
else
return PTEINVALID;
}
}
else
return PDEINVALID;
} 网上流传的
NOT PAE 模式下,我发现 校验VAROOT地址是否是合法的,结果老外那份到PTE 就空了,测试很多地址基本不合法,
但是网上流传的那份代码,直接if( (*(PULONG)uPdeAddr & 0x80) != 0 )//
{
KdPrint(("uPdeAddr and ok\n"));
return VALID_PAGE;
}
返回合法。这是为虾米,请高手解答下下
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课