'Is there a kernel mode API that allows safe access to ntoskrnl.exe address space
I'm just playing around for fun only(on Windows 8.1) with kernel mode address space trying to see if I can access the address space belonging to ntoskrnl.exe from my KMDF driver. So far I've run into PAGE_FAULT_IN_NONPAGED_AREA bugchecks whenever I dereference any memory address situated in the code (.text) section of this PE. Is there a API that will allow safe access to this memory ?
Here is some of the code:
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;
Solution 1:[1]
Just wanted to share with readers the following API which is exactly what I have been looking for. Further details can be found on the Microsoft site here.
MmCopyMemory
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jonny B Good |