/ examples / godmode / src / lib.rs
lib.rs
 1  #![allow(clippy::missing_safety_doc)]
 2  mod utils;
 3  
 4  use log::*;
 5  use safer_ffi::c_char;
 6  use std::{ffi::c_void, ptr::addr_of_mut};
 7  use utils::{hook_apply, hook_new, hook_revert, scan_memory};
 8  
 9  static mut PROC_DMG_STAM_PTR: *mut c_void = std::ptr::null_mut();
10  
11  // TODO: This godmode makes *everyone* godmode.
12  // Need to find a way to get the player's motile pointer.
13  
14  static mut FIRST_RUN: bool = true;
15  
16  static mut HOOK: Option<safer_ffi::boxed::Box<utils::Hook>> = None;
17  
18  #[no_mangle]
19  pub unsafe extern "C" fn enable() -> bool {
20  	if unsafe { FIRST_RUN } {
21  		pretty_env_logger::formatted_builder()
22  			.filter_level(log::LevelFilter::Trace)
23  			.init();
24  		unsafe { FIRST_RUN = false };
25  	}
26  
27  	let sig = "53 56 48 8D 64 24 D8 48 89 CB 40 30 F6 8B 05 ? ? ? ? 89";
28  	let ptr = scan_memory(sig.into());
29  	if ptr.is_null() {
30  		error!("Failed to find pointer for godmode hook");
31  		return false;
32  	}
33  
34  	println!("Found proc_dmg_and_stamina at: {:p}", ptr);
35  
36  	PROC_DMG_STAM_PTR = ptr;
37  
38  	HOOK = Some(hook_new(
39  		"godmode::proc_dmg_stamina".into(),
40  		addr_of_mut!(PROC_DMG_STAM_PTR),
41  		proc_dmg_stam as _,
42  	));
43  
44  	let success = hook_apply(HOOK.as_mut().unwrap());
45  
46  	info!("Hooked proc_dmg_and_stamina: {}", success);
47  
48  	success
49  }
50  
51  #[no_mangle]
52  pub unsafe extern "C" fn disable() -> bool {
53  	let success = hook_revert(HOOK.as_mut().unwrap());
54  
55  	info!("Unhooked proc_dmg_and_stamina: {}", success);
56  
57  	success
58  }
59  
60  #[no_mangle]
61  unsafe extern "C" fn proc_dmg_stam(motile_ptr: *mut c_void, _: f32, _: f32, _: c_char) -> c_char {
62  	println!("{:p}", motile_ptr);
63  
64  	let orig_proc: extern "C" fn(a: *mut c_void, b: f32) -> c_char =
65  		std::mem::transmute(PROC_DMG_STAM_PTR);
66  	orig_proc(motile_ptr, 0.0f32)
67  }