aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsegfault <toni@impl.cc>2020-12-12 20:08:22 +0100
committersegfault <toni@impl.cc>2020-12-12 20:08:22 +0100
commit2c2383838ce791392782aeb5ca3cd0607c92e22e (patch)
tree477fa41c75fae922c33f7b63ed07c9a23a826a76
parent444b885aa818e7a4a91870181950b260a53b8fc9 (diff)
Added KMemDriver GetProcesses to enumerate all processes from kernel space.
* fixed missing NUL termination for converted ASCII strings
-rw-r--r--IntegrationTest/IntegrationTest.cpp45
-rw-r--r--KMemDriver/KMemDriver.c72
-rw-r--r--KMemDriver/Memory.c46
-rw-r--r--MemDriverLib/MemDriverLib.cpp28
-rw-r--r--include/KInterface.h15
-rw-r--r--include/KMemDriver.h63
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: