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
use crate::alloc::string::String;
use nnsdk::root::nn;
use std::fmt;
#[macro_export] macro_rules! install_hooks {
(
$(
$hook_paths:path
),*
$(,)?
) => {
$(
$crate::install_hook!(
$hook_paths
);
)*
};
}
#[repr(u8)]
pub enum Region {
Text,
Rodata,
Data,
Bss,
Heap
}
#[repr(C)]
pub struct InlineCtx {
pub registers: [nn::os::CpuRegister; 29],
}
impl fmt::Display for InlineCtx {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, reg) in self.registers.iter().enumerate() {
unsafe { write!(f, "X[{}]: {:#08x?}\n", i, reg.x.as_ref())?; }
}
Ok(())
}
}
extern "C" {
pub fn A64HookFunction(symbol: *const libc::c_void, replace: *const libc::c_void, result: *mut *mut libc::c_void);
pub fn A64InlineHook(symbol: *const libc::c_void, replace: *const libc::c_void);
pub fn getRegionAddress(region: Region) -> *mut libc::c_void;
}
pub struct HookInfo {
pub fn_name: &'static str,
pub name: Option<String>,
pub offset: Option<u64>,
pub symbol: Option<String>,
pub inline: bool
}
pub struct Hook {
pub ptr: *const (),
pub info: &'static HookInfo,
}
unsafe impl Sync for Hook {
}
impl Hook {
pub fn install(&self) {
todo!()
}
}
#[allow(improper_ctypes)]
extern "C" {
static __hook_array_start: Hook;
static __hook_array_end: Hook;
}
pub fn iter_hooks() -> impl Iterator<Item = &'static Hook> {
let hook_start = unsafe {&__hook_array_start as *const Hook};
let hook_end = unsafe {&__hook_array_end as *const Hook};
let hook_count = ((hook_start as usize) - (hook_end as usize)) / core::mem::size_of::<Hook>();
crate::println!("hook_count: {}", hook_count);
crate::println!("hook_start: {:?}", hook_start);
crate::println!("hook_end: {:?}", hook_start);
unsafe {
core::slice::from_raw_parts(
hook_start,
hook_count
)
}.iter()
}