L o a d i n g . . .
主打一个C++
文章详情

C++驱动层通过进程虚拟地址获取物理地址

Posted on 2018-01-06 23:35:36 by 主打一个C++

ULONG64 TransformationCR3(ULONG64 _cr3, ULONG64 _virtualAddress)
{
    //将用于对齐的低四位清零
    _cr3 &= ~0xF;
    //获取页面偏移
    ULONG64 page_offset = _virtualAddress & ~(~0UL << 0x0C);
    //读虚拟地址所在的三级页表
    SIZE_T bytesTransferred = 0;
    ULONG64 a = 0, b = 0, c = 0;
    ReadPhysicalAddress((void*)(_cr3 + 0x08 * ((_virtualAddress >> 0x27) & (0x1FFll))), &a, sizeof(a), &bytesTransferred);
    //标志判断是否有映射物理内存,0没有,1有
    if (~a & 1)return 0;
    //读虚拟地址所在的二级页表
    ReadPhysicalAddress((void*)((a & ((~0xFULL << 0x08) & 0xFFFFFFFFFULL)) + 0x08 * ((_virtualAddress >> 0x1E) & (0x1FFLL))), &b, sizeof(b), &bytesTransferred);
    //标志判断是否有映射物理内存,0没有,1有
    if (~b & 1)return 0;
    //如果 PS(页面大小)为1,表示该页表项映射的是1GB的物理内存,直接计算出物理地址并返回
    if (b & 0x80)return (b & (~0ull << 42 >> 12)) + (_virtualAddress & ~(~0ULL << 0x1E));
    //读虚拟地址所在的一级页表
    ReadPhysicalAddress((void*)((b & ((~0xFULL << 0x08) & 0xFFFFFFFFFULL)) + 0x08 * ((_virtualAddress >> 0x15) & (0x1FFll))), &c, sizeof(c), &bytesTransferred);
    //标志判断是否有映射物理内存,0没有,1有
    if (~c & 1)return 0;
    //如果 PS 为1,表示该页表项映射的是2MB的物理内存,直接计算出物理地址并返回
    if (c & 0x80)return (c & ((~0xfull << 8) & 0xFFFFFFFFFULL)) + (_virtualAddress & ~(~0ull << 21));
    //读虚拟地址所在的零级页表,计算出物理地址并返回
    ULONG64 address = 0;
    ReadPhysicalAddress((void*)((c & ((~0xFULL << 0x08) & 0xFFFFFFFFFull)) + 0x08 * ((_virtualAddress >> 0x0C) & (0x1FFll))), &address, sizeof(address), &bytesTransferred);
    address &= ((~0xFULL << 0x08) & 0xFFFFFFFFFULL);
    if (!address)return 0;
    return address + page_offset;
}


*转载请注明出处:原文链接:https://cpp.vin/page/71.html

作者近期文章
  • 随手笔记
  • 主打一个C++   2025-01-11 20:02:01
  • 都2000000025年了。还有不能随意访问guthub的,仔细看。在国内其实是可以正常访问的,gfw并没屏蔽。这里给出其中一个简单直接的方法稳定访问。1. 随便百度一个”dn
提示
×
确定
数据库执行: 8次 总耗时: 0.01s
页面加载耗时: 



wechat +447752296473
wechat cpp-blog