diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2024-03-14 12:35:46 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2024-03-14 12:35:46 +0100 |
commit | ffd009ce14f5cf5a0a00b5477b54c518716d9eab (patch) | |
tree | 13a6de53cf5041a3c4c559c3e594703ef078aa84 | |
parent | 07ca2a71eda0a0a6ca4d17335033e4fcfdbd4d87 (diff) |
Updated Tarkov driver (still WiP!)
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | bf4.cpp | 8 | ||||
-rw-r--r-- | memory.hpp | 29 | ||||
-rw-r--r-- | tarkov.cpp | 205 | ||||
-rw-r--r-- | tfk.bat | 4 |
5 files changed, 233 insertions, 25 deletions
@@ -3,7 +3,13 @@ Made for [mingw-w64-dpp](https://github.com/utoni/mingw-w64-dpp). ```shell -make DPP_ROOT="[path-to-mingw-w64-ddk-template-dir]" all +make DPP_ROOT="[path-to-mingw-w64-dpp-dir]" all +``` + +or if you want to install driver/batch files somewhere e.g. to a mounted NTFS volume: + +```shell +make DPP_ROOT="[path-to-mingw-w64-dpp-dir]" DESTDIR=/media/win10/Users/nobody/mingw64-kmem install -j8 ``` # Examples @@ -18,3 +24,7 @@ This ring0 based game hack provide you with: * unlimited breath As usual: Use it at your own risk! + +## Escape From Tarkov (tfk.sys) + +WiP! @@ -8,12 +8,12 @@ using namespace DriverThread; static Thread thread; static Event shutdown_event; +static const wchar_t targetProcess[] = L"bf4.exe"; static uint64_t SearchBF4Process(void) { const auto &procs = ::GetProcesses(); - const wchar_t targetProcess[] = L"bf4.exe"; const auto &found = eastl::find_if(procs.begin(), procs.end(), - [&targetProcess](const auto &item) { + [](const auto &item) { if (item.ProcessName == targetProcess) return true; return false; @@ -69,7 +69,7 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, const auto mods = ::GetModules(pep, FALSE); DbgPrint("mods: %zu\n", mods.size()); for (const auto &mod : mods) { - if (mod.BaseDllName == L"bf4.exe") { + if (mod.BaseDllName == targetProcess) { DbgPrint("%s\n", "found"); base = mod.DllBase; break; @@ -170,8 +170,6 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, memory.Write<const uint32_t>(firing_function_data + 0x0060 + 0x007C, 2); } - if (bf4_pid) - ::CloseProcess(&pep, &obj); return STATUS_SUCCESS; }, args); @@ -91,17 +91,40 @@ public: } template<typename T> + T ReadChain(uint64_t sourceAddress, const eastl::vector<uint64_t>& chainedOffsets) { + for (const auto& offset : chainedOffsets) { + if (offset == chainedOffsets.back()) + break; + sourceAddress = Read<uint64_t>(sourceAddress + offset); + if (!sourceAddress) + break; + } + return Read<T>(sourceAddress); + } + + template<typename T, size_t N> + bool ReadBuffer(uint64_t sourceAddress, T out[N]) { + if (!IsValidAddress(sourceAddress)) + return false; + SIZE_T size = sizeof(T) * N; + m_last_error = ReadVirtualMemory(m_pep, sourceAddress, reinterpret_cast<UCHAR*>(out), &size); + m_last_size = size; + return Succeeded<T, N>(); + } + + template<typename T> bool Write(uint64_t targetAddress, const T& writeData) { if (!IsValidAddress(targetAddress)) return false; SIZE_T size = sizeof(T); m_last_error = WriteVirtualMemory(m_pep, reinterpret_cast<const UCHAR*>(&writeData), targetAddress, &size); m_last_size = size; - if (m_last_error == STATUS_SUCCESS && m_last_size == sizeof(T)) - return true; - return false; + return Succeeded<T, 1>(); } + template<typename T, size_t N> + bool Succeeded() { return m_last_error == STATUS_SUCCESS && m_last_size == sizeof(T) * N; } + NTSTATUS LastError() { return m_last_error; } SIZE_T LastSize() { return m_last_size; } @@ -1,18 +1,81 @@ #include <ntddk.h> +#include <EASTL/array.h> #include <DriverThread.hpp> +#include <obfuscate.hpp> #include "memory.hpp" using namespace DriverThread; static Thread thread; +static Event shutdown_event; +static auto targetProcess = skCrypt(L"EscapeFromTarkov.exe"); +static auto targetModule = skCrypt(L"UnityPlayer.dll"); + +struct BaseObject +{ + uint64_t previousObjectLink; + uint64_t nextObjectLink; + uint64_t object; +}; + +struct GameObjectManager +{ + uint64_t lastTaggedObject; + uint64_t taggedObjects; + uint64_t lastActiveObject; + uint64_t activeObjects; + uint64_t LastActiveNode; + uint64_t ActiveNodes; +}; + +struct UnityList +{ + char pad[16]; // 0x00->0x10; + uint64_t pointer; + uint32_t size; +}; + +static uint64_t GetObjectFromList(Memory& memory, uint64_t listPtr, uint64_t lastObjectPtr, const char * const objectName) +{ + char name[128]; + uint64_t classNamePtr = 0x0; + + BaseObject activeObject = memory.Read<BaseObject>(listPtr); + BaseObject lastObject = memory.Read<BaseObject>(lastObjectPtr); + + if (activeObject.object != 0x0) + { + while (activeObject.object != 0 && activeObject.object != lastObject.object) + { + classNamePtr = memory.Read<uint64_t>(activeObject.object + 0x60); + memory.ReadBuffer<char, sizeof(name)>(classNamePtr, name); + + if (strncmp(name, objectName, sizeof(name)) == 0) + return activeObject.object; + + activeObject = memory.Read<BaseObject>(activeObject.nextObjectLink); + } + } + if (lastObject.object != 0x0) + { + classNamePtr = memory.Read<uint64_t>(lastObject.object + 0x60); + memory.ReadBuffer<char, sizeof(name)>(classNamePtr, name); + + if (strncmp(name, objectName, sizeof(name)) == 0) + return lastObject.object; + } + + memset(name, 0, sizeof(name)); + + return 0; +} static uint64_t SearchTarkovProcess(void) { const auto &procs = ::GetProcesses(); - const wchar_t targetProcess[] = L"EscapeFromTarkov.exe"; const auto &found = eastl::find_if(procs.begin(), procs.end(), - [&targetProcess](const auto &item) { + [](const auto &item) { if (item.ProcessName == targetProcess) return true; return false; @@ -39,20 +102,133 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, [](eastl::shared_ptr<ThreadArgs> args) { UNREFERENCED_PARAMETER(args); - auto pid = reinterpret_cast<HANDLE>(SearchTarkovProcess()); - if (pid == NULL) { - return STATUS_SUCCESS; - } - DbgPrint("Process pid: %p\n", pid); - - PEPROCESS pep; - HANDLE obj; - if (!NT_SUCCESS(::OpenProcess(pid, &pep, &obj))) { - return STATUS_SUCCESS; + HANDLE tarkov_pid = NULL; + PEPROCESS pep = NULL; + HANDLE obj = NULL; + uint64_t base = 0; + LONGLONG wait_timeout = (-1LL) * 10LL * 1000LL * 250LL; + + DbgPrint("%s\n", "start"); + while (shutdown_event.Wait(wait_timeout) == STATUS_TIMEOUT) { + if (!tarkov_pid) { + wait_timeout = (-1LL) * 10LL * 1000LL * 1000LL; + tarkov_pid = reinterpret_cast<HANDLE>(SearchTarkovProcess()); + if (tarkov_pid == NULL) { + continue; + } + DbgPrint("pid: %p\n", tarkov_pid); + + if (!NT_SUCCESS(::OpenProcess(tarkov_pid, &pep, &obj))) { + tarkov_pid = NULL; + continue; + } + + base = 0; + while (!base && tarkov_pid) { + LARGE_INTEGER wait = {.QuadPart = (-1LL) * 10LL * 1000LL * 250LL}; + KeDelayExecutionThread(KernelMode, TRUE, &wait); + + const auto mods = ::GetModules(pep, FALSE); + DbgPrint("mods: %zu\n", mods.size()); + for (const auto &mod : mods) { + if (mod.BaseDllName == targetModule) { + DbgPrint("%s\n", "found"); + base = mod.DllBase; + break; + } + } + + tarkov_pid = reinterpret_cast<HANDLE>(SearchTarkovProcess()); + } + + if (!tarkov_pid) { + ::CloseProcess(&pep, &obj); + continue; + } + + //wait_timeout = (-1LL) * 10LL * 1000LL * 50LL; + } + + Memory memory(pep); + auto gom_ptr = memory.Read<uint64_t>(base + 0x17FFD28); + auto gom = memory.Read<GameObjectManager>(gom_ptr); + if (!gom_ptr) { + ::CloseProcess(&pep, &obj); + tarkov_pid = NULL; + continue; + } + + uint64_t activeNodes = memory.Read<uint64_t>(gom.ActiveNodes); + uint64_t lastActiveNode = memory.Read<uint64_t>(gom.LastActiveNode); + auto game_world = GetObjectFromList(memory, activeNodes, lastActiveNode, "GameWorld"); + auto local_game_world = memory.ReadChain<uint64_t>(game_world, { 0x30, 0x18, 0x28 }); + auto local_player = memory.Read<uint64_t>(local_game_world + 0x118); + auto player_list_ptr = memory.Read<uint64_t>(local_game_world + 0xC0); + auto player_list = memory.Read<UnityList>(player_list_ptr); + auto count = memory.Read<uint32_t>(player_list_ptr + 0x40); + + //auto registered_players = memory.Read<uint64_t>(local_game_world + 0xC0); + //auto player_count = memory.Read<uint32_t>(registered_players + 0x18); + DbgPrint("%p,%p,%p,%p,%p,%u,%u\n", game_world, local_game_world, local_player, player_list_ptr, player_list.pointer, player_list.size, count); +#if 0 + auto lgw = memory.ReadChain<uint64_t>(gom, { 0x30, 0x18, 0x28 }); + if (!lgw) + continue; + + auto registered_players = memory.Read<uint64_t>(lgw + 0xC0); + auto player_count = memory.Read<uint64_t>(registered_players + 0x18); + uint64_t i; + for (i = 0; i < player_count; ++i) { + auto player_ptr = memory.Read<uint64_t>(registered_players + 0x20 + i * 0x8); + auto class_name_ptr = memory.ReadChain<uint64_t>(player_ptr, { 0x0, 0x0, 0x48 }); + //if (!class_name_ptr) + // break; + char buf[64]; + memory.ReadBuffer<char, 64>(class_name_ptr, buf); + DbgPrint("++%.*s++\n", (int)memory.LastSize(), buf); + } + DbgPrint("__%llu,%llu__\n", i, player_count); +#endif +#if 0 + auto camera_address = memory.Read<uint64_t>(base + 0x0179F500); + if (!camera_address) + continue; + auto all_cameras = memory.Read<uint64_t>(camera_address); + if (!all_cameras) + continue; + + uint64_t optic_camera = 0; + for (uint64_t i = 0; i < 512; ++i) { + auto camera = memory.Read<uint64_t>(all_cameras + i * 0x8); + if (!camera) + break; + auto camera_obj = memory.Read<uint64_t>(camera + 0x30); + if (!camera_obj) + break; + auto camera_name_ptr = memory.Read<uint64_t>(camera_obj + 0x60); + + char buf[64]; + memory.ReadBuffer<char, 64>(camera_name_ptr, buf); + if (memory.LastSize() > 0 && strncmp(buf, skCrypt("BaseOpticCamera(Clone)"), sizeof(buf)) == 0) + optic_camera = camera_name_ptr; + } + DbgPrint("--%p,%p--\n", lgw, optic_camera); + + if (!optic_camera) + continue; + auto component_list = memory.Read<uint64_t>(optic_camera + 0x30); + if (!component_list) + continue; + uint64_t i; + for (i = 0; i < 64; ++i) { + auto field = memory.ReadChain<uint64_t>(component_list, { 0x8 + (i * 0x10), 0x28 }); + if (!field) + break; + } + DbgPrint("++%llu++\n", i); +#endif } - // TODO: Fill me with useful code.. ;) - return STATUS_SUCCESS; }, args); @@ -64,6 +240,7 @@ VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DbgPrint("%s\n", "Waiting for thread termination.."); + shutdown_event.Notify(); thread.WaitForTermination(); } } @@ -1,6 +1,6 @@ @echo off -set SERVICE_NAME=tkf -set DRIVER="%~dp0\tkf.sys" +set SERVICE_NAME=tfk +set DRIVER="%~dp0\tfk.sys" net session >nul 2>&1 if NOT %ERRORLEVEL% EQU 0 ( |