aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2024-03-10 00:13:52 +0100
committerToni Uhlig <matzeton@googlemail.com>2024-03-12 00:13:52 +0100
commit07ca2a71eda0a0a6ca4d17335033e4fcfdbd4d87 (patch)
treeff5806996d6b70d3942d681cc4d0f83774a302b7
parent5d697079989f35a437e5101418289b26e6c1f3a6 (diff)
Add Battlefield4 hack.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--Makefile18
-rw-r--r--README.md13
-rw-r--r--bf4.bat27
-rw-r--r--bf4.cpp189
4 files changed, 244 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 8be8128..6015ac9 100644
--- a/Makefile
+++ b/Makefile
@@ -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),$@)
diff --git a/README.md b/README.md
index b879a1e..94a437a 100644
--- a/README.md
+++ b/README.md
@@ -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!
diff --git a/bf4.bat b/bf4.bat
new file mode 100644
index 0000000..03bc112
--- /dev/null
+++ b/bf4.bat
@@ -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
diff --git a/bf4.cpp b/bf4.cpp
new file mode 100644
index 0000000..0527a79
--- /dev/null
+++ b/bf4.cpp
@@ -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();
+}
+}