驱动 ReadPhysicalMemory 读写 物理内存 参考代码 win7 64

本文介绍了在Windows 64位环境下,通过ReadPhysicalMemory函数读写物理内存的方法,包括虚拟地址到页表条目的转换、地址安全检查等关键步骤。代码示例中涉及了PML4、PDPTR、PD、PT等页表级别的转换和检查。
摘要由CSDN通过智能技术生成
#pragma warning( disable: 4100 4103 4146 4213)


NTSTATUS  ReadPhysicalMemory (char *startaddress, UINT_PTR bytestoread, void *output);
UINT_PTR KnownPageTableBase = 0;

void VirtualAddressToIndexes(QWORD address, int *pml4index, int *pagedirptrindex, int *pagedirindex, int *pagetableindex)
/*
* Returns the indexes for the given address  (ia32e)
*/
{
        if (PTESize == 8)
        {
                *pml4index = (address >> 39) & 0x1ff;
                *pagedirptrindex = (address >> 30) & 0x1ff;
                *pagedirindex = (address >> 21) & 0x1ff;
                *pagetableindex = (address >> 12) & 0x1ff;
        }
        else
        {
                *pml4index = 0;
                *pagedirptrindex = 0;
                *pagedirindex = (address >> 22) & 0x3ff;
                *pagetableindex = (address >> 12) & 0x3ff;
        }
}

QWORD IndexesToVirtualAddress(int pml4index, int pagedirptrindex, int pagedirindex, int pagetableindex, int offset)
{
        QWORD r;
#ifndef AMD64
        if (PTESize == 8)
        {
#endif
                r = ((QWORD)pml4index & 0x1ff) << 39;

                if (pml4index >= 256)
                        r = r | 0xFFFF000000000000ULL;

                r |= ((QWORD)pagedirptrindex & 0x1ff) << 30;
                r |= ((QWORD)pagedirindex & 0x1ff) << 21;
                r |= ((QWORD)pagetableindex & 0x1ff) << 12;
                r |= offset & 0xfff;

                
#ifndef AMD64
        }
        else
        {
                r |= (pagedirindex & 0x3ff) << 22;
                r |= (pagetableindex & 0x3ff) << 12;
                r |= offset & 0xfff;
        }
#endif

        return r;

}

#ifndef AMD64
void VirtualAddressToPageEntries32(DWORD address, PPDE *pagedirentry, PPTE *pagetableentry)
{
        DWORD PTE = address;
        UINT_PTR PTB = (DWORD)getPageTableBase();
        PTE = PTE >> 12;
        PTE = PTE * 4;
        PTE = PTE + PTB;
        *pagetableentry = (PPTE)PTE;

        UINT_PTR PDE = PTE;
        PDE = PDE & 0x0000ffffffffffffULL;
        PDE = PDE >> 12;
        PDE = PDE * 4;
        PDE = PDE + PTB;
        *pagedirentry = (PPDE)PDE;        
}
#endif

void VirtualAddressToPageEntries64(QWORD address, PPDPTE_PAE *pml4entry, PPDPTE_PAE *pagedirpointerentry, PPDE_PAE *pagedirentry, PPTE_PAE *pagetableentry)
{
        QWORD PTE = address;

        QWORD PTB=getPageTableBase();

        PTE = PTE & 0x0000ffffffffffffULL;
        PTE = PTE >> 12;
        PTE = PTE * 8;
        PTE = PTE + PTB;
        *pagetableentry = (PPTE_PAE)PTE;

        //*pagetableentry = (PPTE_PAE)((((QWORD)address & 0x0000ffffffffffffull) >> 12)*8) + 0xfffff80000000000ULL;

        QWORD PDE = PTE;
        PDE = PDE & 0x0000ffffffffffffULL;
        PDE = PDE >> 12;
        PDE = PDE * 8;
        PDE = PDE + PTB;
        *pagedirentry = (PPDE_PAE)PDE;


        //*pagedirentry = (PPDE_PAE)((((QWORD)*pagetableentry & 0x0000ffffffffffffull )>> 12)*8) + 0xfffff80000000000ULL;

        QWORD PDPTR = PDE;
        PDPTR = PDPTR & 0x0000ffffffffffffULL;
        PDPTR = PDPTR >> 12;
        PDPTR = PDPTR * 8;
        PDPTR = PDPTR + PTB;
        *pagedirpointerentry = (PPDPTE_PAE)PDPTR;

        //*pagedirpointerentry = (PPDPTE_PAE)((((QWORD)*pagedirentry & 0x0000ffffffffffffull )>> 12)*8) + 0xfffff80000000000ULL;
#ifdef AMD64
        QWORD PML4 = PDPTR;
        PML4 = PML4 & 0x0000ffffffffffffULL;
        PML4 = PML4 >> 12;
        PML4 = PML4 * 8;
        PML4 = PML4 + PTB;
        *pml4entry = (PPDPTE_PAE)PML4;
#else
        *pml4entry = NULL;
#endif
}

BOOLEAN IsAddressSafe(UINT_PTR StartAddress)
{
        #ifdef AMD64
        //cannonical check. Bits 48 to 63 must match bit 47
        UINT_PTR toppart=(StartAddress >> 47);
        if (toppart & 1)
        {
                //toppart must be 0x1ffff
                if (toppart != 0x1ffff)
                        return FALSE;
        }
        else
        {
                //toppart must be 0
                if (toppart != 0)
                        return FALSE;

        }

        #endif

        //return TRUE;
        if (loadedbydbvm)
        {
                BYTE x=0;
                UINT_PTR lasterror;
                disableInterrupts();
                vmx_disable_dataPageFaults();

                x=*(volatile BYTE *)StartAddress;

                vmx_enable_dataPageFaults();
                lasterror=vmx_getLastSkippedPageFault();
                enableInterrupts();

                DbgPrint("IsAddressSafe dbvm-mode: lastError=%p\n", lasterror);
                
                if (lasterror) return FALSE;                
        }


        {
#ifdef AMD64
                UINT_PTR kernelbase=0x7fffffffffffffffULL;

                
                if (StartAddress<kernelbase)
                        return TRUE;
                else
                {
                        PHYSICAL_ADDRESS physical;
                        physical.QuadPart=0;
                        physical=MmGetPhysicalAddress((PVOID)StartAddress);
                        return (physical.QuadPart!=0);
                }
#else
        /*        MDL x;

                
                MmProbeAndLockPages(&x,KernelMode,IoModifyAccess);


                MmUnlockPages(&x);
                */
                ULONG kernelbase=0x7ffe0000;

                if ((!HiddenDriver) && (StartAddress<kernelbase))
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值