Skip to content

Commit

Permalink
WIP randomized base address
Browse files Browse the repository at this point in the history
  • Loading branch information
Kethen committed Sep 28, 2024
1 parent b73bf88 commit 90a1aee
Showing 1 changed file with 38 additions and 19 deletions.
57 changes: 38 additions & 19 deletions s4_league_fps_unlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include <libloaderapi.h>

#define SUSPEND_BEFORE_HOOKING 1
#define ENABLE_LOGGING 0
#define ENABLE_LOGGING 1
#define SIMPLIFIED_SLEEP 0

// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FThread%2FNtDelayExecution.html
Expand Down Expand Up @@ -120,6 +120,11 @@ pthread_mutex_unlock(&_mem_fence);
patch_memory((uint8_t *)(l), (uint8_t *)&_val, 4); \
}

static int64_t hook_address_offset;
static void set_hook_address_offset(int64_t address_offset){
hook_address_offset = address_offset;
}

static pthread_mutex_t config_mutex;
struct config{
int max_framerate;
Expand Down Expand Up @@ -329,7 +334,7 @@ void __attribute__((thiscall)) patched_calculate_weapon_spread(struct ctx_calcul
return;
}

static void hook_calculate_weapon_spread(uint32_t address_offset){
static void hook_calculate_weapon_spread(int64_t address_offset){
LOG("hooking calculate_weapon_spread");

uint8_t intended_trampoline[] = {
Expand Down Expand Up @@ -383,7 +388,7 @@ void __attribute__((thiscall)) patched_fun_00780b20(struct ctx_fun_00780b20 *ctx
ctx->target_fov = orig_fov;
}

static void hook_fun_00780b20(uint32_t address_offset){
static void hook_fun_00780b20(int64_t address_offset){
LOG("hooking fun_00780b20");

uint8_t intended_trampoline[] = {
Expand Down Expand Up @@ -423,14 +428,14 @@ struct ctx_fun_005efcb0{
static void (__attribute__((thiscall)) *orig_fun_005efcb0)(void *, uint32_t);
void __attribute__((thiscall)) patched_fun_005efcb0(struct ctx_fun_005efcb0 *ctx, uint32_t param_1){
orig_fun_005efcb0(ctx, param_1);
if((void *)0x0052438c == __builtin_return_address(1)){
if((void *)(0x0052438c + hook_address_offset) == __builtin_return_address(1)){
set_drop_val = ctx->set_drop_val;
LOG_VERBOSE("%s: updating player set_drop_val to %f", __FUNCTION__, set_drop_val);
}
LOG_VERBOSE("%s: ctx 0x%08x, param_1 %u, set_drop_val %f, 0x%08x -> 0x%08x -> 0x%08x", __FUNCTION__, ctx, param_1, ctx->set_drop_val, __builtin_return_address(2), __builtin_return_address(1), __builtin_return_address(0));
}

static void hook_fun_005efcb0(uint32_t address_offset){
static void hook_fun_005efcb0(int64_t address_offset){
LOG("hooking fun_005efcb0");

uint8_t intended_trampoline[] = {
Expand Down Expand Up @@ -522,7 +527,7 @@ static void (__attribute__((thiscall)) *orig_move_actor_by)(void*, float, float,
void __attribute__((thiscall)) patched_move_actor_by(struct move_actor_by_ctx *ctx, float param_1, float param_2, float param_3){
const double orig_fixed_frametime = 1.66666666666666678509045596002E1;

void *ret_addr = __builtin_return_address(0);
void *ret_addr = (void *)((uint32_t)__builtin_return_address(0) + hook_address_offset);

struct ctx_01b29540* actx = fetch_ctx_01b29540();

Expand Down Expand Up @@ -619,7 +624,7 @@ void __attribute__((thiscall)) patched_move_actor_by(struct move_actor_by_ctx *c
orig_move_actor_by(ctx, param_1, y, param_3);
}

static void hook_move_actor_by(uint32_t address_offset){
static void hook_move_actor_by(int64_t address_offset){
LOG("hooking move_actor_by");

uint8_t intended_trampoline[] = {
Expand Down Expand Up @@ -722,7 +727,7 @@ static void hook_move_actor_exact(){

// 9 direct usages of 0x015f4210
float speed_dampeners[9];
static void redirect_speed_dampeners(uint32_t address_offset){
static void redirect_speed_dampeners(int64_t address_offset){
LOG("%s: redirecting speed dampeners to 0x%08x to 0x%08x", __FUNCTION__, &speed_dampeners[0], &speed_dampeners[8]);

for(int i = 0;i < sizeof(speed_dampeners) / sizeof(float); i++){
Expand All @@ -742,9 +747,10 @@ static void redirect_speed_dampeners(uint32_t address_offset){
}

// function at 00871970, not essentially game tick
static void (__attribute__((thiscall)) *orig_game_tick)(void *);
void __attribute__((thiscall)) patched_game_tick(void *tick_ctx){
LOG_VERBOSE("game tick function hook fired");
// the signature and convention is different in s10 it would seem
static void (__attribute__((fastcall)) *orig_game_tick)(void *tick_ctx);
void __attribute__((fastcall)) patched_game_tick(void *tick_ctx){
LOG("game tick function hook fired");


const static float orig_speed_dampener = 0.015;
Expand All @@ -753,7 +759,7 @@ void __attribute__((thiscall)) patched_game_tick(void *tick_ctx){
static struct time_context tctx;

struct game_context *ctx = fetch_game_context();
LOG_VERBOSE("game context at 0x%08x", (uint32_t)ctx);
LOG("game context at 0x%08x", (uint32_t)ctx);

bool should_limit = ctx->fps_limiter_toggle != 0;

Expand Down Expand Up @@ -814,10 +820,12 @@ void __attribute__((thiscall)) patched_game_tick(void *tick_ctx){

uint8_t fps_limiter_toggle_orig = ctx->fps_limiter_toggle;
ctx->fps_limiter_toggle = 0;
LOG("running original game tick");
orig_game_tick(tick_ctx);
ctx->fps_limiter_toggle = fps_limiter_toggle_orig;

update_time_delta(&tctx);
LOG("tctx.delta_t: %f", tctx.delta_t);

frametime = tctx.delta_t;
uint32_t frametime_uint = frametime;
Expand All @@ -830,9 +838,9 @@ void __attribute__((thiscall)) patched_game_tick(void *tick_ctx){
// some kind of overall speed dampener
speed_dampeners[8] = new_speed_dampener;

LOG_VERBOSE("delta_t: %f, speed_dampener: %f", tctx.delta_t, *speed_dampener);
LOG("frametime: %f, speed_dampener: %f", frametime, new_speed_dampener);
}
static void hook_game_tick(uint32_t address_offset){
static void hook_game_tick(int64_t address_offset){
LOG("hooking game tick");
uint8_t intended_trampoline[] = {
// original 9 bytes
Expand All @@ -844,8 +852,14 @@ static void hook_game_tick(uint32_t address_offset){
};
*(uint32_t *)&intended_trampoline[10] = 0x0089f409 + address_offset;
memcpy(intended_trampoline, (void *)(0x0089f400 + address_offset), 9);
char log_buf[256];
int offset = 0;
for(int i = 0;i < sizeof(intended_trampoline); i++){
offset = offset + sprintf(&log_buf[offset], "%02x ", intended_trampoline[i]);
}
LOG("%s", log_buf);
DWORD old_protect;
orig_game_tick = (void (__attribute__((thiscall)) *)(void *)) VirtualAlloc(NULL, sizeof(intended_trampoline), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
orig_game_tick = (void (__attribute__((fastcall)) *)(void *)) VirtualAlloc(NULL, sizeof(intended_trampoline), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

memcpy((void *)orig_game_tick, intended_trampoline, sizeof(intended_trampoline));
VirtualProtect((void *)orig_game_tick, sizeof(intended_trampoline), PAGE_EXECUTE_READ, &old_protect);
Expand All @@ -870,7 +884,7 @@ static void patch_min_frametime(double min_frametime){
*min_frametime_const = min_frametime;
}

static void experinmental_static_patches(uint32_t address_offset){
static void experinmental_static_patches(int64_t address_offset){
LOG("applying experimental patches");
}

Expand Down Expand Up @@ -937,10 +951,15 @@ static void *delayed_init_thread(void *arg){
exit(1);
}
uint32_t game_base_address = (uint32_t)module_info.lpBaseOfDll;
CloseHandle(s4client_module);
// this actually does not need closing, grabbing this does not increment ref count
// closing it also does not cause a handle exception on wine :)
//CloseHandle(s4client_module);
CloseHandle(current_process);
LOG("game base address is 0x%08x", game_base_address);
uint32_t address_offset = game_base_address - 0x00400000;
int64_t address_offset = game_base_address - 0x00400000;
LOG("address offset is %s0x%08x", address_offset >= 0? "+": "-", address_offset >= 0? address_offset: address_offset * -1);

set_hook_address_offset(address_offset);

#if SUSPEND_BEFORE_HOOKING
// https://learn.microsoft.com/en-us/windows/win32/toolhelp/traversing-the-thread-list
Expand Down Expand Up @@ -991,7 +1010,7 @@ static void *delayed_init_thread(void *arg){

#if SUSPEND_BEFORE_HOOKING
if(threads_snap != INVALID_HANDLE_VALUE){
LOG("resuming thrads after hooking")
LOG("resuming threads after hooking")
if(Thread32First(threads_snap, &te32)){
do{
if(te32.th32OwnerProcessID == this_process && te32.th32ThreadID != this_thread){
Expand Down

0 comments on commit 90a1aee

Please sign in to comment.