-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathlib.rs
153 lines (134 loc) · 4.08 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#![feature(let_chains)]
mod hooks;
mod ue;
use std::{io::BufReader, path::Path};
use anyhow::{Context, Result};
use hooks::{FnLoadGameFromMemory, FnSaveGameToMemory};
use mint_lib::mod_info::Meta;
use windows::Win32::{
Foundation::HMODULE,
System::{
SystemServices::*,
Threading::{GetCurrentThread, QueueUserAPC},
},
};
// x3daudio1_7.dll
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
extern "system" fn X3DAudioCalculate() {}
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
extern "system" fn X3DAudioInitialize() {}
// d3d9.dll
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
extern "system" fn D3DPERF_EndEvent() {}
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
extern "system" fn D3DPERF_BeginEvent() {}
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
extern "system" fn DllMain(dll_module: HMODULE, call_reason: u32, _: *mut ()) -> bool {
unsafe {
match call_reason {
DLL_PROCESS_ATTACH => {
QueueUserAPC(Some(init), GetCurrentThread(), 0);
}
DLL_PROCESS_DETACH => (),
_ => (),
}
true
}
}
unsafe extern "system" fn init(_: usize) {
patch().ok();
}
static mut GLOBALS: Option<Globals> = None;
pub struct Globals {
resolution: hook_resolvers::HookResolution,
meta: Meta,
}
impl Globals {
pub fn gmalloc(&self) -> &ue::FMalloc {
unsafe {
&**(self.resolution.core.as_ref().unwrap().gmalloc.0 as *const *const ue::FMalloc)
}
}
pub fn fframe_step(&self) -> ue::FnFFrameStep {
unsafe { std::mem::transmute(self.resolution.core.as_ref().unwrap().fframe_step.0) }
}
pub fn fframe_step_explicit_property(&self) -> ue::FnFFrameStepExplicitProperty {
unsafe {
std::mem::transmute(
self.resolution
.core
.as_ref()
.unwrap()
.fframe_step_explicit_property
.0,
)
}
}
pub fn fname_to_string(&self) -> ue::FnFNameToString {
unsafe { std::mem::transmute(self.resolution.core.as_ref().unwrap().fnametostring.0) }
}
pub fn uobject_base_utility_get_path_name(&self) -> ue::FnUObjectBaseUtilityGetPathName {
unsafe {
std::mem::transmute(
self.resolution
.core
.as_ref()
.unwrap()
.uobject_base_utility_get_path_name
.0,
)
}
}
pub fn save_game_to_memory(&self) -> FnSaveGameToMemory {
unsafe {
std::mem::transmute(
self.resolution
.save_game
.as_ref()
.unwrap()
.save_game_to_memory
.0,
)
}
}
pub fn load_game_from_memory(&self) -> FnLoadGameFromMemory {
unsafe {
std::mem::transmute(
self.resolution
.save_game
.as_ref()
.unwrap()
.load_game_from_memory
.0,
)
}
}
}
pub fn globals() -> &'static Globals {
unsafe { GLOBALS.as_ref().unwrap() }
}
unsafe fn patch() -> Result<()> {
let pak_path = std::env::current_exe()
.ok()
.as_deref()
.and_then(Path::parent)
.and_then(Path::parent)
.and_then(Path::parent)
.map(|p| p.join("Content/Paks/mods_P.pak"))
.context("could not determine pak path")?;
let mut pak_reader = BufReader::new(std::fs::File::open(pak_path)?);
let pak = repak::PakBuilder::new().reader(&mut pak_reader)?;
let meta_buf = pak.get("meta", &mut pak_reader)?;
let meta: Meta = postcard::from_bytes(&meta_buf)?;
let image = patternsleuth::process::internal::read_image()?;
let resolution = image.resolve(hook_resolvers::HookResolution::resolver())?;
println!("{:#x?}", resolution);
GLOBALS = Some(Globals { resolution, meta });
hooks::initialize()?;
Ok(())
}