更安全的MmIsAddressValid

来源:互联网 发布:淘宝 服务器品牌 编辑:程序博客网 时间:2024/05/16 13:55

代码来着开源工具

CheatEngine


在初始化是先调用InitMemSafe()

然后就可以使用IsAddressSafe来代替MmIsAddressValid了

int PTESize;UINT_PTR PAGE_SIZE_LARGE;UINT_PTR MAX_PDE_POS;UINT_PTR MAX_PTE_POS;struct PTEStruct{unsigned P         :  1; // present (1 = present)unsigned RW        :  1; // read/writeunsigned US        :  1; // user/supervisorunsigned PWT       :  1; // page-level write-throughunsigned PCD       :  1; // page-level cache disabledunsigned A         :  1; // accessedunsigned Reserved  :  1; // dirtyunsigned PS        :  1; // page size (0 = 4-KB page)unsigned G         :  1; // global pageunsigned A1   :  1; // available 1 aka copy-on-writeunsigned A2   :  1; // available 2/ is 1 when paged to diskunsigned A3   :  1; // available 3unsigned PFN       : 20; // page-frame number};void InitMemSafe(){#ifndef AMD64ULONG cr4reg;    //determine if PAE is usedcr4reg=(ULONG)__readcr4();if ((cr4reg & 0x20)==0x20){PTESize=8; //paePAGE_SIZE_LARGE=0x200000;MAX_PDE_POS=0xC0604000;MAX_PTE_POS=0xC07FFFF8;}else{PTESize=4;PAGE_SIZE_LARGE=0x400000;MAX_PDE_POS=0xC0301000;MAX_PTE_POS=0xC03FFFFC;}#elsePTESize=8; //paePAGE_SIZE_LARGE=0x200000;MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL;MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL;#endif}BOOLEAN IsAddressSafe(UINT_PTR StartAddress){#ifdef AMD64//cannonical check. Bits 48 to 63 must match bit 47UINT_PTR toppart=(StartAddress >> 47);if (toppart & 1){//toppart must be 0x1ffffif (toppart != 0x1ffff)return FALSE;}else{//toppart must be 0if (toppart != 0)return FALSE;}#endif//PDT+PTE judge{#ifdef AMD64UINT_PTR kernelbase=0x7fffffffffffffffULL;if (StartAddress<kernelbase){return TRUE;}else{PHYSICAL_ADDRESS physical;physical.QuadPart=0;physical=MmGetPhysicalAddress((PVOID)StartAddress);return (physical.QuadPart!=0);}return TRUE; //for now untill I ave figure out the win 4 paging scheme#elseULONG kernelbase=0x7ffe0000;UINT_PTR PTE,PDE;struct PTEStruct *x;if (StartAddress<kernelbase){return TRUE;}PTE=(UINT_PTR)StartAddress;PTE=PTE/0x1000*PTESize+0xc0000000;//now check if the address in PTE is valid by checking the page table directory at 0xc0300000 (same location as CR3 btw)PDE=PTE/0x1000*PTESize+0xc0000000; //same formulax=(struct PTEStruct *)PDE;if ((x->P==0) && (x->A2==0)){//Not present or paged, and since paging in this area isn't such a smart thing to do just skip it//perhaps this is only for the 4 mb pages, but those should never be paged out, so it should be 1//bah, I've got no idea what this is used forreturn FALSE;}if (x->PS==1){//This is a 4 MB page (no pte list)//so, (startaddress/0x400000*0x400000) till ((startaddress/0x400000*0x400000)+(0x400000-1) ) ) is specified by this page}else //if it's not a 4 MB page then check the PTE{//still here so the page table directory agreed that it is a usable page table entryx=(PVOID)PTE;if ((x->P==0) && (x->A2==0))return FALSE; //see for explenation the part of the PDE}return TRUE;#endif}}


2 0
原创粉丝点击