mirror of https://github.com/hfiref0x/KDU.git
279 lines
5.6 KiB
C++
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;
|
|
}
|