commit 9a5c5fbb134baf4474956ffd83533b5c0006754d Author: SpCreatePackaedLicense Date: Thu Feb 13 14:54:07 2025 +0000 O' I do have the right, O' I do have the right 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 diff --git a/MIIEowClient/MIIEowClient/MIIEowClient.filters b/MIIEowClient/MIIEowClient/MIIEowClient.filters new file mode 100644 index 0000000..39d20bc --- /dev/null +++ b/MIIEowClient/MIIEowClient/MIIEowClient.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 + + + + + Source Files + + + \ No newline at end of file diff --git a/MIIEowClient/MIIEowClient/MIIEowClient.sln b/MIIEowClient/MIIEowClient/MIIEowClient.sln new file mode 100644 index 0000000..7a44a00 --- /dev/null +++ b/MIIEowClient/MIIEowClient/MIIEowClient.sln @@ -0,0 +1,31 @@ + +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}") = "MIIEowClient", "MIIEowClient.vcxproj", "{F69369ED-3072-418D-9621-BDDEF9AC9194}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Debug|x64.ActiveCfg = Debug|x64 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Debug|x64.Build.0 = Debug|x64 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Debug|x86.ActiveCfg = Debug|Win32 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Debug|x86.Build.0 = Debug|Win32 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Release|x64.ActiveCfg = Release|x64 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Release|x64.Build.0 = Release|x64 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Release|x86.ActiveCfg = Release|Win32 + {F69369ED-3072-418D-9621-BDDEF9AC9194}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6387F977-68F6-4156-8B73-29EA132E9A44} + EndGlobalSection +EndGlobal diff --git a/MIIEowClient/MIIEowClient/MIIEowClient.user b/MIIEowClient/MIIEowClient/MIIEowClient.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/MIIEowClient/MIIEowClient/MIIEowClient.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj b/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj new file mode 100644 index 0000000..98b46ae --- /dev/null +++ b/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {f69369ed-3072-418d-9621-bddef9ac9194} + PhoneAct + 10.0 + MIIEowClient + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj.user b/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/MIIEowClient/MIIEowClient/MIIEowClient.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MIIEowClient/MIIEowClient/Source.c b/MIIEowClient/MIIEowClient/Source.c new file mode 100644 index 0000000..7735769 --- /dev/null +++ b/MIIEowClient/MIIEowClient/Source.c @@ -0,0 +1,271 @@ +#include +#include +#include + +/* ------------------------------- CFG ------------------------------- */ + +#include +#pragma comment(lib, "slc.lib") + +#define DRIVER_NAME L"miieow" + +#define PROCESS_NAME L"sppsvc.exe" +#define MODULE_NAME L"sppsvc.exe" + +#define OFFSET 0 +#define SIGNATURE_SZ 10 +#define SIGNATURE { 0x8B, 0x7D, 0x00, 0x85, 0xFF, 0x75, 0x00, 0x49, 0x8B, 0x06 } +#define MASK { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 } + +#define PATCH { 0x31, 0xff, 0x90 } +#define PATCH_SZ 3 + +static HSLC hSLC = NULL; +void Pre() +{ + // Spin up an sppsvc.exe instance + SLOpen(&hSLC); +} + +void Post() +{ + SLClose(hSLC); +} + +/* ------------------------------- CFG ------------------------------- */ + + +/* --------------------------- MIIEow API --------------------------- */ + +// MIIEow Interface +#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; +}; +// MIIEow Interface + +struct MIIEow +{ + HANDLE hDriver; + DWORD ProcessId; +}; + +struct MIIEow* +MwcCreate(_In_ DWORD ProcessId) +{ + struct MIIEow* pMIIEow = (struct MIIEow*)malloc(sizeof(struct MIIEow)); + if (pMIIEow != NULL) + { + pMIIEow->ProcessId = ProcessId; + pMIIEow->hDriver = CreateFileW(L"\\\\.\\" DRIVER_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + return pMIIEow; + } + else + { + MessageBoxW(NULL, L"Failed to init Mwc", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } +} + +void +MwcReadProcessMemory(struct MIIEow *pMIIEow, _In_ PVOID Address, _In_ SIZE_T Size, _Out_ PVOID pBuffer) +{ + struct MwVmRequest r; + r.ProcessId = pMIIEow->ProcessId; + r.Src = Address; + r.Dst = pBuffer; + r.Size = Size; + + if (DeviceIoControl(pMIIEow->hDriver, MwCtlReadProcessMemory, (PVOID)&r, sizeof(r), (PVOID)&r, sizeof(r), NULL, NULL) == FALSE) + { + MessageBoxW(NULL, L"Failed to read memory", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } +} + +void +MwcWriteProcessMemory(struct MIIEow* pMIIEow, _In_ PVOID Address, _In_ SIZE_T Size, _In_ PVOID pBuffer) +{ + struct MwVmRequest r; + r.ProcessId = pMIIEow->ProcessId; + r.Src = pBuffer; + r.Dst = Address; + r.Size = Size; + + if (DeviceIoControl(pMIIEow->hDriver, MwCtlWriteProcessMemory, (PVOID)&r, sizeof(r), (PVOID)&r, sizeof(r), NULL, NULL) == FALSE) + { + MessageBoxW(NULL, L"Failed to write memory", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } +} + +void +MwcProtectProcessMemory(struct MIIEow* pMIIEow, _In_ PVOID Address, _In_ SIZE_T Size, _In_ ULONG NewProt, _Out_ ULONG* pOldProt) +{ + struct MwVpRequest r; + r.ProcessId = pMIIEow->ProcessId; + r.Address = Address; + r.NewProt = NewProt; + r.Size = Size; + r.pOldProt = pOldProt; + + if (DeviceIoControl(pMIIEow->hDriver, MwCtlProtectProcessMemory, (PVOID)&r, sizeof(r), (PVOID)&r, sizeof(r), NULL, NULL) == FALSE) + { + MessageBoxW(NULL, L"Failed to virtual protect memory", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } +} + +struct MwMiRequest +MwcGetModuleInfo(struct MIIEow* pMIIEow, LPCWSTR ModuleName) +{ + struct MwMiRequest r; + r.ProcessId = pMIIEow->ProcessId; + wcscpy_s(r.Module, 256, ModuleName); + + if (DeviceIoControl(pMIIEow->hDriver, MwCtlGetModuleInfo, (PVOID)&r, sizeof(r), (PVOID)&r, sizeof(r), NULL, NULL) == FALSE) + { + MessageBoxW(NULL, L"Failed to get base address", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } + + return r; +} + +void +MwcDelete(struct MIIEow* pMIIEow) +{ + if (pMIIEow != NULL) + { + if (pMIIEow->hDriver != INVALID_HANDLE_VALUE) + { + CloseHandle(pMIIEow->hDriver); + } + free(pMIIEow); + } +} + +/* --------------------------- MIIEow API --------------------------- */ + +PVOID +SignatureScan(struct MIIEow* pMIIEow, PVOID BaseAddress, SIZE_T Size) +{ + PVOID EndAddress = (PVOID)((SIZE_T)BaseAddress + Size); + + const BYTE Signature[SIGNATURE_SZ] = SIGNATURE; + const BYTE Mask[SIGNATURE_SZ] = MASK; + + for (BYTE* Address = BaseAddress; Address < ((SIZE_T)EndAddress - SIGNATURE_SZ); Address++) + { + // TODO: Do this by page, ioctl is expensive + BYTE Buffer[SIGNATURE_SZ] = { 0 }; + MwcReadProcessMemory(pMIIEow, Address, SIGNATURE_SZ, Buffer); + + BOOL Found = TRUE; + for (int i = 0; i < SIGNATURE_SZ; i++) + { + if (Mask[i] == 0 && Buffer[i] != Signature[i]) + { + Found = FALSE; + break; + } + } + if (Found) return Address + OFFSET; + } + return NULL; +} + + +DWORD +GetProcessIdByName(LPCWSTR processName) +{ + PROCESSENTRY32 Entry; + Entry.dwSize = sizeof(PROCESSENTRY32); + HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); + + if (Process32First(Snapshot, &Entry) == TRUE) + { + while (Process32Next(Snapshot, &Entry) == TRUE) + { + if (_wcsicmp(Entry.szExeFile, processName) == 0) + { + CloseHandle(Snapshot); + return Entry.th32ProcessID; + } + } + } + CloseHandle(Snapshot); + return (DWORD)-1; +} + +int main() +{ + Pre(); + + LPCWSTR TargetProcessName = PROCESS_NAME; + DWORD ProcessId = GetProcessIdByName(TargetProcessName); + + if (ProcessId == (DWORD)-1) + { + MessageBoxW(NULL, L"Failed to find target process", L"Error", MB_OK | MB_ICONERROR); + ExitProcess(1); + } + printf("[+] Located target process\n"); + + struct MIIEow* pMIIEow = MwcCreate(ProcessId); + printf("[+] MIIEow initialised\n"); + + struct MwMiRequest ModuleInfo = MwcGetModuleInfo(pMIIEow, MODULE_NAME); + printf("[+] Got base address : %zx\n", (SIZE_T)ModuleInfo.BaseAddr); + + PVOID PatchAddr = SignatureScan(pMIIEow, ModuleInfo.BaseAddr, ModuleInfo.Size); + printf("[+] Scan result : %zx\n", (SIZE_T)PatchAddr); + + BYTE SanityByte; + MwcReadProcessMemory(pMIIEow, PatchAddr, 1, &SanityByte); + printf("[+] Sanity byte : %zx\n", (SIZE_T)SanityByte); + + ULONG OldProt; + MwcProtectProcessMemory(pMIIEow, PatchAddr, 4096, PAGE_EXECUTE_READWRITE, &OldProt); + + printf("[+] Set protection to RWX\n"); + + const BYTE Patch[PATCH_SZ] = PATCH; + MwcWriteProcessMemory(pMIIEow, PatchAddr, 4, Patch); + printf("[+] Patched\n"); + + ULONG _; + MwcProtectProcessMemory(pMIIEow, PatchAddr, 4096, OldProt, &_); + printf("[+] Restored protection\n"); + + MwcDelete(pMIIEow); + + Post(); + + return 0; +} diff --git a/sppdebug.reg b/sppdebug.reg new file mode 100644 index 0000000..5691617 Binary files /dev/null and b/sppdebug.reg differ