From f661be495da085eacceae17f0e2edf986a4279d1 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Sun, 7 Jul 2019 01:19:41 +0200 Subject: KTest -> Hunted --- Hunted/Hunted.cpp | 400 ++++++++++++++++++++++++++++++++++++++++++ Hunted/Hunted.vcxproj | 194 ++++++++++++++++++++ Hunted/Hunted.vcxproj.filters | 39 ++++ Hunted/KInterface.cpp | 326 ++++++++++++++++++++++++++++++++++ Hunted/pch.cpp | 5 + Hunted/pch.h | 14 ++ KMemDriver.sln | 2 +- KTest/KInterface.cpp | 326 ---------------------------------- KTest/KTest.cpp | 400 ------------------------------------------ KTest/KTest.vcxproj | 193 -------------------- KTest/KTest.vcxproj.filters | 39 ---- KTest/pch.cpp | 5 - KTest/pch.h | 14 -- 13 files changed, 979 insertions(+), 978 deletions(-) create mode 100644 Hunted/Hunted.cpp create mode 100644 Hunted/Hunted.vcxproj create mode 100644 Hunted/Hunted.vcxproj.filters create mode 100644 Hunted/KInterface.cpp create mode 100644 Hunted/pch.cpp create mode 100644 Hunted/pch.h delete mode 100644 KTest/KInterface.cpp delete mode 100644 KTest/KTest.cpp delete mode 100644 KTest/KTest.vcxproj delete mode 100644 KTest/KTest.vcxproj.filters delete mode 100644 KTest/pch.cpp delete mode 100644 KTest/pch.h diff --git a/Hunted/Hunted.cpp b/Hunted/Hunted.cpp new file mode 100644 index 0000000..b4cbda5 --- /dev/null +++ b/Hunted/Hunted.cpp @@ -0,0 +1,400 @@ +#include "pch.h" +#include "KMemDriver.h" +#include "KInterface.h" + +#include +#include +#include + +#pragma comment(lib, "User32.lib") + +#define WHEXOUT std::setfill(L'0') << std::setw(16) << std::hex + +BOOL running = false; +const wchar_t *wName = L"HUNT"; + +typedef struct SSystemGlobalEnvironment +{ + PVOID pDialogSystem; + PVOID p3DEngine; + PVOID pNetwork; + PVOID pNetContext; + PVOID pLobby; + PVOID pScriptSystem; + PVOID pPhysicalWorld; + PVOID pFlowSystem; + PVOID pInput; + PVOID pStatoscope; + PVOID pCryPak; + PVOID pFileChangeMonitor; + PVOID pProfileLogSystem; + PVOID pParticleManager; + PVOID pOpticsManager; + PVOID pFrameProfileSystem; + PVOID pTimer; + PVOID pCryFont; + PVOID pGameFramework; + PVOID pLocalMemoryUsage; + PVOID pEntitySystem; + PVOID pConsole; + PVOID pAudioSystem; + PVOID pSystem; + PVOID pCharacterManager; + PVOID pAISystem; + PVOID pLog; + PVOID pCodeCheckpointMgr; + PVOID pMovieSystem; + PVOID pNameTable; + PVOID pRenderer; + PVOID pAuxGeomRenderer; + PVOID pHardwareMouse; + PVOID pMaterialEffects; + PVOID pJobManager; + PVOID pOverloadSceneManager; + PVOID pFlashUI; + PVOID pUIFramework; + PVOID pServiceNetwork; + PVOID pRemoteCommandManager; + PVOID pDynamicResponseSystem; + PVOID pThreadManager; + PVOID pScaleformHelper; // nullptr when Scaleform support is not enabled + PVOID pSchematyc; + PVOID pSchematyc2; + PVOID pReflection; + + PVOID pLiveCreateManager; + PVOID pLiveCreateHost; + PVOID pMonoRuntime; + UINT32 mMainThreadId; //!< The main thread ID is used in multiple systems so should be stored globally. + UINT32 nMainFrameID; + const char* szCmdLine = ""; //!< Startup command line. + + //! Generic debug string which can be easily updated by any system and output by the debug handler + enum { MAX_DEBUG_STRING_LENGTH = 128 }; + char szDebugStatus[MAX_DEBUG_STRING_LENGTH]; + + //! Used to tell if this is a server/multiplayer instance + bool bServer; + bool bMultiplayer; + bool bHostMigrating; + int bDeepProfiling; + bool bBootProfilerEnabledFrames; + PVOID callbackStartSection; + PVOID callbackEndSection; + ////////////////////////////////////////////////////////////////////////// + + //! Whether we are running unattended, disallows message boxes and other blocking events that require human intervention + bool bUnattendedMode; + //! Whether we are unit testing + bool bTesting; + + bool bNoRandomSeed; +} SSystemGlobalEnvironment; + + + +bool consoleHandler(int signal) { + if (signal == CTRL_C_EVENT) { + if (!running) + exit(EXIT_FAILURE); + running = false; + std::wcout << L"Waiting for graceful shutdown .." << std::endl; + } + return true; +} + +void printBuf(UCHAR *buf, SIZE_T siz, SIZE_T bytesBeforeNewline) { + unsigned int i, j; + const unsigned char colors[] = { 10,11,12,13,14,15 }; + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + + for (i = 0, j = 0; i < siz; ++i) { + if (i % bytesBeforeNewline == 0) { + SetConsoleTextAttribute(hConsole, colors[j++ % (sizeof colors)]); + wprintf(L"\n0x%04X: ", i); + } + wprintf(L"%02X ", buf[i]); + } + wprintf(L"\n"); + SetConsoleTextAttribute(hConsole, 15); +} + +BOOL CALLBACK enumWindowsProc(HWND hWnd, LPARAM lParam) +{ + int length = GetWindowTextLength(hWnd); + TCHAR* buffer; + buffer = new TCHAR[length + 1]; + memset(buffer, 0, (length + 1) * sizeof(TCHAR)); + GetWindowText(hWnd, buffer, length + 1); + if (!wcscmp(buffer, wName)) + *(HWND *)lParam = hWnd; + delete[] buffer; + return TRUE; +} + +int wmain(int argc, wchar_t **argv) +{ + HANDLE targetPID = 0; + PVOID buf; + HANDLE kevent; + HANDLE uevent; + + KInterface &ki = KInterface::getInstance(); + std::vector pages; + std::vector modules; + + if (argc > 1 && !wcscmp(argv[1], L"test")) { + return 0; + } + + if (argc > 1 && !wcscmp(argv[1], L"wnd")) { + if (argc < 3) { + std::wcout << L"Window title required!" << std::endl; + return 1; + } + wName = argv[2]; + std::wcout << L"Waiting for window title: '" << wName << L"'" << std::endl; + + HWND targetHWND = NULL; + while (1) { + if (!EnumWindows(enumWindowsProc, (LPARAM)&targetHWND)) { + return 1; + } + if (targetHWND) { + std::wcout << L"Found window '" << wName << L"' with Handle 0x" + << std::hex << targetHWND << std::endl; + break; + } + Sleep(1000); + } + GetWindowThreadProcessId(targetHWND, (LPDWORD)&targetPID); + } + + SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE); + + if (!ki.Init()) { + std::wcout << L"Kernel Interface Init() failed" << std::endl; + return 1; + } + + try { + buf = ki.getBuffer(); + kevent = ki.getKHandle(); + uevent = ki.getUHandle(); + } + catch (std::runtime_error& err) { + std::wcout << err.what() << std::endl; + return 1; + } + + std::wcout << L"Buffer.: " << buf << std::endl; + std::wcout << L"KHandle: " << kevent << std::endl; + std::wcout << L"UHandle: " << uevent << std::endl; + + if (!ki.Handshake()) { + std::wcout << L"Kernel Interface Handshake() failed" << std::endl; + return 1; + } + if (targetPID) { + if (!ki.Modules(targetPID, modules)) + std::wcout << L"Kernel Interface Modules() failed with 0x" + << std::hex << ki.getLastNtStatus() << std::endl; + else std::wcout << L"Got " << std::dec << modules.size() << L" modules for pid 0x" + << std::hex << targetPID << std::endl; + if (!ki.Pages(targetPID, pages)) + std::wcout << L"Kernel Interface Pages() failed with 0x" + << std::hex << ki.getLastNtStatus() << std::endl; + else std::wcout << L"Got " << std::dec << pages.size() << L" mapped pages for pid 0x" + << std::hex << targetPID << std::endl; + } + + running = TRUE; + do { + if (ki.RecvWait() == SRR_TIMEOUT) { + std::wcout << L"Ping -> "; + if (!ki.Ping()) { + std::wcout << L"Got no valid PONG, abort!" << std::endl; + running = FALSE; + } + else std::wcout << L"PONG!" << std::endl; + } + + if (!running) + break; + + try { + if (targetPID) { + for (MODULE_DATA& md : modules) { + if (!strncmp(md.BaseDllName, "CrySystem.dll", + sizeof md.BaseDllName)) + { + std::wcout << L"CrySystem.dll......: 0x" << WHEXOUT << md.DllBase << std::endl; + UINT64 g_pEnv = KMemory::Rpm(targetPID, + (PVOID)((UINT64)md.DllBase + 0xA37708)); + + std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl; + } + else + if (!strncmp(md.BaseDllName, "CryEntitySystem.dll", + sizeof md.BaseDllName)) + { + std::wcout << L"CryEntitySystem.dll: 0x" << std::hex << md.DllBase << std::endl; +#if 1 + /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader) */ + UINT64 g_pEnv = KMemory::Rpm(targetPID, + (PVOID)((UINT64)md.DllBase + 0x28C400)); + + std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl; +#if 1 + BYTE tmp[sizeof SSystemGlobalEnvironment * 2] = { 0 }; + SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)(g_pEnv), tmp); + + SSystemGlobalEnvironment *gEnv = (SSystemGlobalEnvironment *)&tmp[0]; + std::wcout << std::hex + << gEnv->p3DEngine << ", " + << gEnv->pEntitySystem << ", " + << gEnv->bMultiplayer << ", " + << gEnv->mMainThreadId << ", " + << gEnv->nMainFrameID << ", " + << gEnv->szDebugStatus << ", " + << gEnv->pMonoRuntime << ", " + << gEnv->callbackStartSection << ", " + << gEnv->callbackEndSection << ", " + << gEnv->bUnattendedMode << ", " + << gEnv->bTesting << ", " + << gEnv->bNoRandomSeed << ", " + << gEnv->bDeepProfiling << ", " + << std::endl; + + /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader) + * search for String "ExistingEntity: '%s' '%s'" + */ + UINT64 m_EntityArray = KMemory::Rpm(targetPID, + (PVOID)((UINT64)gEnv->pEntitySystem + 0x40078)); + //m_EntityArray += 0x40078; + std::wcout << WHEXOUT + << m_EntityArray + << std::endl; + + USHORT nops; + nops = KMemory::Rpm(targetPID, + (PVOID)((UINT64)md.DllBase + 0x12C3C7)); + std::wcout << std::hex << "+++ " << nops << std::endl; + nops = 0x9090; + KMemory::Wpm(targetPID, + (PVOID)((UINT64)md.DllBase + 0x12C3C7), &nops); +#if 0 + UINT64 tmp2[1024]; + SSIZE_T siz2 = KMemoryBuf::Rpm(targetPID, (PVOID)(m_EntityArray), (PBYTE)tmp2); + SIZE_T i = 0; + for (UINT64 val : tmp2) { + if (val) + std::wcout << WHEXOUT << val << ", "; + if (++i % 16 == 0) + std::wcout << std::endl; + } + /* + if (siz2 > 0) + printBuf(tmp2, sizeof tmp2, 64); + */ +#endif +#endif +#if 0 + SSIZE_T siz3; + static Diff<65535> diff = { 0 }; + siz3 = KScan::BinDiffSimple(targetPID, (PVOID)(m_EntityArray), &diff); + if (siz3 > 0) { + std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl; + for (auto& e : diff.diffs) { + std::wcout << std::dec << L"0x" + << std::hex << (PVOID)(/*(ULONG_PTR)(m_EntityArray)+*/e.first) + << " - " << std::hex << e.second + << L": "; + printBuf((UCHAR *)((ULONG_PTR)(diff.current_buffer) + e.first), e.second, e.second); + } + } +#endif +#if 0 +#if 1 + //UCHAR scan[1024] = { 0 }; + UCHAR scan[] = "anti_alles"; + SSIZE_T found = KScan::ScanSimple(targetPID, + (PVOID)(m_EntityArray), 65535, scan); +#else + SSIZE_T found = (SSIZE_T)(pIEntitySystem)+8192; +#endif + if (found >= 0) { + std::wcout << "FOUND: 0x" << std::hex << (PVOID)found << std::endl; + UCHAR tmp[4096] = { 0 }; + SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)found, tmp); + if (siz > 0) { + printBuf(tmp, sizeof tmp, 64); +#if 0 + UINT64 i; + for (i = 0; i < sizeof tmp; i += 8) { + UINT64 value = *(UINT64 *)&tmp[i]; + if (value) + printf("0x%p ", (PVOID)value); + } + printf("\nGot %llu entities ..\n", i); +#endif + } + } +#endif +#endif + } +#if 0 + else if (!strncmp(md.BaseDllName, "CryRenderD3D11.dll", + sizeof md.BaseDllName)) + { + UINT32 displayWidth = KMemory::Rpm(targetPID, + (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0FE */ 0x5EA870)); + UINT32 displayHeight = KMemory::Rpm(targetPID, + (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0F0 */ 0x5EA9DC)); + std::wcout << L"Display.........: " << std::dec << displayWidth + << " x " << displayHeight << std::endl; + } +#endif +#if 0 + else if (!strncmp(md.BaseDllName, "ntdll.dll", + sizeof md.BaseDllName)) + { + UCHAR tmp[8192] = { 0 }; + SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)((ULONGLONG)md.DllBase), tmp); + /* + if (siz > 0) + printBuf(tmp, sizeof tmp, 64); + + UCHAR scan[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; + SSIZE_T found = KScan::ScanSimple(targetPID, + (PVOID)((ULONGLONG)md.DllBase), sizeof tmp, scan); + std::wcout << "FOUND: 0x" << std::hex << (found - (ULONGLONG)md.DllBase) << std::endl; + */ + static Diff<10> diff = { 0 }; + siz = KScan::BinDiffSimple(targetPID, (PVOID)((ULONGLONG)md.DllBase), &diff); + if (siz > 0) { + std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl; + for (auto& e : diff.diffs) { + printBuf((UCHAR *)((ULONGLONG)md.DllBase + e.first), e.second, e.second); + /* + std::wcout << std::dec << L" addr: " << e.first + << std::endl << L" size: " << e.second + << std::endl; + */ + } + } + } +#endif + } + } + } + catch (std::runtime_error& err) { + std::wcout << err.what() << std::endl; + } + } while (running); + + std::wcout << L"Driver shutdown .." << std::endl; + ki.Exit(); + + return 0; +} \ No newline at end of file diff --git a/Hunted/Hunted.vcxproj b/Hunted/Hunted.vcxproj new file mode 100644 index 0000000..a87c397 --- /dev/null +++ b/Hunted/Hunted.vcxproj @@ -0,0 +1,194 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {8661069D-CE09-4A70-8C75-8F33E77732E6} + Win32Proj + Hunted + 10.0.17763.0 + Hunted + + + + Application + true + v141 + Unicode + false + + + Application + false + v141 + true + Unicode + false + + + Application + true + v141 + Unicode + Static + false + + + Application + false + v141 + true + Unicode + false + Static + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + MultiThreadedDebug + SyncCThrow + true + $(SolutionDir)include + + + Console + true + $(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories) + false + + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + SyncCThrow + false + MultiThreaded + + + Console + true + false + + + + + Use + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + Sync + false + + + Console + true + true + true + false + + + + + Use + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + Sync + false + $(SolutionDir)include + + + Console + true + true + true + $(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories) + false + + + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/Hunted/Hunted.vcxproj.filters b/Hunted/Hunted.vcxproj.filters new file mode 100644 index 0000000..6961c18 --- /dev/null +++ b/Hunted/Hunted.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/Hunted/KInterface.cpp b/Hunted/KInterface.cpp new file mode 100644 index 0000000..62859a4 --- /dev/null +++ b/Hunted/KInterface.cpp @@ -0,0 +1,326 @@ +#include "pch.h" +#include "KInterface.h" +#include "KMemDriver.h" + +#include +#include +#include + + +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& 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& 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 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> *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 + (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 diff --git a/Hunted/pch.cpp b/Hunted/pch.cpp new file mode 100644 index 0000000..3a3d12b --- /dev/null +++ b/Hunted/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed + +#include "pch.h" + +// In general, ignore this file, but keep it around if you are using pre-compiled headers. diff --git a/Hunted/pch.h b/Hunted/pch.h new file mode 100644 index 0000000..b04e71e --- /dev/null +++ b/Hunted/pch.h @@ -0,0 +1,14 @@ +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file + +#ifndef PCH_H +#define PCH_H + +// TODO: add headers that you want to pre-compile here + +#endif //PCH_H diff --git a/KMemDriver.sln b/KMemDriver.sln index 8e5601e..75c1b3b 100644 --- a/KMemDriver.sln +++ b/KMemDriver.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.28307.421 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KMemDriver", "KMemDriver\KMemDriver.vcxproj", "{5B65BD0E-C43C-41E3-A016-1CD0B092998F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KTest", "KTest\KTest.vcxproj", "{8661069D-CE09-4A70-8C75-8F33E77732E6}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Hunted", "Hunted\Hunted.vcxproj", "{8661069D-CE09-4A70-8C75-8F33E77732E6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemDriverLib", "MemDriverLib\MemDriverLib.vcxproj", "{B6790A97-6995-46B6-AD73-AC5BC4AC76DB}" EndProject diff --git a/KTest/KInterface.cpp b/KTest/KInterface.cpp deleted file mode 100644 index dae57e3..0000000 --- a/KTest/KInterface.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "pch.h" -#include "KInterface.h" -#include "Driver.h" - -#include -#include -#include - - -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& 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& 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 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> *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 - (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 diff --git a/KTest/KTest.cpp b/KTest/KTest.cpp deleted file mode 100644 index 4dad138..0000000 --- a/KTest/KTest.cpp +++ /dev/null @@ -1,400 +0,0 @@ -#include "pch.h" -#include "Driver.h" -#include "KInterface.h" - -#include -#include -#include - -#pragma comment(lib, "User32.lib") - -#define WHEXOUT std::setfill(L'0') << std::setw(16) << std::hex - -BOOL running = false; -const wchar_t *wName = L"HUNT"; - -typedef struct SSystemGlobalEnvironment -{ - PVOID pDialogSystem; - PVOID p3DEngine; - PVOID pNetwork; - PVOID pNetContext; - PVOID pLobby; - PVOID pScriptSystem; - PVOID pPhysicalWorld; - PVOID pFlowSystem; - PVOID pInput; - PVOID pStatoscope; - PVOID pCryPak; - PVOID pFileChangeMonitor; - PVOID pProfileLogSystem; - PVOID pParticleManager; - PVOID pOpticsManager; - PVOID pFrameProfileSystem; - PVOID pTimer; - PVOID pCryFont; - PVOID pGameFramework; - PVOID pLocalMemoryUsage; - PVOID pEntitySystem; - PVOID pConsole; - PVOID pAudioSystem; - PVOID pSystem; - PVOID pCharacterManager; - PVOID pAISystem; - PVOID pLog; - PVOID pCodeCheckpointMgr; - PVOID pMovieSystem; - PVOID pNameTable; - PVOID pRenderer; - PVOID pAuxGeomRenderer; - PVOID pHardwareMouse; - PVOID pMaterialEffects; - PVOID pJobManager; - PVOID pOverloadSceneManager; - PVOID pFlashUI; - PVOID pUIFramework; - PVOID pServiceNetwork; - PVOID pRemoteCommandManager; - PVOID pDynamicResponseSystem; - PVOID pThreadManager; - PVOID pScaleformHelper; // nullptr when Scaleform support is not enabled - PVOID pSchematyc; - PVOID pSchematyc2; - PVOID pReflection; - - PVOID pLiveCreateManager; - PVOID pLiveCreateHost; - PVOID pMonoRuntime; - UINT32 mMainThreadId; //!< The main thread ID is used in multiple systems so should be stored globally. - UINT32 nMainFrameID; - const char* szCmdLine = ""; //!< Startup command line. - - //! Generic debug string which can be easily updated by any system and output by the debug handler - enum { MAX_DEBUG_STRING_LENGTH = 128 }; - char szDebugStatus[MAX_DEBUG_STRING_LENGTH]; - - //! Used to tell if this is a server/multiplayer instance - bool bServer; - bool bMultiplayer; - bool bHostMigrating; - int bDeepProfiling; - bool bBootProfilerEnabledFrames; - PVOID callbackStartSection; - PVOID callbackEndSection; - ////////////////////////////////////////////////////////////////////////// - - //! Whether we are running unattended, disallows message boxes and other blocking events that require human intervention - bool bUnattendedMode; - //! Whether we are unit testing - bool bTesting; - - bool bNoRandomSeed; -} SSystemGlobalEnvironment; - - - -bool consoleHandler(int signal) { - if (signal == CTRL_C_EVENT) { - if (!running) - exit(EXIT_FAILURE); - running = false; - std::wcout << L"Waiting for graceful shutdown .." << std::endl; - } - return true; -} - -void printBuf(UCHAR *buf, SIZE_T siz, SIZE_T bytesBeforeNewline) { - unsigned int i, j; - const unsigned char colors[] = { 10,11,12,13,14,15 }; - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - - for (i = 0, j = 0; i < siz; ++i) { - if (i % bytesBeforeNewline == 0) { - SetConsoleTextAttribute(hConsole, colors[j++ % (sizeof colors)]); - wprintf(L"\n0x%04X: ", i); - } - wprintf(L"%02X ", buf[i]); - } - wprintf(L"\n"); - SetConsoleTextAttribute(hConsole, 15); -} - -BOOL CALLBACK enumWindowsProc(HWND hWnd, LPARAM lParam) -{ - int length = GetWindowTextLength(hWnd); - TCHAR* buffer; - buffer = new TCHAR[length + 1]; - memset(buffer, 0, (length + 1) * sizeof(TCHAR)); - GetWindowText(hWnd, buffer, length + 1); - if (!wcscmp(buffer, wName)) - *(HWND *)lParam = hWnd; - delete[] buffer; - return TRUE; -} - -int wmain(int argc, wchar_t **argv) -{ - HANDLE targetPID = 0; - PVOID buf; - HANDLE kevent; - HANDLE uevent; - - KInterface &ki = KInterface::getInstance(); - std::vector pages; - std::vector modules; - - if (argc > 1 && !wcscmp(argv[1], L"test")) { - return 0; - } - - if (argc > 1 && !wcscmp(argv[1], L"wnd")) { - if (argc < 3) { - std::wcout << L"Window title required!" << std::endl; - return 1; - } - wName = argv[2]; - std::wcout << L"Waiting for window title: '" << wName << L"'" << std::endl; - - HWND targetHWND = NULL; - while (1) { - if (!EnumWindows(enumWindowsProc, (LPARAM)&targetHWND)) { - return 1; - } - if (targetHWND) { - std::wcout << L"Found window '" << wName << L"' with Handle 0x" - << std::hex << targetHWND << std::endl; - break; - } - Sleep(1000); - } - GetWindowThreadProcessId(targetHWND, (LPDWORD)&targetPID); - } - - SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE); - - if (!ki.Init()) { - std::wcout << L"Kernel Interface Init() failed" << std::endl; - return 1; - } - - try { - buf = ki.getBuffer(); - kevent = ki.getKHandle(); - uevent = ki.getUHandle(); - } - catch (std::runtime_error& err) { - std::wcout << err.what() << std::endl; - return 1; - } - - std::wcout << L"Buffer.: " << buf << std::endl; - std::wcout << L"KHandle: " << kevent << std::endl; - std::wcout << L"UHandle: " << uevent << std::endl; - - if (!ki.Handshake()) { - std::wcout << L"Kernel Interface Handshake() failed" << std::endl; - return 1; - } - if (targetPID) { - if (!ki.Modules(targetPID, modules)) - std::wcout << L"Kernel Interface Modules() failed with 0x" - << std::hex << ki.getLastNtStatus() << std::endl; - else std::wcout << L"Got " << std::dec << modules.size() << L" modules for pid 0x" - << std::hex << targetPID << std::endl; - if (!ki.Pages(targetPID, pages)) - std::wcout << L"Kernel Interface Pages() failed with 0x" - << std::hex << ki.getLastNtStatus() << std::endl; - else std::wcout << L"Got " << std::dec << pages.size() << L" mapped pages for pid 0x" - << std::hex << targetPID << std::endl; - } - - running = TRUE; - do { - if (ki.RecvWait() == SRR_TIMEOUT) { - std::wcout << L"Ping -> "; - if (!ki.Ping()) { - std::wcout << L"Got no valid PONG, abort!" << std::endl; - running = FALSE; - } - else std::wcout << L"PONG!" << std::endl; - } - - if (!running) - break; - - try { - if (targetPID) { - for (MODULE_DATA& md : modules) { - if (!strncmp(md.BaseDllName, "CrySystem.dll", - sizeof md.BaseDllName)) - { - std::wcout << L"CrySystem.dll......: 0x" << WHEXOUT << md.DllBase << std::endl; - UINT64 g_pEnv = KMemory::Rpm(targetPID, - (PVOID)((UINT64)md.DllBase + 0xA37708)); - - std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl; - } - else - if (!strncmp(md.BaseDllName, "CryEntitySystem.dll", - sizeof md.BaseDllName)) - { - std::wcout << L"CryEntitySystem.dll: 0x" << std::hex << md.DllBase << std::endl; -#if 1 - /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader) */ - UINT64 g_pEnv = KMemory::Rpm(targetPID, - (PVOID)((UINT64)md.DllBase + 0x28C400)); - - std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl; -#if 1 - BYTE tmp[sizeof SSystemGlobalEnvironment * 2] = { 0 }; - SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)(g_pEnv), tmp); - - SSystemGlobalEnvironment *gEnv = (SSystemGlobalEnvironment *)&tmp[0]; - std::wcout << std::hex - << gEnv->p3DEngine << ", " - << gEnv->pEntitySystem << ", " - << gEnv->bMultiplayer << ", " - << gEnv->mMainThreadId << ", " - << gEnv->nMainFrameID << ", " - << gEnv->szDebugStatus << ", " - << gEnv->pMonoRuntime << ", " - << gEnv->callbackStartSection << ", " - << gEnv->callbackEndSection << ", " - << gEnv->bUnattendedMode << ", " - << gEnv->bTesting << ", " - << gEnv->bNoRandomSeed << ", " - << gEnv->bDeepProfiling << ", " - << std::endl; - - /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader) - * search for String "ExistingEntity: '%s' '%s'" - */ - UINT64 m_EntityArray = KMemory::Rpm(targetPID, - (PVOID)((UINT64)gEnv->pEntitySystem + 0x40078)); - //m_EntityArray += 0x40078; - std::wcout << WHEXOUT - << m_EntityArray - << std::endl; - - USHORT nops; - nops = KMemory::Rpm(targetPID, - (PVOID)((UINT64)md.DllBase + 0x12C3C7)); - std::wcout << std::hex << "+++ " << nops << std::endl; - nops = 0x9090; - KMemory::Wpm(targetPID, - (PVOID)((UINT64)md.DllBase + 0x12C3C7), &nops); -#if 0 - UINT64 tmp2[1024]; - SSIZE_T siz2 = KMemoryBuf::Rpm(targetPID, (PVOID)(m_EntityArray), (PBYTE)tmp2); - SIZE_T i = 0; - for (UINT64 val : tmp2) { - if (val) - std::wcout << WHEXOUT << val << ", "; - if (++i % 16 == 0) - std::wcout << std::endl; - } - /* - if (siz2 > 0) - printBuf(tmp2, sizeof tmp2, 64); - */ -#endif -#endif -#if 0 - SSIZE_T siz3; - static Diff<65535> diff = { 0 }; - siz3 = KScan::BinDiffSimple(targetPID, (PVOID)(m_EntityArray), &diff); - if (siz3 > 0) { - std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl; - for (auto& e : diff.diffs) { - std::wcout << std::dec << L"0x" - << std::hex << (PVOID)(/*(ULONG_PTR)(m_EntityArray)+*/e.first) - << " - " << std::hex << e.second - << L": "; - printBuf((UCHAR *)((ULONG_PTR)(diff.current_buffer) + e.first), e.second, e.second); - } - } -#endif -#if 0 -#if 1 - //UCHAR scan[1024] = { 0 }; - UCHAR scan[] = "anti_alles"; - SSIZE_T found = KScan::ScanSimple(targetPID, - (PVOID)(m_EntityArray), 65535, scan); -#else - SSIZE_T found = (SSIZE_T)(pIEntitySystem)+8192; -#endif - if (found >= 0) { - std::wcout << "FOUND: 0x" << std::hex << (PVOID)found << std::endl; - UCHAR tmp[4096] = { 0 }; - SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)found, tmp); - if (siz > 0) { - printBuf(tmp, sizeof tmp, 64); -#if 0 - UINT64 i; - for (i = 0; i < sizeof tmp; i += 8) { - UINT64 value = *(UINT64 *)&tmp[i]; - if (value) - printf("0x%p ", (PVOID)value); - } - printf("\nGot %llu entities ..\n", i); -#endif - } - } -#endif -#endif - } -#if 0 - else if (!strncmp(md.BaseDllName, "CryRenderD3D11.dll", - sizeof md.BaseDllName)) - { - UINT32 displayWidth = KMemory::Rpm(targetPID, - (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0FE */ 0x5EA870)); - UINT32 displayHeight = KMemory::Rpm(targetPID, - (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0F0 */ 0x5EA9DC)); - std::wcout << L"Display.........: " << std::dec << displayWidth - << " x " << displayHeight << std::endl; - } -#endif -#if 0 - else if (!strncmp(md.BaseDllName, "ntdll.dll", - sizeof md.BaseDllName)) - { - UCHAR tmp[8192] = { 0 }; - SSIZE_T siz = KMemoryBuf::Rpm(targetPID, (PVOID)((ULONGLONG)md.DllBase), tmp); - /* - if (siz > 0) - printBuf(tmp, sizeof tmp, 64); - - UCHAR scan[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; - SSIZE_T found = KScan::ScanSimple(targetPID, - (PVOID)((ULONGLONG)md.DllBase), sizeof tmp, scan); - std::wcout << "FOUND: 0x" << std::hex << (found - (ULONGLONG)md.DllBase) << std::endl; - */ - static Diff<10> diff = { 0 }; - siz = KScan::BinDiffSimple(targetPID, (PVOID)((ULONGLONG)md.DllBase), &diff); - if (siz > 0) { - std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl; - for (auto& e : diff.diffs) { - printBuf((UCHAR *)((ULONGLONG)md.DllBase + e.first), e.second, e.second); - /* - std::wcout << std::dec << L" addr: " << e.first - << std::endl << L" size: " << e.second - << std::endl; - */ - } - } - } -#endif - } - } - } - catch (std::runtime_error& err) { - std::wcout << err.what() << std::endl; - } - } while (running); - - std::wcout << L"Driver shutdown .." << std::endl; - ki.Exit(); - - return 0; -} \ No newline at end of file diff --git a/KTest/KTest.vcxproj b/KTest/KTest.vcxproj deleted file mode 100644 index d2a9fcd..0000000 --- a/KTest/KTest.vcxproj +++ /dev/null @@ -1,193 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {8661069D-CE09-4A70-8C75-8F33E77732E6} - Win32Proj - KTest - 10.0.17763.0 - - - - Application - true - v141 - Unicode - false - - - Application - false - v141 - true - Unicode - false - - - Application - true - v141 - Unicode - Static - false - - - Application - false - v141 - true - Unicode - false - Static - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Level3 - Disabled - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - MultiThreadedDebug - SyncCThrow - true - $(SolutionDir)include - - - Console - true - $(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories) - false - - - - - Use - Level3 - Disabled - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - SyncCThrow - false - MultiThreaded - - - Console - true - false - - - - - Use - Level3 - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - Sync - false - - - Console - true - true - true - false - - - - - Use - Level3 - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - Sync - false - $(SolutionDir)include - - - Console - true - true - true - $(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories) - false - - - - - - - - - - - - Create - Create - Create - Create - - - - - - \ No newline at end of file diff --git a/KTest/KTest.vcxproj.filters b/KTest/KTest.vcxproj.filters deleted file mode 100644 index edf8597..0000000 --- a/KTest/KTest.vcxproj.filters +++ /dev/null @@ -1,39 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/KTest/pch.cpp b/KTest/pch.cpp deleted file mode 100644 index 3a3d12b..0000000 --- a/KTest/pch.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed - -#include "pch.h" - -// In general, ignore this file, but keep it around if you are using pre-compiled headers. diff --git a/KTest/pch.h b/KTest/pch.h deleted file mode 100644 index b04e71e..0000000 --- a/KTest/pch.h +++ /dev/null @@ -1,14 +0,0 @@ -// Tips for Getting Started: -// 1. Use the Solution Explorer window to add/manage files -// 2. Use the Team Explorer window to connect to source control -// 3. Use the Output window to see build output and other messages -// 4. Use the Error List window to view errors -// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project -// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file - -#ifndef PCH_H -#define PCH_H - -// TODO: add headers that you want to pre-compile here - -#endif //PCH_H -- cgit v1.2.3