是否有允许安全访问 ntoskrnl.exe 地址 space 的内核模式 API

Is there a kernel mode API that allows safe access to ntoskrnl.exe address space

我只是为了好玩(在 Windows 8.1 上)使用内核模式地址 space 试图看看我是否可以访问属于 [= 的地址 space 18=] 来自我的 KMDF 驱动程序。到目前为止,每当我取消引用位于此 PE 的代码 (.text) 部分中的任何内存地址时,我都会 运行 进入 PAGE_FAULT_IN_NONPAGED_AREA 错误检查。是否有 API 允许安全访问此内存?

下面是部分代码:

extern IMAGE_DOS_HEADER* NtBase;

PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_SECTION_HEADER sectionHeader;
UINT64 nSectionCount;

dosHeader = (PIMAGE_DOS_HEADER)NtBase;

if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{       
    PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)((UCHAR*)dosHeader + dosHeader->e_lfanew);

    if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
    {
        sectionHeader = IMAGE_FIRST_SECTION(NtHeader);
        nSectionCount = NtHeader->FileHeader.NumberOfSections;
        
        PIMAGE_OPTIONAL_HEADER64 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER64) & (NtHeader->OptionalHeader);
                    
        UINT64 *BaseOfCodePtr = (UINT64*)pOptionalHeader->BaseOfCode;
        UINT64 SizeofCode = (UINT64)pOptionalHeader->SizeOfCode;
        UINT64 *ImageBasePtr = (UINT64*)pOptionalHeader->ImageBase;
        UINT64 *AbsoluteAddressPtr = (UINT64 *)(pOptionalHeader->ImageBase + pOptionalHeader->BaseOfCode);
        UINT64* AddressofEntryPointPtr = (UINT64*)pOptionalHeader->AddressOfEntryPoint;

        DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "Relative Address of BaseOfCode is %p AND Size of Code is %d\n", pOptionalHeader->BaseOfCode, pOptionalHeader->SizeOfCode);
        DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "Absolute Address is ImageBase + BaseOfCode %p\n", AbsoluteAddressPtr);
        DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "Address of Entry Point is %p\n", AddressofEntryPointPtr);
        DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "SizeofCode - 0x0A is %d\n", SizeofCode - 0x0A);

        UINT64 i = 0x142800, j = 0;
        UINT64 k = 0x14280C;
        UINT64* pNtBase = (UINT64*)NtBase;
        bool found = false;

---->   DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "NTBase at %p + offset of %p = Address %p Value is %p\n", pNtBase, i, *(pNtBase + i)); <----- Crash (BSOD)
        
        for (i = 0x142800; i < k; i++)
        {   
            found = false;
            j = 0;
            
            if (*(pNtBase + i) == pPatch_Info.Signature[j]) // found first byte that matches 
            {
                break;
                DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "Comparing0 pNtBase[%p] = %p .vs. pPatch_Info.Signature[%p] = %p\t\n", i, pNtBase[i], j, pPatch_Info.Signature[j]);
                
                for (j = 1; j < SZ_PATCH_MAX; j++)      // we reach here if the first byte is a match
                {
                    i++;
                    DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "Comparing1 pNtBase[%d] = %p .vs. pPatch_Info.Signature[%d] = %p\t\n", i, pNtBase[i], j, pPatch_Info.Signature[j]);
                    if (*(pNtBase + i) == pPatch_Info.Signature[j])
                    {
                        if (j == (SZ_PATCH_MAX - 1))
                        {
                            found = true;   // found the entire sequence of bytes
                            break;
                        }
                    }
                    else if (*(pNtBase + i) != pPatch_Info.Signature[j])
                    {
                        break;          // don't need to remain in loop
                    }
                }
                
                if(found)
                {
                    break;
                }
            }
        }           
    }   
}
return STATUS_SUCCESS;

只是想与读者分享以下 API 这正是我一直在寻找的。可以在 Microsoft 站点 here.

上找到更多详细信息
MmCopyMemory