diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2025-08-15 11:18:43 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2025-08-15 11:18:43 +0200 |
commit | 22716e0684b896647beaccdfb8bc44e3b20e9300 (patch) | |
tree | 5e3b04d5cdca9a3b92638f6b559fcc69ccb26588 | |
parent | 3227fb90bd9414d81aa4941f179f45bd8dd28ddd (diff) |
fixed bf4 bugcheckmain
* added hunt2 spectator count check and chams color change
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | bf4.cpp | 271 | ||||
-rw-r--r-- | hunt2.cpp | 30 |
2 files changed, 172 insertions, 129 deletions
@@ -1,6 +1,7 @@ #include <ntddk.h> #include <DriverThread.hpp> +#include <except.h> #include <obfuscate.hpp> #include "memory.hpp" @@ -13,12 +14,12 @@ static auto targetProcess = skCrypt(L"bf4.exe"); static uint64_t SearchBF4Process(void) { const auto &procs = ::GetProcesses(); - const auto &found = eastl::find_if(procs.begin(), procs.end(), - [](const auto &item) { - if (item.ProcessName == targetProcess) - return true; - return false; - }); + const auto &found = + eastl::find_if(procs.begin(), procs.end(), [](const auto &item) { + if (item.ProcessName == targetProcess) + return true; + return false; + }); if (found == procs.end()) { return 0; @@ -31,6 +32,16 @@ extern "C" { DRIVER_INITIALIZE DriverEntry; DRIVER_UNLOAD DriverUnload; +int mainloop_exception_handler(_In_ EXCEPTION_POINTERS *lpEP) { + (void)lpEP; + return EXCEPTION_EXECUTE_HANDLER; +} + +int unload_exception_handler(_In_ EXCEPTION_POINTERS *lpEP) { + (void)lpEP; + return EXCEPTION_EXECUTE_HANDLER; +} + NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(DriverObject); @@ -48,128 +59,161 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, 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); + __dpptry(mainloop_exception_handler, mainloop_seh) { + 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; - } + 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 == targetProcess) { - DbgPrint("%s\n", "found"); - base = mod.DllBase; - break; + 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 == targetProcess) { + DbgPrint("%s\n", "found"); + base = mod.DllBase; + break; + } } + + bf4_pid = reinterpret_cast<HANDLE>(SearchBF4Process()); + if (!bf4_pid) + break; } - bf4_pid = reinterpret_cast<HANDLE>(SearchBF4Process()); - if (!bf4_pid) - break; + wait_timeout = (-1LL) * 10LL * 1000LL * 50LL; } - 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) + 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; - auto primary_fire = memory.Read<uint64_t>(current_weapon_firing + 0x0128); - auto shot_config_data1 = memory.Read<uint64_t>(primary_fire + 0x0010); + 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 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 health_component = + memory.Read<uint64_t>(local_soldier + 0x0140); + auto health = memory.Read<float>(health_component + 0x0020); + if (health <= 0.0f) + continue; - 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); + if (in_vehicle) { + auto current_weapon_firing = memory.Read<uint64_t>(0x1423b2ec8); + if (!current_weapon_firing) + continue; - continue; - } + auto primary_fire = + memory.Read<uint64_t>(current_weapon_firing + 0x0128); + auto shot_config_data1 = + memory.Read<uint64_t>(primary_fire + 0x0010); - 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 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 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 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); - 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); + continue; + } - auto primary_fire = memory.Read<uint64_t>(corrected_firing + 0x0128); - auto firing_function_data = memory.Read<uint64_t>(primary_fire + 0x0010); + 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 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 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 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); + 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); } + __dppexcept(mainloop_seh) { return STATUS_UNSUCCESSFUL; } + __dpptryend(mainloop_seh); return STATUS_SUCCESS; }, @@ -182,7 +226,12 @@ VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DbgPrint("%s\n", "Waiting for thread termination.."); - shutdown_event.Notify(); - thread.WaitForTermination(); + __dpptry(unload_exception_handler, unload_seh) { + shutdown_event.Notify(); + while (thread.WaitForTermination() != STATUS_UNSUCCESSFUL) { + } + } + __dppexcept(unload_seh) {} + __dpptryend(unload_seh); } } @@ -20,17 +20,6 @@ static Event shutdown_event; static auto targetProcess = skCrypt(L"HuntGame.exe"); static auto targetModule = skCrypt(L"GameHunt.dll"); -enum ColorType : uint32_t { - Pink = 0xFFA0FF40, - Red = 0xFF000080, - Green = 0x00FF00FF, - Blue = 0x0000FF60, - Cyan = 0x00FFFFFF, - Orange = 0xFFA500FF, - Yellow = 0xFFFF0060, - White = 0xFFFFFFFF -}; - static uint64_t SearchHuntProcess(void) { const auto &procs = ::GetProcesses(); const auto &found = @@ -86,12 +75,6 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, __dpptry(mainloop_exception_handler, mainloop_seh) { while (shutdown_event.Wait(wait_timeout) == STATUS_TIMEOUT) { if (!hunt_pid) { -#ifdef HUNT2_DEBUG - cur_iter = 0; - objects_found.clear(); - render_nodes_found.clear(); -#endif - wait_timeout = (-1LL) * 10LL * 1000LL * 1000LL; hunt_pid = reinterpret_cast<HANDLE>(SearchHuntProcess()); if (hunt_pid == NULL) { @@ -99,6 +82,12 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, } DbgPrint(skCrypt("pid: %p\n"), hunt_pid); +#ifdef HUNT2_DEBUG + cur_iter = 0; + objects_found.clear(); + render_nodes_found.clear(); +#endif + if (!NT_SUCCESS(::OpenProcess(hunt_pid, &pep, &obj))) { hunt_pid = NULL; continue; @@ -175,13 +164,18 @@ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, if (STRNCMP_CR(entity_name, "ShootingRange_Target") == 0 || STRNCMP_CR(entity_name, "HunterBasic") == 0 || STRNCMP_CR(entity_name, "Hunter") == 0) { + uint64_t color = 0x0004ffaf; + auto spectators = memory.ReadChain<int32_t>(entity, { 0x198, 0x20, 0xD0, 0xE8, 0x330 }); + if (spectators > 0) + color = 0x6824ffaf; + auto slots_ptr = memory.Read<uint64_t>(entity + 0xA8); auto slot_ptr = memory.Read<uint64_t>(slots_ptr + 0); auto render_node_ptr = memory.Read<uint64_t>(slot_ptr + 0xA0); memory.Write<uint32_t>(render_node_ptr + 0x10, 0x80018); memory.Write<float>(render_node_ptr + 0x2c, 10000.f); - memory.Write<uint64_t>(render_node_ptr + 0x130, 0x0004ffaf); + memory.Write<decltype(color)>(render_node_ptr + 0x130, color); #ifdef HUNT2_DEBUG render_nodes_found[render_node_ptr]++; #endif |