aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsegfault <toni@impl.cc>2021-01-11 13:24:35 +0100
committersegfault <toni@impl.cc>2021-01-11 13:24:35 +0100
commit89ec896bede35949a43a41e779aadb11fe16f9a2 (patch)
tree5edea9bf65457340d2891d2864233b6f4a40c943
parent0ede1cd40edc539764de998e373acd57f87403f1 (diff)
Added new MemDriverLib functions to determine if a page is freed/reserved.
* added PAGES/RPM tests * increased memory for ZwQuerySystemInformation in GetProcesses
-rw-r--r--IntegrationTest/IntegrationTest.cpp74
-rw-r--r--KMemDriver/KMemDriver.c9
-rw-r--r--include/KInterface.h10
3 files changed, 85 insertions, 8 deletions
diff --git a/IntegrationTest/IntegrationTest.cpp b/IntegrationTest/IntegrationTest.cpp
index 4f87819..a254e85 100644
--- a/IntegrationTest/IntegrationTest.cpp
+++ b/IntegrationTest/IntegrationTest.cpp
@@ -2,14 +2,17 @@
#include "KInterface.h"
#include <iostream>
+#include <map>
-#define PRINT_CHECK_MSG(message) std::wcout << L ## message
+#define PRINT_CHECK_MSG(message) std::wcout << L ## message ## " "
#define PRINT_FAIL_MSG() std::wcout << L" [FAIL]" << std::endl
#define PRINT_OK_MSG() std::wcout << L" [ OK ]" << std::endl
#define KM_ASSERT_EQUAL(equal, condition, message) \
do { PRINT_CHECK_MSG(message); if ((condition) != (equal)) { \
PRINT_FAIL_MSG(); goto error; } else { PRINT_OK_MSG(); } \
} while (0)
+#define KM_ASSERT_EQUAL_NO_MSG(equal, condition) \
+ do { if ((condition) != (equal)) { goto error; } } while (0)
#define KM_TEST_SUITE(condition, message) \
do { \
PRINT_CHECK_MSG("--- TestSuite " ## message ## " ---\n"); \
@@ -167,6 +170,72 @@ error:
return false;
}
+static std::map<HANDLE, bool> GetCurrentHeaps()
+{
+ std::map<HANDLE, bool> retval;
+ SIZE_T const max_heaps = 64;
+ HANDLE heaps[max_heaps];
+ DWORD count = GetProcessHeaps(max_heaps, heaps);
+
+ if (count > 0) {
+ for (SIZE_T j = 0; j < count; ++j) {
+ retval[heaps[j]] = true;
+ }
+ }
+ return retval;
+}
+
+static bool test_PagesRPM(KInterface& ki, HANDLE pid)
+{
+ {
+ std::vector<MEMORY_BASIC_INFORMATION> pages;
+ KM_ASSERT_EQUAL(true, ki.Pages(pid, pages), "Kernel Interface Pages");
+ KM_ASSERT_EQUAL(0, ki.getLastNtStatus(), "Last NtStatus");
+ for (auto& page : pages) {
+ std::map<HANDLE, bool> heaps = GetCurrentHeaps();
+ if (heaps.find(page.BaseAddress) != heaps.end()) {
+ continue;
+ }
+ if (KInterface::PageIsFreed(page) == true || KInterface::PageIsPrivateReserved(page) == true) {
+ continue;
+ }
+ BYTE buf[4096];
+ SIZE_T siz = (page.RegionSize > sizeof(buf) ? sizeof(buf) : page.RegionSize);
+ KM_ASSERT_EQUAL_NO_MSG(true, ki.RPM(pid, page.BaseAddress, buf, siz, NULL));
+ KM_ASSERT_EQUAL_NO_MSG(0, ki.getLastNtStatus());
+ }
+
+ std::vector<MEMORY_BASIC_INFORMATION> vq_pages;
+ MEMORY_BASIC_INFORMATION page;
+ SIZE_T base = NULL;
+ while (VirtualQuery((LPVOID)base, &page, sizeof(page)) > 0) {
+ std::map<HANDLE, bool> vq_heaps = GetCurrentHeaps();
+ base += page.RegionSize;
+ if (vq_heaps.find(page.BaseAddress) != vq_heaps.end()) {
+ continue;
+ }
+ vq_pages.push_back(page);
+ }
+
+ for (SIZE_T i = 0; i < vq_pages.size(); ++i) {
+ if (vq_pages[i].BaseAddress != pages[i].BaseAddress) {
+ /* not optimal as we do test all pages */
+ break;
+ }
+ KM_ASSERT_EQUAL_NO_MSG(vq_pages[i].Protect, pages[i].Protect);
+ KM_ASSERT_EQUAL_NO_MSG(vq_pages[i].RegionSize, pages[i].RegionSize);
+ KM_ASSERT_EQUAL_NO_MSG(vq_pages[i].State, pages[i].State);
+ KM_ASSERT_EQUAL_NO_MSG(vq_pages[i].Type, pages[i].Type);
+ }
+
+ KM_ASSERT_EQUAL_NO_MSG(pages.size(), pages.size());
+ }
+
+ return true;
+error:
+ return false;
+}
+
int main()
{
HANDLE this_pid = (HANDLE)((ULONG_PTR)GetCurrentProcessId());
@@ -188,6 +257,7 @@ int main()
KM_TEST_SUITE(test_Pages(ki, this_pid), "Pages");
KM_TEST_SUITE(test_VirtualMemory(ki, this_pid), "VirtualMemory");
KM_TEST_SUITE(test_MemoryReadWrite(ki, this_pid), "MemoryReadWrite");
+ KM_TEST_SUITE(test_PagesRPM(ki, this_pid), "ModulesPagesRPM");
KM_ASSERT_EQUAL(true, ki.Ping(), "Kernel Interface PING - PONG #4");
KM_ASSERT_EQUAL(true, ki.Exit(), "Kernel Interface Driver Shutdown");
}
@@ -199,5 +269,5 @@ int main()
error:
ki.Exit();
std::wcout << std::endl << "KMemDriver Shutdown [PRESS RETURN KEY TO EXIT]" << std::endl;
- getchar();
+ std::getchar();
} \ No newline at end of file
diff --git a/KMemDriver/KMemDriver.c b/KMemDriver/KMemDriver.c
index f574e17..edcf834 100644
--- a/KMemDriver/KMemDriver.c
+++ b/KMemDriver/KMemDriver.c
@@ -179,6 +179,7 @@ NTSTATUS GetProcesses(OUT PROCESS_DATA* procs, IN OUT SIZE_T* psiz)
return status;
}
+ mem_needed += 16 * sizeof(SYSTEM_PROCESS_INFORMATION);
if (mem_needed / sizeof(SYSTEM_PROCESS_INFORMATION) > max_siz / sizeof(PROCESS_DATA)) {
KDBG("NtQuerySystemInformation buffer too small\n", status);
return STATUS_BUFFER_TOO_SMALL;
@@ -554,11 +555,11 @@ NTSTATUS KRThread(IN PVOID pArg)
}
ULONG new_prot = PAGE_EXECUTE_READWRITE, old_prot = 0;
KeProtectVirtualMemory(lastPROC, rr->Address, rr->SizeReq, new_prot, &old_prot);
- KDBG("RPM to 0x%p size 0x%X bytes (protection before/after: 0x%X/0x%X)\n",
- rr->Address, rr->SizeReq, old_prot, new_prot);
rr->StatusRes = KeReadVirtualMemory(lastPEP, (PVOID)rr->Address,
(PVOID)((ULONG_PTR)shm_buf + sizeof * rr), &siz);
KeRestoreProtectVirtualMemory(lastPROC, rr->Address, rr->SizeReq, old_prot);
+ KDBG("RPM to 0x%p size 0x%X bytes returned 0x%X (protection before/after: 0x%X/0x%X)\n",
+ rr->Address, rr->SizeReq, rr->StatusRes, old_prot, new_prot);
if (NT_SUCCESS(rr->StatusRes)) {
rr->SizeRes = siz;
@@ -589,11 +590,11 @@ NTSTATUS KRThread(IN PVOID pArg)
}
ULONG new_prot = PAGE_EXECUTE_READWRITE, old_prot = 0;
KeProtectVirtualMemory(lastPROC, wr->Address, wr->SizeReq, new_prot, &old_prot);
- KDBG("WPM to 0x%p size 0x%X bytes (protection before/after: 0x%X/0x%X)\n",
- wr->Address, wr->SizeReq, old_prot, new_prot);
wr->StatusRes = KeWriteVirtualMemory(lastPEP, (PVOID)((ULONG_PTR)shm_buf + sizeof * wr),
(PVOID)wr->Address, &siz);
KeRestoreProtectVirtualMemory(lastPROC, wr->Address, wr->SizeReq, old_prot);
+ KDBG("WPM to 0x%p size 0x%X bytes returned 0x%X (protection before/after: 0x%X/0x%X)\n",
+ wr->Address, wr->SizeReq, wr->StatusRes, old_prot, new_prot);
if (NT_SUCCESS(wr->StatusRes)) {
wr->SizeRes = siz;
diff --git a/include/KInterface.h b/include/KInterface.h
index 19c9268..55137e8 100644
--- a/include/KInterface.h
+++ b/include/KInterface.h
@@ -100,12 +100,18 @@ public:
UINT32 getLastPingValue();
UINT32 getLastNtStatus();
+ static bool PageIsFreed(MEMORY_BASIC_INFORMATION& page) {
+ return (page.Protect & PAGE_NOACCESS) != 0;
+ }
+ static bool PageIsPrivateReserved(MEMORY_BASIC_INFORMATION& page) {
+ return page.Protect == 0;
+ }
SendRecvReturn RecvWait(DWORD timeout = DEFAULT_TIMEOUT_MS);
- void StartPingThread(void (__cdecl *onTimeout)(void));
+ void StartPingThread(void(__cdecl* onTimeout)(void));
private:
SendRecvReturn SendRecvWait(UINT32 type, DWORD timeout = DEFAULT_TIMEOUT_MS);
- void PingThread(void (__cdecl *onTimeout)(void));
+ void PingThread(void(__cdecl* onTimeout)(void));
PVOID m_shmem = NULL;
HANDLE m_kevent = NULL, m_uevent = NULL;