Skip to content

Commit

Permalink
WIP tracy
Browse files Browse the repository at this point in the history
  • Loading branch information
trumank committed Jun 9, 2024
1 parent 4f455a9 commit 2f95e86
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 16 deletions.
57 changes: 57 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions hook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ bitflags = "2.4.1"
widestring = "1.0.2"
tokio = { workspace = true, features = ["full"] }
tracing-appender = "0.2.3"
seq-macro = "0.3.5"
tracing-subscriber = "0.3.18"
tracing-tracy = { git = "https://github.com/trumank/rust_tracy_client.git", branch = "static-linking" }
104 changes: 96 additions & 8 deletions hook/src/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod server_list;

use std::{
collections::HashMap,
ffi::c_void,
path::{Path, PathBuf},
ptr::NonNull,
Expand All @@ -17,7 +18,7 @@ use windows::Win32::System::Memory::{VirtualProtect, PAGE_EXECUTE_READWRITE};

use crate::{
globals,
ue::{self, FLinearColor, UObject},
ue::{self, kismet::FFrame, FLinearColor, UFunction, UObject},
LOG_GUARD,
};

Expand All @@ -28,6 +29,8 @@ retour::static_detour! {
static DoesSaveGameExist: unsafe extern "system" fn(*const ue::FString, i32) -> bool;
static UObjectTemperatureComponentTimerCallback: unsafe extern "system" fn(*mut c_void);
static WinMain: unsafe extern "system" fn(*mut (), *mut (), *mut (), i32, *const ()) -> i32;
static FEngineLoopTick: unsafe extern "system" fn(*mut ());
static UGameEngineTick: unsafe extern "system" fn(*mut (), f32, bool);

}

Expand Down Expand Up @@ -63,6 +66,20 @@ pub unsafe fn initialize() -> Result<()> {
)?;
WinMain.enable()?;

if let Ok(debug) = &globals().resolution.debug {
FEngineLoopTick.initialize(
std::mem::transmute(debug.fengine_loop_tick.0),
detour_fengine_loop_tick,
)?;
FEngineLoopTick.enable()?;

UGameEngineTick.initialize(
std::mem::transmute(debug.ugame_engine_tick.0),
detour_ugame_engine_tick,
)?;
UGameEngineTick.enable()?;
}

HookUFunctionBind.initialize(
std::mem::transmute(globals().resolution.core.as_ref().unwrap().ufunction_bind.0),
move |function| {
Expand Down Expand Up @@ -281,27 +298,98 @@ fn does_save_game_exist_detour(slot_name: *const ue::FString, user_index: i32) -
}
}

struct NativesArray([Option<ExecFn>; 0x100]);

static mut GNATIVES_OLD: NativesArray = NativesArray([None; 0x100]);
static mut NAME_CACHE: Option<HashMap<usize, String>> = None;

unsafe fn debug(expr: usize, ctx: *mut UObject, frame: *mut FFrame, ret: *mut c_void) {
if NAME_CACHE.is_none() {
NAME_CACHE = Some(Default::default());
}

let (index, path) = {
let stack = &*frame;
let func = &*(stack.node as *const UFunction);

let index = 0;
//TODO causes issues for some reason
//let index = (stack.code as isize)
// .wrapping_sub(func.ustruct.script.as_ptr() as isize);

let path = NAME_CACHE
.as_mut()
.unwrap_unchecked()
.entry(stack.node as usize)
.or_insert_with(|| {
func.ustruct
.ufield
.uobject
.uobject_base_utility
.uobject_base
.get_path_name(None)
});
(index, path)
};

tracing::info_span!("kismet", path, index).in_scope(|| {
((GNATIVES_OLD.0)[expr].unwrap())(ctx, frame, ret);
});
}

unsafe extern "system" fn hook_exec<const N: usize>(
ctx: *mut UObject,
frame: *mut FFrame,
ret: *mut c_void,
) {
debug(N, ctx, frame, ret);
}

unsafe fn hook_gnatives(gnatives: &mut NativesArray) {
seq_macro::seq!(N in 0..256 {
(GNATIVES_OLD.0)[N] = gnatives.0[N];
gnatives.0[N] = Some(hook_exec::<N>);
});
}

fn detour_fengine_loop_tick(this: *mut ()) {
tracing::warn_span!("FEngineLoop::Tick").in_scope(|| unsafe {
FEngineLoopTick.call(this);
});
}

fn detour_ugame_engine_tick(this: *mut (), delta_seconds: f32, b_idle_mode: bool) {
tracing::warn_span!("UGameEngine::Tick").in_scope(|| unsafe {
UGameEngineTick.call(this, delta_seconds, b_idle_mode);
});
}

fn detour_main(
h_instance: *mut (),
h_prev_instance: *mut (),
lp_cmd_line: *mut (),
n_cmd_show: i32,
cmd_line: *const (),
) -> i32 {
let ret = unsafe {
WinMain.call(
unsafe {
if let Ok(debug) = &globals().resolution.debug {
tracing::info!("hooking GNatives");
hook_gnatives((debug.gnatives.0 as *mut NativesArray).as_mut().unwrap());
}

let ret = WinMain.call(
h_instance,
h_prev_instance,
lp_cmd_line,
n_cmd_show,
cmd_line,
)
};
);

// about to exit, drop log guard
drop(unsafe { LOG_GUARD.take() });
// about to exit, drop log guard
drop(LOG_GUARD.take());

ret
ret
}
}

unsafe extern "system" fn exec_get_mod_json(
Expand Down
18 changes: 12 additions & 6 deletions hook/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,17 @@ unsafe fn patch() -> Result<()> {
let exe_path = std::env::current_exe().ok();
let bin_dir = exe_path.as_deref().and_then(Path::parent);

let guard = bin_dir
.and_then(|bin_dir| mint_lib::setup_logging(bin_dir.join("mint_hook.log"), "hook").ok());
if guard.is_none() {
warn!("failed to set up logging");
}
//let guard = bin_dir
// .and_then(|bin_dir| mint_lib::setup_logging(bin_dir.join("mint_hook.log"), "hook").ok());
//if guard.is_none() {
// warn!("failed to set up logging");
//}
use tracing_subscriber::layer::SubscriberExt;

tracing::subscriber::set_global_default(
tracing_subscriber::registry().with(tracing_tracy::TracyLayer::default()),
)
.expect("setup tracy layer");

let pak_path = bin_dir
.and_then(Path::parent)
Expand All @@ -156,7 +162,7 @@ unsafe fn patch() -> Result<()> {
info!("PS scan: {:#x?}", resolution);

GLOBALS = Some(Globals { resolution, meta });
LOG_GUARD = guard;
//LOG_GUARD = guard;

hooks::initialize()?;

Expand Down
15 changes: 13 additions & 2 deletions hook_resolvers/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use patternsleuth::resolvers::futures::future::join_all;
use patternsleuth::resolvers::unreal::blueprint_library::UFunctionBind;
use patternsleuth::resolvers::unreal::fname::{FNameCtorWchar, FNameToString};
use patternsleuth::resolvers::unreal::game_loop::Main;
use patternsleuth::resolvers::unreal::game_loop::{FEngineLoopTick, Main, UGameEngineTick};
use patternsleuth::resolvers::unreal::gmalloc::GMalloc;
use patternsleuth::resolvers::unreal::kismet::{FFrameStep, FFrameStepExplicitProperty};
use patternsleuth::resolvers::unreal::kismet::{FFrameStep, FFrameStepExplicitProperty, GNatives};
use patternsleuth::resolvers::unreal::save_game::{
UGameplayStaticsDoesSaveGameExist, UGameplayStaticsLoadGameFromMemory,
UGameplayStaticsLoadGameFromSlot, UGameplayStaticsSaveGameToMemory,
Expand Down Expand Up @@ -183,6 +183,16 @@ impl_try_collector! {
}
}

impl_try_collector! {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde-resolvers", derive(Serialize, Deserialize))]
pub struct DebugResolution {
pub gnatives: GNatives,
pub ugame_engine_tick: UGameEngineTick,
pub fengine_loop_tick: FEngineLoopTick,
}
}

impl_collector! {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde-resolvers", derive(Serialize, Deserialize))]
Expand All @@ -193,5 +203,6 @@ impl_collector! {
pub save_game: SaveGameResolution,
pub gas_fix: GasFixResolution,
pub core: CoreResolution,
pub debug: DebugResolution,
}
}

0 comments on commit 2f95e86

Please sign in to comment.