From 9a5c5fbb134baf4474956ffd83533b5c0006754d Mon Sep 17 00:00:00 2001 From: SpCreatePackaedLicense Date: Thu, 13 Feb 2025 14:54:07 +0000 Subject: O' I do have the right, O' I do have the right --- MIIEow/MIIEow/MIIEow.inf | 28 ++++ MIIEow/MIIEow/MIIEow.sln | 35 +++++ MIIEow/MIIEow/MIIEow.vcxproj | 115 +++++++++++++++ MIIEow/MIIEow/MIIEow.vcxproj.filters | 36 +++++ MIIEow/MIIEow/Source.c | 262 +++++++++++++++++++++++++++++++++++ MIIEow/MIIEow/Undocumented.h | 128 +++++++++++++++++ 6 files changed, 604 insertions(+) create mode 100644 MIIEow/MIIEow/MIIEow.inf create mode 100644 MIIEow/MIIEow/MIIEow.sln create mode 100644 MIIEow/MIIEow/MIIEow.vcxproj create mode 100644 MIIEow/MIIEow/MIIEow.vcxproj.filters create mode 100644 MIIEow/MIIEow/Source.c create mode 100644 MIIEow/MIIEow/Undocumented.h (limited to 'MIIEow') diff --git a/MIIEow/MIIEow/MIIEow.inf b/MIIEow/MIIEow/MIIEow.inf new file mode 100644 index 0000000..7ccc1ef --- /dev/null +++ b/MIIEow/MIIEow/MIIEow.inf @@ -0,0 +1,28 @@ +; +; MIIEow.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=System +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} +Provider=%ManufacturerName% +DriverVer= +CatalogFile=MIIEow.cat +PnpLockdown=1 + +[DestinationDirs] +DefaultDestDir = 13 + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] + +[Manufacturer] + +[Standard.NT$ARCH$.10.0...16299] + +[Strings] +ManufacturerName="" ;TODO: Replace with your manufacturer name +DiskName="MIIEow Source Disk" diff --git a/MIIEow/MIIEow/MIIEow.sln b/MIIEow/MIIEow/MIIEow.sln new file mode 100644 index 0000000..6dacb58 --- /dev/null +++ b/MIIEow/MIIEow/MIIEow.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35013.160 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MIIEow", "MIIEow.vcxproj", "{BBEE9FBF-2223-44A6-9937-BEA956D06E92}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|ARM64.Build.0 = Debug|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|x64.ActiveCfg = Debug|x64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|x64.Build.0 = Debug|x64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Debug|x64.Deploy.0 = Debug|x64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|ARM64.ActiveCfg = Release|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|ARM64.Build.0 = Release|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|ARM64.Deploy.0 = Release|ARM64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|x64.ActiveCfg = Release|x64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|x64.Build.0 = Release|x64 + {BBEE9FBF-2223-44A6-9937-BEA956D06E92}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {67AC022C-5E9C-4E21-BB55-BFE076997E2B} + EndGlobalSection +EndGlobal diff --git a/MIIEow/MIIEow/MIIEow.vcxproj b/MIIEow/MIIEow/MIIEow.vcxproj new file mode 100644 index 0000000..4c4ab77 --- /dev/null +++ b/MIIEow/MIIEow/MIIEow.vcxproj @@ -0,0 +1,115 @@ + + + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {BBEE9FBF-2223-44A6-9937-BEA956D06E92} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + x64 + MIIEow + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + sha256 + + + + + sha256 + + + MinSpace + + + true + + + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MIIEow/MIIEow/MIIEow.vcxproj.filters b/MIIEow/MIIEow/MIIEow.vcxproj.filters new file mode 100644 index 0000000..b303d3c --- /dev/null +++ b/MIIEow/MIIEow/MIIEow.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/MIIEow/MIIEow/Source.c b/MIIEow/MIIEow/Source.c new file mode 100644 index 0000000..46998a7 --- /dev/null +++ b/MIIEow/MIIEow/Source.c @@ -0,0 +1,262 @@ +#include +#include + +#include "Undocumented.h" + +#define DRIVER_NAME "miieow" + +static UNICODE_STRING DriverName; +static UNICODE_STRING DeviceName; +static UNICODE_STRING SymbolicLink; + +NTSTATUS +MwCreate(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp); + +NTSTATUS +MwClose(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp); + +NTSTATUS +MwCtl(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp); + +#define MwCtlReadProcessMemory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define MwCtlWriteProcessMemory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define MwCtlProtectProcessMemory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define MwCtlGetModuleInfo CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) + +struct MwVmRequest +{ + _In_ DWORD ProcessId; + _In_ PVOID Src; + _In_ SIZE_T Size; + _Out_ PVOID Dst; +}; + +struct MwVpRequest +{ + _In_ DWORD ProcessId; + _In_ PVOID Address; + _In_ ULONG NewProt; + _In_ SIZE_T Size; + _Out_ ULONG* pOldProt; +}; + +struct MwMiRequest +{ + _In_ DWORD ProcessId; + _In_ WCHAR Module[256]; + _Out_ PVOID BaseAddr; + _Out_ ULONG Size; +}; + +NTSTATUS +DriverEntry(_In_ PDRIVER_OBJECT pDriverObject, _In_ PUNICODE_STRING pRegistryPath) +{ + UNREFERENCED_PARAMETER(pRegistryPath); + + + NTSTATUS Status = STATUS_SUCCESS; + + RtlInitUnicodeString(&DriverName, L"\\Driver\\" DRIVER_NAME); + RtlInitUnicodeString(&DeviceName, L"\\Device\\" DRIVER_NAME); + RtlInitUnicodeString(&SymbolicLink, L"\\DosDevices\\" DRIVER_NAME); + + if (pDriverObject == NULL) + { + return IoCreateDriver(&DriverName, &DriverEntry); + } + + PDEVICE_OBJECT pDeviceObject = NULL; + Status = IoCreateDevice(pDriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject); + if (Status != STATUS_SUCCESS) + { + return Status; + } + + Status = IoCreateSymbolicLink(&SymbolicLink, &DeviceName); + if (Status != STATUS_SUCCESS) + { + return Status; + } + + SetFlag(pDeviceObject->Flags, DO_BUFFERED_IO); + pDriverObject->MajorFunction[IRP_MJ_CREATE] = MwCreate; + pDriverObject->MajorFunction[IRP_MJ_CLOSE] = MwClose; + pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MwCtl; + + ClearFlag(pDeviceObject->Flags, DO_DEVICE_INITIALIZING); + + return Status; +} + +NTSTATUS +MwCopyVirtualMemory(_In_ PEPROCESS pSourceProcess, _In_ PVOID SourceAddress, _In_ PEPROCESS pDestinationProcess, _In_ PVOID DestinationAddress, _In_ SIZE_T Size) +{ + NTSTATUS Status; + + SIZE_T ReturnSize; + Status = MmCopyVirtualMemory(pSourceProcess, SourceAddress, pDestinationProcess, DestinationAddress, Size, KernelMode, &ReturnSize); + + return Status; +} + +NTSTATUS +MwCreate(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp) +{ + UNREFERENCED_PARAMETER(pDeviceObject); + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + return pIrp->IoStatus.Status; +} + +NTSTATUS +MwClose(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp) +{ + UNREFERENCED_PARAMETER(pDeviceObject); + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + return pIrp->IoStatus.Status; +} + +NTSTATUS +MwCtl(_In_ PDEVICE_OBJECT pDeviceObject, _In_ PIRP pIrp) +{ + UNREFERENCED_PARAMETER(pDeviceObject); + UNREFERENCED_PARAMETER(pIrp); + + NTSTATUS Status = STATUS_SUCCESS; + PEPROCESS pTargetProcess = NULL; + + pIrp->IoStatus.Information = 0; + + PIO_STACK_LOCATION pStackIrp = IoGetCurrentIrpStackLocation(pIrp); + if (pStackIrp == NULL || pIrp->AssociatedIrp.SystemBuffer == NULL) + { + Status = STATUS_UNSUCCESSFUL; + goto Cleanup; + } + + const ULONG ControlCode = pStackIrp->Parameters.DeviceIoControl.IoControlCode; + switch (ControlCode) + { + case MwCtlReadProcessMemory: + { + struct MwVmRequest *Request = (struct MwVmRequest *)pIrp->AssociatedIrp.SystemBuffer; + + Status = PsLookupProcessByProcessId((HANDLE)Request->ProcessId, &pTargetProcess); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + Status = MwCopyVirtualMemory(pTargetProcess, Request->Src, PsGetCurrentProcess(), Request->Dst, Request->Size); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + pIrp->IoStatus.Information = sizeof(struct MwVmRequest); + break; + } + + case MwCtlWriteProcessMemory: + { + struct MwVmRequest* Request = (struct MwVmRequest*)pIrp->AssociatedIrp.SystemBuffer; + + Status = PsLookupProcessByProcessId((HANDLE)Request->ProcessId, &pTargetProcess); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + Status = MwCopyVirtualMemory(PsGetCurrentProcess(), Request->Src, pTargetProcess, Request->Dst, Request->Size); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + pIrp->IoStatus.Information = sizeof(struct MwVmRequest); + break; + } + + case MwCtlProtectProcessMemory: + { + struct MwVpRequest* Request = (struct MwVpRequest*)pIrp->AssociatedIrp.SystemBuffer; + + Status = PsLookupProcessByProcessId((HANDLE)Request->ProcessId, &pTargetProcess); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + // Locals used in usermode address space scope must be stack relative + // due to cr3 being modified. However, the stack is still paged in and + // other normal registers are preserved + PVOID Address = Request->Address; + SIZE_T Size = Request->Size; + ULONG NewProt = Request->NewProt; + ULONG OldProt; + + KAPC_STATE state = { 0 }; + KeStackAttachProcess(pTargetProcess, &state); + { + Status = ZwProtectVirtualMemory(ZwCurrentProcess(), &Address, &Size, NewProt, &OldProt); + } + KeUnstackDetachProcess(&state); + + *Request->pOldProt = OldProt; + pIrp->IoStatus.Information = sizeof(struct MwVpRequest); + break; + } + + case MwCtlGetModuleInfo: + { + struct MwMiRequest* pRequest = (struct MwMiRequest*)pIrp->AssociatedIrp.SystemBuffer; + + Status = PsLookupProcessByProcessId((HANDLE)pRequest->ProcessId, &pTargetProcess); + if (Status != STATUS_SUCCESS) + { + goto Cleanup; + } + + PEB* pPeb = PsGetProcessPeb(pTargetProcess); + + UNICODE_STRING TargetModule; + RtlInitUnicodeString(&TargetModule, pRequest->Module); + + PVOID ModuleBase = NULL; + ULONG ModuleSize = 0; + { + KAPC_STATE State; + KeStackAttachProcess(pTargetProcess, &State); + { + for (PLIST_ENTRY entry = pPeb->Ldr->InLoadOrderModuleList.Flink; entry != &pPeb->Ldr->InLoadOrderModuleList; entry = entry->Flink) + { + PLDR_DATA_TABLE_ENTRY _entry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + if (RtlCompareUnicodeString(&TargetModule, &_entry->BaseDllName, TRUE) == 0) + { + ModuleBase = _entry->DllBase; + ModuleSize = _entry->SizeOfImage; + } + } + } + KeUnstackDetachProcess(&State); + } + + pRequest->BaseAddr = ModuleBase; + pRequest->Size = ModuleSize; + + pIrp->IoStatus.Information = sizeof(struct MwMiRequest); + break; + } + + default: + { + Status = STATUS_UNSUCCESSFUL; + pIrp->IoStatus.Information = 0; + break; + } + } + +Cleanup: + pIrp->IoStatus.Status = Status; + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + return Status; +} \ No newline at end of file diff --git a/MIIEow/MIIEow/Undocumented.h b/MIIEow/MIIEow/Undocumented.h new file mode 100644 index 0000000..95a76c5 --- /dev/null +++ b/MIIEow/MIIEow/Undocumented.h @@ -0,0 +1,128 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +NTKERNELAPI NTSTATUS IoCreateDriver(PUNICODE_STRING DriverName, + PDRIVER_INITIALIZE InitializationFunction); + +NTKERNELAPI NTSTATUS MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, + PEPROCESS TargetProcess, PVOID TargetAddress, + SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, + PSIZE_T ReturnSize); + +NTSTATUS ZwProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID* BaseAddress, + IN OUT SIZE_T* NumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG OldAccessProtection); + +NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process); + +typedef struct _PEB_LDR_DATA +{ + ULONG Length; + UCHAR Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +typedef struct _PEB_LDR_DATA32 +{ + ULONG Length; + UCHAR Initialized; + ULONG SsHandle; + LIST_ENTRY32 InLoadOrderModuleList; + LIST_ENTRY32 InMemoryOrderModuleList; + LIST_ENTRY32 InInitializationOrderModuleList; +} PEB_LDR_DATA32, * PPEB_LDR_DATA32; + +typedef struct _PEB +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR BitField; + PVOID Mutant; + PVOID ImageBaseAddress; + PPEB_LDR_DATA Ldr; + PVOID ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PVOID FastPebLock; + PVOID AtlThunkSListPtr; + PVOID IFEOKey; + PVOID CrossProcessFlags; + PVOID KernelCallbackTable; + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + PVOID ApiSetMap; +} PEB, * PPEB; + +typedef struct _PEB32 +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR BitField; + ULONG Mutant; + ULONG ImageBaseAddress; + ULONG Ldr; + ULONG ProcessParameters; + ULONG SubSystemData; + ULONG ProcessHeap; + ULONG FastPebLock; + ULONG AtlThunkSListPtr; + ULONG IFEOKey; + ULONG CrossProcessFlags; + ULONG UserSharedInfoPtr; + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + ULONG ApiSetMap; +} PEB32, * PPEB32; + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY HashLinks; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + +typedef struct _LDR_DATA_TABLE_ENTRY32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + LIST_ENTRY32 InInitializationOrderLinks; + ULONG DllBase; + ULONG EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING32 FullDllName; + UNICODE_STRING32 BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY32 HashLinks; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32; + +#ifdef __cplusplus +} +#endif \ No newline at end of file -- cgit v1.2.3