diff options
author | segfault <toni@impl.cc> | 2020-12-12 20:08:22 +0100 |
---|---|---|
committer | segfault <toni@impl.cc> | 2020-12-12 20:08:22 +0100 |
commit | 2c2383838ce791392782aeb5ca3cd0607c92e22e (patch) | |
tree | 477fa41c75fae922c33f7b63ed07c9a23a826a76 | |
parent | 444b885aa818e7a4a91870181950b260a53b8fc9 (diff) |
Added KMemDriver GetProcesses to enumerate all processes from kernel space.
* fixed missing NUL termination for converted ASCII strings
-rw-r--r-- | IntegrationTest/IntegrationTest.cpp | 45 | ||||
-rw-r--r-- | KMemDriver/KMemDriver.c | 72 | ||||
-rw-r--r-- | KMemDriver/Memory.c | 46 | ||||
-rw-r--r-- | MemDriverLib/MemDriverLib.cpp | 28 | ||||
-rw-r--r-- | include/KInterface.h | 15 | ||||
-rw-r--r-- | include/KMemDriver.h | 63 |
6 files changed, 215 insertions, 54 deletions
diff --git a/IntegrationTest/IntegrationTest.cpp b/IntegrationTest/IntegrationTest.cpp index c7bd04c..6a53d94 100644 --- a/IntegrationTest/IntegrationTest.cpp +++ b/IntegrationTest/IntegrationTest.cpp @@ -18,10 +18,10 @@ int main() { HANDLE this_pid = (HANDLE)((ULONG_PTR)GetCurrentProcessId()); + KInterface& ki = KInterface::getInstance(); KM_ASSERT_EQUAL(true, true, "Integration Test Init"); try { - KInterface& ki = KInterface::getInstance(); KM_ASSERT_EQUAL(true, ki.Init(), "Kernel Interface Init"); KM_ASSERT_EQUAL(true, ki.Handshake(), "Kernel Interface Handshake"); KM_ASSERT_EQUAL(true, ki.getBuffer() != NULL, "Kernel Interface Buffer != NULL"); @@ -32,10 +32,49 @@ int main() KM_ASSERT_EQUAL(true, ki.Ping(), "Kernel Interface PING - PONG #3"); { + SIZE_T required_processes_found = 0; + std::vector<PROCESS_DATA> processes; + KM_ASSERT_EQUAL(true, ki.Processes(processes), "Kernel Interface Processes"); + KM_ASSERT_EQUAL(0, ki.getLastNtStatus(), "Last NtStatus"); + + for (auto& process : processes) + { + //std::cout << "Process Name: " << process.ImageName << std::endl; + if (strcmp(process.ImageName, "IntegrationTest-kmem.exe") == 0 && strlen(process.ImageName) == strlen("IntegrationTest-kmem.exe")) + { + required_processes_found++; + } + if (strcmp(process.ImageName, "System") == 0 && strlen(process.ImageName) == strlen("System")) + { + required_processes_found++; + } + if (strcmp(process.ImageName, "Registry") == 0 && strlen(process.ImageName) == strlen("Registry")) + { + required_processes_found++; + } + if (strcmp(process.ImageName, "wininit.exe") == 0 && strlen(process.ImageName) == strlen("wininit.exe")) + { + required_processes_found++; + } + if (strcmp(process.ImageName, "winlogon.exe") == 0 && strlen(process.ImageName) == strlen("winlogon.exe")) + { + required_processes_found++; + } + if (strcmp(process.ImageName, "lsass.exe") == 0 && strlen(process.ImageName) == strlen("lsass.exe")) + { + required_processes_found++; + } + } + KM_ASSERT_EQUAL(6, required_processes_found, "Kernel Interface Modules (6 required found)"); + } + + { SIZE_T required_modules_found = 0; std::vector<MODULE_DATA> modules; KM_ASSERT_EQUAL(true, ki.Modules(this_pid, modules), "Kernel Interface Modules"); + KM_ASSERT_EQUAL(0, ki.getLastNtStatus(), "Last NtStatus"); for (auto& module : modules) { + //std::cout << "DLL Name: " << module.BaseDllName << std::endl; if (strcmp(module.BaseDllName, "IntegrationTest-kmem.exe") == 0 && strlen(module.BaseDllName) == strlen("IntegrationTest-kmem.exe")) { required_modules_found++; @@ -56,6 +95,7 @@ int main() SIZE_T found_shmaddr = 0; std::vector<MEMORY_BASIC_INFORMATION> pages; KM_ASSERT_EQUAL(true, ki.Pages(this_pid, pages), "Kernel Interface Pages"); + KM_ASSERT_EQUAL(0, ki.getLastNtStatus(), "Last NtStatus"); for (auto& page : pages) { if (page.BaseAddress == (PVOID)SHMEM_ADDR && page.RegionSize == SHMEM_SIZE) { found_shmaddr++; @@ -89,6 +129,7 @@ int main() std::wcout << "Done." << std::endl; error: - std::wcout << std::endl << "[PRESS RETURN KEY TO EXIT]" << std::endl; + ki.Exit(); + std::wcout << std::endl << "KMemDriver Shutdown [PRESS RETURN KEY TO EXIT]" << std::endl; getchar(); }
\ No newline at end of file diff --git a/KMemDriver/KMemDriver.c b/KMemDriver/KMemDriver.c index 0350c81..4c7592f 100644 --- a/KMemDriver/KMemDriver.c +++ b/KMemDriver/KMemDriver.c @@ -167,6 +167,60 @@ NTSTATUS DriverEntry( return status; } +NTSTATUS GetProcesses(OUT PROCESS_DATA* procs, IN OUT SIZE_T* psiz) +{ + SIZE_T const max_siz = *psiz; + ULONG mem_needed = 0; + + NTSTATUS status = ZwQuerySystemInformation(0x05, NULL, 0, &mem_needed); + if (!NT_SUCCESS(status) && mem_needed == 0) { + KDBG("NtQuerySystemInformation(ReturnLength: %lu) failed with 0x%X\n", mem_needed, status); + return status; + } + + if (mem_needed / sizeof(SYSTEM_PROCESS_INFORMATION) > max_siz / sizeof(PROCESS_DATA)) { + KDBG("NtQuerySystemInformation buffer too small\n", status); + return STATUS_BUFFER_TOO_SMALL; + } + + SYSTEM_PROCESS_INFORMATION* sysinfo = MmAllocateNonCachedMemory(mem_needed); + if (sysinfo == NULL) { + return STATUS_NO_MEMORY; + } + + status = ZwQuerySystemInformation(0x05, sysinfo, mem_needed, NULL); + if (!NT_SUCCESS(status)) { + KDBG("NtQuerySystemInformation(SystemInformationLength: %lu) failed with 0x%X\n", mem_needed, status); + goto free_memory; + } + + *psiz = 0; + SYSTEM_PROCESS_INFORMATION* cur_proc = sysinfo; + while (cur_proc->NextEntryOffset > 0 && *psiz < max_siz) { + cur_proc = (SYSTEM_PROCESS_INFORMATION*)((PUCHAR)cur_proc + cur_proc->NextEntryOffset); + + ANSI_STRING name; + if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &cur_proc->ImageName, TRUE))) { + SIZE_T len = (name.Length >= sizeof(procs->ImageName) ? sizeof(procs->ImageName) - 1 : name.Length); + RtlCopyMemory(procs->ImageName, name.Buffer, len); + procs->ImageName[len] = '\0'; + RtlFreeAnsiString(&name); + } + + procs->NumberOfThreads = cur_proc->NumberOfThreads; + procs->UniqueProcessId = cur_proc->UniqueProcessId; + procs->HandleCount = cur_proc->HandleCount; + + *psiz += sizeof(procs[0]); + procs++; + } + KDBG("Found %zu processes\n", *psiz / sizeof(*procs)); + +free_memory: + MmFreeNonCachedMemory(sysinfo, mem_needed); + return status; +} + NTSTATUS WaitForControlProcess(OUT PEPROCESS* ppEProcess) { NTSTATUS status; @@ -418,6 +472,24 @@ NTSTATUS KRThread(IN PVOID pArg) KeWriteVirtualMemory(ctrlPEP, ping, (PVOID)SHMEM_ADDR, &siz); break; } + case MEM_PROCESSES: { + PKERNEL_PROCESSES_REQUEST procs = (PKERNEL_PROCESSES_REQUEST)shm_buf; + PROCESS_DATA* data = (PPROCESS_DATA)(procs + 1); + siz = SHMEM_SIZE - sizeof(*procs); + //siz = sizeof(*data) * 128; + KDBG("Got a PROCESSES request\n"); + + procs->ProcessCount = 0; + procs->StatusRes = GetProcesses(data, &siz); + if (!NT_SUCCESS(procs->StatusRes)) + { + break; + } + + procs->ProcessCount = siz / sizeof(*data); + KeWriteVirtualMemory(ctrlPEP, procs, (PVOID)SHMEM_ADDR, &siz); + break; + } case MEM_PAGES: { PKERNEL_PAGE pages = (PKERNEL_PAGE)shm_buf; KDBG("Got a PAGES request for process 0x%X start at address 0x%p\n", diff --git a/KMemDriver/Memory.c b/KMemDriver/Memory.c index 2b0621b..86d3f8c 100644 --- a/KMemDriver/Memory.c +++ b/KMemDriver/Memory.c @@ -7,8 +7,8 @@ NTSTATUS GetPages( IN PEPROCESS Process, - OUT MEMORY_BASIC_INFORMATION *mbiArr, - IN SIZE_T mbiArrLen, OUT SIZE_T *mbiUsed, + OUT MEMORY_BASIC_INFORMATION* mbiArr, + IN SIZE_T mbiArrLen, OUT SIZE_T* mbiUsed, IN PVOID start_addr ) { @@ -31,8 +31,8 @@ NTSTATUS GetPages( do { mbiReturn = 0; status = ZwQueryVirtualMemory(procHandle, (PVOID)baseAddr, - MemoryBasicInformation, mbiArr, sizeof *mbiArr * mbiArrLen, &mbiReturn); - mbiLength = mbiReturn / sizeof *mbiArr; + MemoryBasicInformation, mbiArr, sizeof * mbiArr * mbiArrLen, &mbiReturn); + mbiLength = mbiReturn / sizeof * mbiArr; if (!NT_SUCCESS(status)) { if (status == STATUS_INVALID_PARAMETER) status = STATUS_SUCCESS; @@ -58,7 +58,7 @@ NTSTATUS GetPages( NTSTATUS GetModules( IN PEPROCESS Process, - OUT PMODULE_DATA pmod, IN OUT SIZE_T *psiz, + OUT PMODULE_DATA pmod, IN OUT SIZE_T* psiz, IN SIZE_T start_index, IN BOOLEAN isWow64 ) @@ -106,20 +106,18 @@ NTSTATUS GetModules( tmpUnicodeStr.Length = ldrEntry32->BaseDllName.Length; tmpUnicodeStr.MaximumLength = ldrEntry32->BaseDllName.MaximumLength; if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &tmpUnicodeStr, TRUE))) { - RtlCopyMemory(pmod->BaseDllName, name.Buffer, - (name.Length > sizeof pmod->BaseDllName ? - sizeof pmod->BaseDllName : name.Length) - ); + SIZE_T len = (name.Length >= sizeof(pmod->BaseDllName) ? sizeof(pmod->BaseDllName) - 1 : name.Length); + RtlCopyMemory(pmod->BaseDllName, name.Buffer, len); + pmod->BaseDllName[len] = '\0'; RtlFreeAnsiString(&name); } tmpUnicodeStr.Buffer = (PWCH)ldrEntry32->FullDllName.Buffer; tmpUnicodeStr.Length = ldrEntry32->FullDllName.Length; tmpUnicodeStr.MaximumLength = ldrEntry32->FullDllName.MaximumLength; if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &tmpUnicodeStr, TRUE))) { - RtlCopyMemory(pmod->FullDllPath, name.Buffer, - (name.Length > sizeof pmod->FullDllPath ? - sizeof pmod->FullDllPath : name.Length) - ); + SIZE_T len = (name.Length >= sizeof(pmod->FullDllPath) ? sizeof(pmod->FullDllPath) - 1 : name.Length); + RtlCopyMemory(pmod->FullDllPath, name.Buffer, len); + pmod->FullDllPath[len] = '\0'; RtlFreeAnsiString(&name); } pmod->DllBase = (PVOID)ldrEntry32->DllBase; @@ -164,17 +162,15 @@ NTSTATUS GetModules( PLDR_DATA_TABLE_ENTRY ldrEntry = CONTAINING_RECORD(listEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); ANSI_STRING name; if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &ldrEntry->BaseDllName, TRUE))) { - RtlCopyMemory(pmod->BaseDllName, name.Buffer, - (name.Length > sizeof pmod->BaseDllName ? - sizeof pmod->BaseDllName : name.Length) - ); + SIZE_T len = (name.Length >= sizeof(pmod->BaseDllName) ? sizeof(pmod->BaseDllName) - 1 : name.Length); + RtlCopyMemory(pmod->BaseDllName, name.Buffer, len); + pmod->BaseDllName[len] = '\0'; RtlFreeAnsiString(&name); } if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &ldrEntry->FullDllName, TRUE))) { - RtlCopyMemory(pmod->FullDllPath, name.Buffer, - (name.Length > sizeof pmod->FullDllPath ? - sizeof pmod->FullDllPath : name.Length) - ); + SIZE_T len = (name.Length >= sizeof(pmod->FullDllPath) ? sizeof(pmod->FullDllPath) - 1 : name.Length); + RtlCopyMemory(pmod->FullDllPath, name.Buffer, len); + pmod->FullDllPath[len] = '\0'; RtlFreeAnsiString(&name); } pmod->DllBase = ldrEntry->DllBase; @@ -239,7 +235,7 @@ NTSTATUS KeWriteVirtualMemory( NTSTATUS KeProtectVirtualMemory( IN HANDLE hProcess, IN PVOID addr, IN SIZE_T siz, IN ULONG new_prot, - OUT ULONG *old_prot + OUT ULONG* old_prot ) { NTSTATUS status; @@ -277,7 +273,7 @@ NTSTATUS KeRestoreProtectVirtualMemory(IN HANDLE hProcess, return status; } -NTSTATUS AllocMemoryToProcess(IN PEPROCESS pep, IN OUT PVOID *baseAddr, IN OUT SIZE_T *outSize, IN ULONG protect) +NTSTATUS AllocMemoryToProcess(IN PEPROCESS pep, IN OUT PVOID* baseAddr, IN OUT SIZE_T* outSize, IN ULONG protect) { NTSTATUS status; PKAPC_STATE apc; @@ -339,7 +335,7 @@ NTSTATUS WritePhysicalPage(IN PVOID addr, IN PUCHAR content, IN OUT PSIZE_T cont return MmCopyMemory(vaddr, mm, 4096, MM_COPY_MEMORY_VIRTUAL, content_size_and_transferred); } -NTSTATUS ReadPhysicalPage(IN PHYSICAL_ADDRESS * addr, OUT PUCHAR content, IN OUT PSIZE_T content_size_and_transferred) +NTSTATUS ReadPhysicalPage(IN PHYSICAL_ADDRESS* addr, OUT PUCHAR content, IN OUT PSIZE_T content_size_and_transferred) { MM_COPY_ADDRESS mm = { 0 }; @@ -348,7 +344,7 @@ NTSTATUS ReadPhysicalPage(IN PHYSICAL_ADDRESS * addr, OUT PUCHAR content, IN OUT return STATUS_UNSUCCESSFUL; } - mm.PhysicalAddress = *(PHYSICAL_ADDRESS *)addr; + mm.PhysicalAddress = *(PHYSICAL_ADDRESS*)addr; return MmCopyMemory(content, mm, 4096, MM_COPY_MEMORY_PHYSICAL, content_size_and_transferred); } diff --git a/MemDriverLib/MemDriverLib.cpp b/MemDriverLib/MemDriverLib.cpp index 34bbf2c..c79a01a 100644 --- a/MemDriverLib/MemDriverLib.cpp +++ b/MemDriverLib/MemDriverLib.cpp @@ -48,6 +48,34 @@ bool KInterface::Ping() return srr == SRR_SIGNALED; } +bool KInterface::Processes(std::vector<PROCESS_DATA>& dest) +{ + SendRecvReturn srr; + PKERNEL_PROCESSES_REQUEST processes = (PKERNEL_PROCESSES_REQUEST)getBuffer(); + PPROCESS_DATA data = (PPROCESS_DATA)(processes + 1); + + m_last_ntstatus = INVALID_NTSTATUS; + srr = SendRecvWait(MEM_PROCESSES); + if (srr == SRR_SIGNALED) { + m_last_ntstatus = processes->StatusRes; + if (validateResponeEx(processes, processes->StatusRes, processes->ProcessCount * sizeof(PROCESS_DATA)) == MEM_PROCESSES) + { + for (SIZE_T i = 0; i < processes->ProcessCount; ++i, ++data) + { + dest.push_back(*data); + } + } + else { + return false; + } + } + else { + return false; + } + + return true; +} + bool KInterface::Pages(HANDLE targetPID, std::vector<MEMORY_BASIC_INFORMATION>& dest, PVOID start_address) diff --git a/include/KInterface.h b/include/KInterface.h index 540548b..3fee236 100644 --- a/include/KInterface.h +++ b/include/KInterface.h @@ -28,17 +28,18 @@ public: bool Init(); bool Handshake(); bool Ping(); + bool Processes(std::vector<PROCESS_DATA>& dest); bool Pages(HANDLE targetPID, std::vector<MEMORY_BASIC_INFORMATION>& dest, PVOID start_address = NULL); bool Modules(HANDLE targetPID, std::vector<MODULE_DATA>& dest); bool Exit(); - bool RPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size, + bool RPM(HANDLE targetPID, PVOID address, BYTE* buf, SIZE_T size, PKERNEL_READ_REQUEST result); - bool WPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size, + bool WPM(HANDLE targetPID, PVOID address, BYTE* buf, SIZE_T size, PKERNEL_WRITE_REQUEST result); - bool VAlloc(HANDLE targetPID, PVOID *address, SIZE_T *size, ULONG protection); + bool VAlloc(HANDLE targetPID, PVOID* address, SIZE_T* size, ULONG protection); bool VFree(HANDLE targetPID, PVOID address, SIZE_T size); bool VUnlink(HANDLE targetPID, PVOID address); @@ -70,8 +71,8 @@ public: return buf; } template <class T> - static void Wpm(HANDLE targetPID, PVOID address, T *buf) { - if (!KInterface::getInstance().WPM(targetPID, address, (BYTE*)buf, sizeof *buf, NULL)) + static void Wpm(HANDLE targetPID, PVOID address, T* buf) { + if (!KInterface::getInstance().WPM(targetPID, address, (BYTE*)buf, sizeof * buf, NULL)) throw std::runtime_error("KMemory WPM failed"); } }; @@ -80,14 +81,14 @@ class KMemoryBuf { public: template <size_t SIZE> - static SSIZE_T Rpm(HANDLE targetPID, PVOID address, BYTE *dest) { + static SSIZE_T Rpm(HANDLE targetPID, PVOID address, BYTE* dest) { KERNEL_READ_REQUEST rr = { 0 }; if (!KInterface::getInstance().RPM(targetPID, address, &dest[0], SIZE, &rr)) return -1; return rr.SizeRes; } template <size_t SIZE> - static SSIZE_T Wpm(HANDLE targetPID, PVOID address, BYTE *dest) { + static SSIZE_T Wpm(HANDLE targetPID, PVOID address, BYTE* dest) { KERNEL_WRITE_REQUEST wr = { 0 }; if (!KInterface::getInstance().WPM(targetPID, address, &dest[0], SIZE, &wr)) return -1; diff --git a/include/KMemDriver.h b/include/KMemDriver.h index 90a06f2..bc50d61 100644 --- a/include/KMemDriver.h +++ b/include/KMemDriver.h @@ -21,34 +21,35 @@ typedef _Return_type_success_(return >= 0) LONG NTSTATUS; #define MEM_HANDSHAKE 0x800 #define MEM_PING 0x801 -#define MEM_MODULES 0x802 -#define MEM_PAGES 0x803 -#define MEM_RPM 0x804 -#define MEM_WPM 0x805 -#define MEM_VALLOC 0x806 -#define MEM_VFREE 0x807 -#define MEM_VUNLINK 0x808 -#define MEM_EXIT 0x809 +#define MEM_PROCESSES 0x802 +#define MEM_MODULES 0x803 +#define MEM_PAGES 0x804 +#define MEM_RPM 0x805 +#define MEM_WPM 0x806 +#define MEM_VALLOC 0x807 +#define MEM_VFREE 0x808 +#define MEM_VUNLINK 0x809 +#define MEM_EXIT 0x810 typedef struct _KERNEL_HEADER { UINT32 magic; UINT32 type; -} KERNEL_HEADER, *PKERNEL_HEADER; +} KERNEL_HEADER, * PKERNEL_HEADER; typedef struct _KERNEL_HANDSHAKE { KERNEL_HEADER hdr; HANDLE kevent; HANDLE uevent; -} KERNEL_HANDSHAKE, *PKERNEL_HANDSHAKE; +} KERNEL_HANDSHAKE, * PKERNEL_HANDSHAKE; typedef struct _KERNEL_PING { KERNEL_HEADER hdr; UINT32 rnd_user; UINT32 rnd_kern; -} KERNEL_PING, *PKERNEL_PING; +} KERNEL_PING, * PKERNEL_PING; typedef struct _KERNEL_PAGE { @@ -59,7 +60,7 @@ typedef struct _KERNEL_PAGE NTSTATUS StatusRes; SIZE_T pages; MEMORY_BASIC_INFORMATION pages_start; -} KERNEL_PAGE, *PKERNEL_PAGE; +} KERNEL_PAGE, * PKERNEL_PAGE; typedef struct _MODULE_DATA { @@ -67,7 +68,7 @@ typedef struct _MODULE_DATA ULONG SizeOfImage; CHAR BaseDllName[64]; CHAR FullDllPath[256]; -} MODULE_DATA, *PMODULE_DATA; +} MODULE_DATA, * PMODULE_DATA; typedef struct _KERNEL_MODULES { @@ -78,12 +79,12 @@ typedef struct _KERNEL_MODULES NTSTATUS StatusRes; SIZE_T modules; MODULE_DATA modules_start; -} KERNEL_MODULES, *PKERNEL_MODULES; +} KERNEL_MODULES, * PKERNEL_MODULES; typedef struct _KERNEL_EXIT { KERNEL_HEADER hdr; -} KERNEL_EXIT, *PKERNEL_EXIT; +} KERNEL_EXIT, * PKERNEL_EXIT; typedef struct _KERNEL_READ_REQUEST { @@ -94,7 +95,7 @@ typedef struct _KERNEL_READ_REQUEST NTSTATUS StatusRes; SIZE_T SizeRes; -} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST; +} KERNEL_READ_REQUEST, * PKERNEL_READ_REQUEST; typedef struct _KERNEL_WRITE_REQUEST { @@ -105,7 +106,7 @@ typedef struct _KERNEL_WRITE_REQUEST NTSTATUS StatusRes; SIZE_T SizeRes; -} KERNEL_WRITE_REQUEST, *PKERNEL_WRITE_REQUEST; +} KERNEL_WRITE_REQUEST, * PKERNEL_WRITE_REQUEST; typedef struct _KERNEL_VALLOC_REQUEST { @@ -118,7 +119,7 @@ typedef struct _KERNEL_VALLOC_REQUEST NTSTATUS StatusRes; PVOID AddressRes; SIZE_T SizeRes; -} KERNEL_VALLOC_REQUEST, *PKERNEL_VALLOC_REQUEST; +} KERNEL_VALLOC_REQUEST, * PKERNEL_VALLOC_REQUEST; typedef struct _KERNEL_VFREE_REQUEST { @@ -128,7 +129,7 @@ typedef struct _KERNEL_VFREE_REQUEST SIZE_T Size; NTSTATUS StatusRes; -} KERNEL_VFREE_REQUEST, *PKERNEL_VFREE_REQUEST; +} KERNEL_VFREE_REQUEST, * PKERNEL_VFREE_REQUEST; typedef struct _KERNEL_VUNLINK_REQUEST { @@ -137,7 +138,24 @@ typedef struct _KERNEL_VUNLINK_REQUEST PVOID Address; NTSTATUS StatusRes; -} KERNEL_VUNLINK_REQUEST, *PKERNEL_VUNLINK_REQUEST; +} KERNEL_VUNLINK_REQUEST, * PKERNEL_VUNLINK_REQUEST; + +typedef struct _PROCESS_DATA +{ + ULONG NumberOfThreads; + CHAR ImageName[80]; + HANDLE UniqueProcessId; + ULONG HandleCount; +} PROCESS_DATA, * PPROCESS_DATA; + +typedef struct _KERNEL_PROCESSES_REQUEST +{ + KERNEL_HEADER hdr; + + NTSTATUS StatusRes; + SIZE_T ProcessCount; + //PROCESS_DATA processes[ProcessCount]; +} KERNEL_PROCESSES_REQUEST, * PKERNEL_PROCESSES_REQUEST; #ifndef KERNEL_MODULE @@ -149,6 +167,10 @@ static inline VOID prepareRequest(PVOID buf, UINT32 type) } #endif +#ifndef KERNEL_MODULE +#define validateResponeEx(buf, status, count) (!status && count <= SHMEM_SIZE) && validateRespone(buf) +#endif + static inline UINT32 #ifndef KERNEL_MODULE validateRespone @@ -163,6 +185,7 @@ validateRequest switch (hdr->type) { case MEM_HANDSHAKE: case MEM_PING: + case MEM_PROCESSES: case MEM_PAGES: case MEM_MODULES: case MEM_RPM: |