aboutsummaryrefslogtreecommitdiff
path: root/Hunted/KInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Hunted/KInterface.cpp')
-rw-r--r--Hunted/KInterface.cpp326
1 files changed, 0 insertions, 326 deletions
diff --git a/Hunted/KInterface.cpp b/Hunted/KInterface.cpp
deleted file mode 100644
index 62859a4..0000000
--- a/Hunted/KInterface.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-#include "pch.h"
-#include "KInterface.h"
-#include "KMemDriver.h"
-
-#include <sstream>
-#include <ctime>
-#include <stdexcept>
-
-
-KInterface::KInterface()
-{
-}
-
-bool KInterface::Init()
-{
- std::srand((unsigned int)std::time(nullptr));
- m_shmem = VirtualAlloc((PVOID)SHMEM_ADDR, SHMEM_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- m_kevent = CreateEvent(NULL, FALSE, FALSE, NULL);
- m_uevent = CreateEvent(NULL, FALSE, FALSE, NULL);
- return m_shmem && m_kevent != INVALID_HANDLE_VALUE && m_uevent != INVALID_HANDLE_VALUE;
-}
-
-bool KInterface::Handshake()
-{
- PKERNEL_HANDSHAKE hnds = (PKERNEL_HANDSHAKE)getBuffer();
- hnds->kevent = m_kevent;
- hnds->uevent = m_uevent;
- m_last_ntstatus = INVALID_NTSTATUS;
- return SendRecvWait(MEM_HANDSHAKE) == SRR_SIGNALED;
-}
-
-bool KInterface::Ping()
-{
- SendRecvReturn srr;
- PKERNEL_PING ping = (PKERNEL_PING)getBuffer();
- m_last_ping_value = ping->rnd_user = (std::rand() << 16) | std::rand();
- std::srand(m_last_ping_value);
- m_last_ntstatus = INVALID_NTSTATUS;
- srr = SendRecvWait(MEM_PING);
- if (ping->rnd_kern != getLastPingValue())
- return false;
- return srr == SRR_SIGNALED;
-}
-
-bool KInterface::Pages(HANDLE targetPID,
- std::vector<MEMORY_BASIC_INFORMATION>& dest,
- PVOID start_address)
-{
- PKERNEL_PAGE pages = (PKERNEL_PAGE)getBuffer();
- const ULONGLONG max_pages = (SHMEM_SIZE - sizeof *pages +
- sizeof pages->pages_start) / sizeof pages->pages_start;
- SendRecvReturn srr;
- bool success = false;
-
- do {
- m_last_ntstatus = INVALID_NTSTATUS;
- pages->pages = 0;
- pages->ProcessId = targetPID;
- pages->StartAddress = start_address;
- srr = SendRecvWait(MEM_PAGES);
- if (srr == SRR_SIGNALED) {
- m_last_ntstatus = pages->StatusRes;
- if (validateRespone(getBuffer()) == MEM_PAGES &&
- !pages->StatusRes &&
- pages->pages * sizeof(pages->pages_start) <= SHMEM_SIZE)
- {
- for (SIZE_T i = 0; i < pages->pages; ++i) {
- dest.push_back((&pages->pages_start)[i]);
- start_address = (PVOID)
- ((ULONG_PTR)((&pages->pages_start)[i].BaseAddress)
- + (&pages->pages_start)[i].RegionSize);
- }
- success = true;
- }
- else {
- success = false;
- break;
- }
- }
- } while (srr == SRR_SIGNALED && pages->pages == max_pages && pages->pages);
- return success && srr == SRR_SIGNALED;;
-}
-
-bool KInterface::Modules(HANDLE targetPID,
- std::vector<MODULE_DATA>& dest)
-{
- PKERNEL_MODULES mods = (PKERNEL_MODULES)getBuffer();
- SIZE_T start_index = 0;
- const ULONGLONG max_mods = (SHMEM_SIZE - sizeof *mods +
- sizeof mods->modules_start) / sizeof mods->modules_start;
- SendRecvReturn srr;
- bool success = false;
-
- do {
- m_last_ntstatus = INVALID_NTSTATUS;
- mods->modules = 0;
- mods->ProcessId = targetPID;
- mods->StartIndex = start_index;
- srr = SendRecvWait(MEM_MODULES);
- if (srr == SRR_SIGNALED) {
- m_last_ntstatus = mods->StatusRes;
- if (validateRespone(getBuffer()) == MEM_MODULES &&
- !mods->StatusRes &&
- mods->modules * sizeof(mods->modules_start) <= SHMEM_SIZE)
- {
- for (SIZE_T i = 0; i < mods->modules; ++i) {
- dest.push_back((&mods->modules_start)[i]);
- start_index++;
- }
- success = true;
- }
- else {
- success = false;
- break;
- }
- }
- } while (srr == SRR_SIGNALED && mods->modules == max_mods && mods->modules);
- return success && srr == SRR_SIGNALED;
-}
-
-bool KInterface::Exit()
-{
- m_last_ntstatus = INVALID_NTSTATUS;
- return SendRecvWait(MEM_EXIT, INFINITE) == SRR_SIGNALED;
-}
-
-bool KInterface::RPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
- PKERNEL_READ_REQUEST result)
-{
- PKERNEL_READ_REQUEST rr = (PKERNEL_READ_REQUEST)getBuffer();
- m_last_ntstatus = INVALID_NTSTATUS;
- if (size > SHMEM_SIZE - sizeof *rr)
- return false;
- rr->ProcessId = targetPID;
- rr->Address = address;
- rr->SizeReq = size;
- rr->SizeRes = (SIZE_T)-1;
- rr->StatusRes = (NTSTATUS)-1;
- if (SendRecvWait(MEM_RPM) == SRR_SIGNALED) {
- m_last_ntstatus = rr->StatusRes;
- if (rr->StatusRes ||
- rr->SizeRes != size)
- {
- std::stringstream err_str;
- err_str << "Call RPM(0x" << std::hex << address
- << "," << std::dec << size
- << ") failed with 0x"
- << std::hex << rr->StatusRes
- << " (Size Req/Res: "
- << std::dec << rr->SizeReq << "/" << (SSIZE_T)rr->SizeRes
- << ")";
- throw std::runtime_error(err_str.str());
- }
- memcpy(buf, (BYTE *)rr + sizeof *rr, size);
- if (result)
- *result = *rr;
- return true;
- }
- return false;
-}
-
-bool KInterface::WPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
- PKERNEL_WRITE_REQUEST result)
-{
- PKERNEL_WRITE_REQUEST wr = (PKERNEL_WRITE_REQUEST)getBuffer();
- m_last_ntstatus = INVALID_NTSTATUS;
- if (size > SHMEM_SIZE - sizeof *wr)
- return false;
- wr->ProcessId = targetPID;
- wr->Address = address;
- wr->SizeReq = size;
- wr->SizeRes = (SIZE_T)-1;
- wr->StatusRes = (NTSTATUS)-1;
- memcpy((BYTE *)wr + sizeof *wr, buf, size);
- if (SendRecvWait(MEM_WPM) == SRR_SIGNALED) {
- m_last_ntstatus = wr->StatusRes;
- if (wr->StatusRes ||
- wr->SizeRes != size)
- {
- std::stringstream err_str;
- err_str << "Call WPM(0x" << std::hex << address
- << "," << std::dec << size
- << ") failed with 0x"
- << std::hex << wr->StatusRes
- << " (Size Req/Res: "
- << std::dec << wr->SizeReq << "/" << (SSIZE_T)wr->SizeRes
- << ")";
- throw std::runtime_error(err_str.str());
- }
- if (result)
- *result = *wr;
- return true;
- }
- return false;
-}
-
-PVOID KInterface::getBuffer() {
- if (!m_shmem)
- throw std::runtime_error("Call Init() before..");
- return m_shmem;
-}
-
-HANDLE KInterface::getKHandle() {
- if (!m_kevent)
- throw std::runtime_error("Call Init() before..");
- return m_kevent;
-}
-
-HANDLE KInterface::getUHandle() {
- if (!m_uevent)
- throw std::runtime_error("Call Init() before..");
- return m_uevent;
-}
-
-UINT32 KInterface::getLastPingValue() {
- return m_last_ping_value;
-}
-
-UINT32 KInterface::getLastNtStatus() {
- return m_last_ntstatus;
-}
-
-SendRecvReturn KInterface::SendRecvWait(UINT32 type, DWORD timeout)
-{
- prepareRequest(getBuffer(), type);
- if (!SetEvent(m_kevent))
- return SRR_ERR_KEVENT;
- return RecvWait(timeout);
-}
-
-SendRecvReturn KInterface::RecvWait(DWORD timeout)
-{
- switch (WaitForSingleObject(m_uevent, timeout)) {
- case WAIT_OBJECT_0:
- return validateRespone(getBuffer()) != INVALID_REQUEST ? SRR_SIGNALED : SRR_ERR_HEADER;
- case WAIT_TIMEOUT:
- return SRR_TIMEOUT;
- }
- return SRR_ERR_UEVENT;
-}
-
-SSIZE_T KScan::KScanSimple(HANDLE targetPID, PVOID start_address, SIZE_T max_scansize,
- PVOID scanbuf, SIZE_T scanbuf_size)
-{
- ULONG_PTR max_addr;
- ULONG_PTR cur_addr = (ULONG_PTR)start_address;
- BYTE tmp_rpmbuf[SHMEM_SIZE];
- SIZE_T scan_index, processed, real_size, diff_size;
- std::vector<MEMORY_BASIC_INFORMATION> mbis;
- KERNEL_READ_REQUEST rr = { 0 };
-
- if (max_scansize < scanbuf_size)
- return -1;
- if (!KInterface::getInstance().Pages(targetPID, mbis, start_address))
- return -1;
-
- diff_size = (ULONG_PTR)start_address - (ULONG_PTR)mbis.at(0).BaseAddress;
- real_size = (mbis.at(0).RegionSize - diff_size > max_scansize ?
- max_scansize : (ULONG_PTR)mbis.at(0).RegionSize - diff_size);
- max_addr = (ULONG_PTR)start_address + real_size;
-
- while (cur_addr < max_addr) {
- if (!KInterface::getInstance().RPM(targetPID, (PVOID)cur_addr,
- tmp_rpmbuf, (sizeof tmp_rpmbuf > real_size ? real_size : sizeof tmp_rpmbuf), &rr))
- {
- break;
- }
-
- if (rr.StatusRes || rr.SizeRes < scanbuf_size)
- break;
-
- for (processed = 0, scan_index = 0; processed < rr.SizeRes; ++processed) {
- if (tmp_rpmbuf[processed] != *((BYTE*)scanbuf + scan_index)) {
- scan_index = 0;
- }
- else {
- scan_index++;
- if (scan_index == scanbuf_size) {
- return cur_addr + processed - scanbuf_size + 1;
- }
- }
- }
- cur_addr += processed;
- real_size -= processed;
- }
- return -1;
-}
-
-SSIZE_T KScan::KBinDiffSimple(HANDLE targetPID, PVOID start_address,
- BYTE *curbuf, BYTE *oldbuf, SIZE_T siz, std::vector<std::pair<SIZE_T, SIZE_T>> *diffs)
-{
- SSIZE_T scanned, diff_start;
- SIZE_T diff_size;
- KERNEL_READ_REQUEST rr = { 0 };
-
- if (!KInterface::getInstance().RPM(targetPID, start_address,
- curbuf, siz, &rr))
- {
- scanned = -1;
- }
- else scanned = rr.SizeRes;
-
- if (scanned > 0) {
- diffs->clear();
- diff_start = -1;
- diff_size = 0;
- for (SIZE_T i = 0; i < (SIZE_T)scanned; ++i) {
- if (curbuf[i] != oldbuf[i]) {
- if (diff_start < 0)
- diff_start = i;
- diff_size++;
- }
- else if (diff_start >= 0) {
- diffs->push_back(std::pair<SIZE_T, SIZE_T>
- (diff_start, diff_size));
- diff_start = -1;
- diff_size = 0;
- }
- }
- memcpy(oldbuf, curbuf, scanned);
- if ((SIZE_T)scanned < siz)
- memset(oldbuf + scanned, 0, siz - scanned);
- }
-
- return scanned;
-} \ No newline at end of file