You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.6 KiB
92 lines
2.6 KiB
#include "Common.h"
|
|
#include <ntimage.h>
|
|
|
|
EXTERN_C
|
|
__int64 __fastcall fnMmLoadSystemImage(
|
|
struct _UNICODE_STRING *DrvName,
|
|
const UNICODE_STRING *a2,
|
|
UNICODE_STRING *a3,
|
|
unsigned int a4_win32k_status,
|
|
ULONG64 *SectionPointer,
|
|
ULONG64 *BaseAddress);
|
|
|
|
EXTERN_C
|
|
PIMAGE_NT_HEADERS
|
|
NTAPI
|
|
RtlImageNtHeader(PVOID Base);
|
|
|
|
__declspec(
|
|
noinline) long CallMeWin32kDriver(wchar_t *DriverPath, unsigned long DriverPathLength, bool NeedPrefix /*= true*/)
|
|
{
|
|
long lStatus = -1;
|
|
|
|
unsigned long uDriverPathAllLength = DriverPathLength;
|
|
|
|
do
|
|
{
|
|
if (!DriverPath || !DriverPathLength)
|
|
{
|
|
break;
|
|
}
|
|
|
|
wchar_t wszDriverPath[MAX_PATH + 1];
|
|
RtlSecureZeroMemory(wszDriverPath, sizeof(wszDriverPath));
|
|
|
|
if (NeedPrefix)
|
|
{
|
|
strcat_w(wszDriverPath, (L"\\??\\"));
|
|
}
|
|
|
|
if (DriverPathLength < MAX_PATH * sizeof(wchar_t))
|
|
{
|
|
strcat_w(wszDriverPath, DriverPath);
|
|
if (NeedPrefix)
|
|
{
|
|
uDriverPathAllLength += 4 * sizeof(wchar_t);
|
|
}
|
|
}
|
|
|
|
UNICODE_STRING usDriverName;
|
|
usDriverName.Buffer = wszDriverPath;
|
|
usDriverName.Length = (USHORT)uDriverPathAllLength;
|
|
usDriverName.MaximumLength = MAX_PATH * sizeof(wchar_t);
|
|
|
|
UNICODE_STRING usMmLoadSystemImage;
|
|
RtlInitUnicodeString(&usMmLoadSystemImage, L"MmLoadSystemImage");
|
|
|
|
auto pMmLoadSystemImage = (decltype(&fnMmLoadSystemImage))(MmGetSystemRoutineAddress(&usMmLoadSystemImage));
|
|
if (pMmLoadSystemImage)
|
|
{
|
|
ULONG64 uSectionPointer = 0, uBaseAddress = 0;
|
|
lStatus = pMmLoadSystemImage(&usDriverName, 0, 0, 1, &uSectionPointer, &uBaseAddress);
|
|
if (NT_SUCCESS(lStatus) && uBaseAddress)
|
|
{
|
|
auto pImageNtHeader = RtlImageNtHeader((void *)uBaseAddress);
|
|
if (pImageNtHeader)
|
|
{
|
|
// Fake Driver Object
|
|
auto pNewDrvObj = (PDRIVER_OBJECT)ExAllocatePool(NonPagedPool, 0x1000);
|
|
if (!pNewDrvObj)
|
|
{
|
|
__asm {int 3 }
|
|
}
|
|
|
|
RtlSecureZeroMemory(pNewDrvObj, 0x1000);
|
|
pNewDrvObj->DriverStart = (PVOID)uBaseAddress;
|
|
|
|
// Call OEP
|
|
auto pOEP = (PDRIVER_INITIALIZE)(uBaseAddress + pImageNtHeader->OptionalHeader.AddressOfEntryPoint);
|
|
lStatus = pOEP(pNewDrvObj, nullptr);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lStatus = STATUS_NOT_SUPPORTED;
|
|
}
|
|
|
|
} while (0);
|
|
|
|
return lStatus;
|
|
}
|