看流星社区

 找回密码
 注册账号
查看: 1679|回复: 0

更安全的MmIsAddressValid

[复制链接]

该用户从未签到

发表于 2017-6-1 12:52:11 | 显示全部楼层 |阅读模式
代码来着开源工具
CheatEngine



在初始化是先调用InitMemSafe()
然后就可以使用IsAddressSafe来代替MmIsAddressValid了
  1. int PTESize;
  2. UINT_PTR PAGE_SIZE_LARGE;
  3. UINT_PTR MAX_PDE_POS;
  4. UINT_PTR MAX_PTE_POS;
  5. struct PTEStruct
  6. {
  7.         unsigned P         :  1; // present (1 = present)
  8.         unsigned RW        :  1; // read/write
  9.         unsigned US        :  1; // user/supervisor
  10.         unsigned PWT       :  1; // page-level write-through
  11.         unsigned PCD       :  1; // page-level cache disabled
  12.         unsigned A         :  1; // accessed
  13.         unsigned Reserved  :  1; // dirty
  14.         unsigned PS        :  1; // page size (0 = 4-KB page)
  15.         unsigned G         :  1; // global page
  16.         unsigned A1                   :  1; // available 1 aka copy-on-write
  17.         unsigned A2                   :  1; // available 2/ is 1 when paged to disk
  18.         unsigned A3                   :  1; // available 3
  19.         unsigned PFN       : 20; // page-frame number
  20. };
  21. void InitMemSafe()
  22. {
  23. #ifndef AMD64
  24.         ULONG cr4reg;
  25.     //determine if PAE is used
  26.         cr4reg=(ULONG)__readcr4();
  27.         if ((cr4reg & 0x20)==0x20)
  28.         {
  29.                 PTESize=8; //pae
  30.                 PAGE_SIZE_LARGE=0x200000;
  31.                 MAX_PDE_POS=0xC0604000;
  32.                 MAX_PTE_POS=0xC07FFFF8;
  33.         }
  34.         else
  35.         {
  36.                 PTESize=4;
  37.                 PAGE_SIZE_LARGE=0x400000;
  38.                 MAX_PDE_POS=0xC0301000;
  39.                 MAX_PTE_POS=0xC03FFFFC;
  40.         }
  41. #else
  42.         PTESize=8; //pae
  43.         PAGE_SIZE_LARGE=0x200000;
  44.         MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL;
  45.         MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL;
  46. #endif
  47. }
  48. BOOLEAN IsAddressSafe(UINT_PTR StartAddress)
  49. {
  50.         #ifdef AMD64
  51.         //cannonical check. Bits 48 to 63 must match bit 47
  52.         UINT_PTR toppart=(StartAddress >> 47);
  53.         if (toppart & 1)
  54.         {
  55.                 //toppart must be 0x1ffff
  56.                 if (toppart != 0x1ffff)
  57.                         return FALSE;
  58.         }
  59.         else
  60.         {
  61.                 //toppart must be 0
  62.                 if (toppart != 0)
  63.                         return FALSE;
  64.         }
  65.         #endif
  66.         //PDT+PTE judge
  67.         {
  68.         #ifdef AMD64
  69.                 UINT_PTR kernelbase=0x7fffffffffffffffULL;
  70.                 if (StartAddress<kernelbase)
  71.                 {
  72.                         return TRUE;
  73.                 }
  74.                 else
  75.                 {
  76.                         PHYSICAL_ADDRESS physical;
  77.                         physical.QuadPart=0;
  78.                         physical=MmGetPhysicalAddress((PVOID)StartAddress);
  79.                         return (physical.QuadPart!=0);
  80.                 }
  81.                 return TRUE; //for now untill I ave figure out the win 4 paging scheme
  82.         #else
  83.                 ULONG kernelbase=0x7ffe0000;
  84.                 UINT_PTR PTE,PDE;
  85.                 struct PTEStruct *x;
  86.                 if (StartAddress<kernelbase)
  87.                 {
  88.                         return TRUE;
  89.                 }
  90.                 PTE=(UINT_PTR)StartAddress;
  91.                 PTE=PTE/0x1000*PTESize+0xc0000000;
  92.                 //now check if the address in PTE is valid by checking the page table directory at 0xc0300000 (same location as CR3 btw)
  93.                 PDE=PTE/0x1000*PTESize+0xc0000000; //same formula
  94.                 x=(struct PTEStruct *)PDE;
  95.                 if ((x->P==0) && (x->A2==0))
  96.                 {
  97.                         //Not present or paged, and since paging in this area isn't such a smart thing to do just skip it
  98.                         //perhaps this is only for the 4 mb pages, but those should never be paged out, so it should be 1
  99.                         //bah, I've got no idea what this is used for
  100.                         return FALSE;
  101.                 }
  102.                 if (x->PS==1)
  103.                 {
  104.                         //This is a 4 MB page (no pte list)
  105.                         //so, (startaddress/0x400000*0x400000) till ((startaddress/0x400000*0x400000)+(0x400000-1) ) ) is specified by this page
  106.                 }
  107.                 else //if it's not a 4 MB page then check the PTE
  108.                 {
  109.                         //still here so the page table directory agreed that it is a usable page table entry
  110.                         x=(PVOID)PTE;
  111.                         if ((x->P==0) && (x->A2==0))
  112.                                 return FALSE; //see for explenation the part of the PDE
  113.                 }
  114.                 return TRUE;
  115.         #endif
  116.         }
  117. }
复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 12:10

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表