diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2024-03-10 00:13:52 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2024-03-12 00:13:52 +0100 |
commit | 07ca2a71eda0a0a6ca4d17335033e4fcfdbd4d87 (patch) | |
tree | ff5806996d6b70d3942d681cc4d0f83774a302b7 | |
parent | 5d697079989f35a437e5101418289b26e6c1f3a6 (diff) |
Add Battlefield4 hack.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | bf4.bat | 27 | ||||
-rw-r--r-- | bf4.cpp | 189 |
4 files changed, 244 insertions, 3 deletions
@@ -4,6 +4,8 @@ endif include $(DPP_ROOT)/Makefile.inc +COMMON_HEADERS = native.h memory.hpp + DRIVER_NAME = driver-kmem DRIVER_OBJECTS = $(DRIVER_NAME).o memory.o DRIVER_TARGET = $(DRIVER_NAME).sys @@ -12,19 +14,26 @@ TARKOV_NAME = tfk TARKOV_OBJECTS = tarkov.o memory.o TARKOV_TARGET = $(TARKOV_NAME).sys -all: $(DRIVER_TARGET) $(TARKOV_TARGET) +BF4_NAME = bf4 +BF4_OBJECTS = bf4.o memory.o +BF4_TARGET = $(BF4_NAME).sys + +all: $(DRIVER_TARGET) $(TARKOV_TARGET) $(BF4_TARGET) -install: $(DRIVER_TARGET) $(TARKOV_TARGET) +install: $(DRIVER_TARGET) $(TARKOV_TARGET) $(BF4_TARGET) $(call INSTALL_EXEC_SIGN,$(DRIVER_TARGET)) $(INSTALL) $(DRIVER_NAME).bat $(DESTDIR) $(call INSTALL_EXEC_SIGN,$(TARKOV_TARGET)) $(INSTALL) $(TARKOV_NAME).bat $(DESTDIR) + $(call INSTALL_EXEC_SIGN,$(BF4_TARGET)) + $(INSTALL) $(BF4_NAME).bat $(DESTDIR) clean: rm -f $(DRIVER_OBJECTS) $(DRIVER_TARGET) rm -f $(TARKOV_OBJECTS) $(TARKOV_TARGET) + rm -f $(BF4_OBJECTS) $(BF4_TARGET) -%.o: %.cpp +%.o: %.cpp $(COMMON_HEADERS) $(call BUILD_CPP_OBJECT,$<,$@) $(DRIVER_TARGET): $(DRIVER_OBJECTS) @@ -32,3 +41,6 @@ $(DRIVER_TARGET): $(DRIVER_OBJECTS) $(TARKOV_TARGET): $(TARKOV_OBJECTS) $(call LINK_CPP_KERNEL_TARGET,$(TARKOV_OBJECTS),$@) + +$(BF4_TARGET): $(BF4_OBJECTS) + $(call LINK_CPP_KERNEL_TARGET,$(BF4_OBJECTS),$@) @@ -5,3 +5,16 @@ Made for [mingw-w64-dpp](https://github.com/utoni/mingw-w64-dpp). ```shell make DPP_ROOT="[path-to-mingw-w64-ddk-template-dir]" all ``` + +# Examples + +## Battlefield4 Driver (bf4.sys) + +This ring0 based game hack provide you with: + + * two bullets per shell/shot + * recoil removal + * deviation removal + * unlimited breath + +As usual: Use it at your own risk! @@ -0,0 +1,27 @@ +@echo off +set SERVICE_NAME=bf4 +set DRIVER="%~dp0\bf4.sys" + +net session >nul 2>&1 +if NOT %ERRORLEVEL% EQU 0 ( + echo ERROR: This script requires Administrator privileges! + pause + exit /b 1 +) + +echo --------------------------------------- +echo -- Service Name: %SERVICE_NAME% +echo -- Driver......: %DRIVER% +echo --------------------------------------- + +sc create %SERVICE_NAME% binPath= %DRIVER% type= kernel +echo --------------------------------------- +sc start %SERVICE_NAME% +echo --------------------------------------- +sc query %SERVICE_NAME% +echo [PRESS A KEY TO STOP THE DRIVER] +pause +sc stop %SERVICE_NAME% +sc delete %SERVICE_NAME% +echo Done. +timeout /t 3 @@ -0,0 +1,189 @@ +#include <ntddk.h> + +#include <DriverThread.hpp> + +#include "memory.hpp" + +using namespace DriverThread; + +static Thread thread; +static Event shutdown_event; + +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) { + if (item.ProcessName == targetProcess) + return true; + return false; + }); + + if (found == procs.end()) { + return 0; + } + + return found->UniqueProcessId; +} + +extern "C" { +DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD DriverUnload; + +NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, + _In_ PUNICODE_STRING RegistryPath) { + UNREFERENCED_PARAMETER(DriverObject); + UNREFERENCED_PARAMETER(RegistryPath); + + auto args = eastl::make_shared<ThreadArgs>(); + thread.Start( + [](eastl::shared_ptr<ThreadArgs> args) { + UNREFERENCED_PARAMETER(args); + + HANDLE bf4_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 (!bf4_pid) { + wait_timeout = (-1LL) * 10LL * 1000LL * 250LL; + bf4_pid = reinterpret_cast<HANDLE>(SearchBF4Process()); + if (bf4_pid == NULL) { + continue; + } + DbgPrint("pid: %p\n", bf4_pid); + + if (!NT_SUCCESS(::OpenProcess(bf4_pid, &pep, &obj))) { + bf4_pid = NULL; + continue; + } + + base = 0; + while (!base) { + 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 == L"bf4.exe") { + DbgPrint("%s\n", "found"); + base = mod.DllBase; + break; + } + } + + bf4_pid = reinterpret_cast<HANDLE>(SearchBF4Process()); + if (!bf4_pid) + break; + } + + wait_timeout = (-1LL) * 10LL * 1000LL * 50LL; + } + + Memory memory(pep); + // Offsets stolen from: https://github.com/ALEHACKsp/bf4-external-cheat/blob/master/Offsets.cs + auto client_game_context = memory.Read<uint64_t>(0x142670d80); + auto client_player_manager = memory.Read<uint64_t>(client_game_context + 0x60); + auto local_player = memory.Read<uint64_t>(client_player_manager + 0x540); + auto player_array = memory.Read<uint64_t>(client_player_manager + 0x548); + + if (!client_game_context) { + bf4_pid = NULL; + ::CloseProcess(&pep, &obj); + continue; + } + if (!client_player_manager || !local_player || !player_array) + continue; + + bool in_vehicle = false; + auto local_soldier = memory.Read<uint64_t>(local_player + 0x14B0 - sizeof(uint64_t)); + if (!local_soldier) + local_soldier = memory.Read<uint64_t>(local_player + 0x14D0); + else + in_vehicle = true; + if (!local_soldier) + continue; + + auto health_component = memory.Read<uint64_t>(local_soldier + 0x0140); + auto health = memory.Read<float>(health_component + 0x0020); + if (health <= 0.0f) + continue; + + if (in_vehicle) { + auto current_weapon_firing = memory.Read<uint64_t>(0x1423b2ec8); + if (!current_weapon_firing) + continue; + + auto primary_fire = memory.Read<uint64_t>(current_weapon_firing + 0x0128); + auto shot_config_data1 = memory.Read<uint64_t>(primary_fire + 0x0010); + + auto vehicle_bullets_per_shell = memory.Read<uint32_t>(shot_config_data1 + 0x0060 + 0x0078); + if (vehicle_bullets_per_shell != 2) + memory.Write<const uint32_t>(shot_config_data1 + 0x0060 + 0x0078, 2); + + auto vehicle_bullets_per_shot = memory.Read<uint32_t>(shot_config_data1 + 0x0060 + 0x007C); + if (vehicle_bullets_per_shot != 2) + memory.Write<const uint32_t>(shot_config_data1 + 0x0060 + 0x007C, 2); + + continue; + } + + auto soldier_weapon_component = memory.Read<uint64_t>(local_soldier + 0x0570); + auto weapon_handle = memory.Read<uint64_t>(soldier_weapon_component + 0x0890); + auto active_slot = memory.Read<uint32_t>(soldier_weapon_component + 0x0A98); + auto soldier_weapon = memory.Read<uint64_t>(weapon_handle + active_slot * 0x8); + auto corrected_firing = memory.Read<uint64_t>(soldier_weapon + 0x49C0); + auto sway = memory.Read<uint64_t>(corrected_firing + 0x0078); + auto sway_data = memory.Read<uint64_t>(sway + 0x0008); + + auto first_shot_recoil_multiplier = memory.Read<float>(sway_data + 0x444); + if (first_shot_recoil_multiplier != 0.0f) { + memory.Write<const float>(sway_data + 0x444, 0.0f); + memory.Write<const float>(sway_data + 0x440, 100.0f); + } + + auto deviation_scale_factor_zoom = memory.Read<float>(sway_data + 0x430); + if (deviation_scale_factor_zoom != 0.0f) { + memory.Write<const float>(sway_data + 0x430, 0.0f); + memory.Write<const float>(sway_data + 0x434, 0.0f); + memory.Write<const float>(sway_data + 0x438, 0.0f); + memory.Write<const float>(sway_data + 0x43C, 0.0f); + } + + auto breath_control_handler = memory.Read<uint64_t>(local_soldier + 0x0588); + if (breath_control_handler) + memory.Write<const float>(breath_control_handler + 0x0058, 0.0f); + + auto primary_fire = memory.Read<uint64_t>(corrected_firing + 0x0128); + auto firing_function_data = memory.Read<uint64_t>(primary_fire + 0x0010); + + auto bullets_per_shell = memory.Read<uint32_t>(firing_function_data + 0x0060 + 0x0078); + if (bullets_per_shell != 2) + memory.Write<const uint32_t>(firing_function_data + 0x0060 + 0x0078, 2); + + auto bullets_per_shot = memory.Read<uint32_t>(firing_function_data + 0x0060 + 0x007C); + if (bullets_per_shot != 2) + memory.Write<const uint32_t>(firing_function_data + 0x0060 + 0x007C, 2); + } + + if (bf4_pid) + ::CloseProcess(&pep, &obj); + return STATUS_SUCCESS; + }, + args); + + return STATUS_SUCCESS; +} + +VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) { + UNREFERENCED_PARAMETER(DriverObject); + + DbgPrint("%s\n", "Waiting for thread termination.."); + shutdown_event.Notify(); + thread.WaitForTermination(); +} +} |