subsecond_types/lib.rs
1use serde::{Deserialize, Serialize};
2use std::{
3 collections::HashMap,
4 hash::{BuildHasherDefault, Hasher},
5 path::PathBuf,
6};
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
9pub struct JumpTable {
10 /// The dylib containing the patch. This should be a valid path so you can just pass it to LibLoading
11 ///
12 /// On wasm you will need to fetch() this file and then pass it to the WebAssembly.instantiate() function
13 pub lib: PathBuf,
14
15 /// old -> new
16 /// does not take into account the base address of the patch when loaded into memory - need dlopen for that
17 ///
18 /// These are intended to be `*const ()` pointers but need to be `u64` for the hashmap. On 32-bit platforms
19 /// you will need to cast to `usize` before using them.
20 pub map: AddressMap,
21
22 /// the address of the base address of the old original binary
23 ///
24 /// machos: this is the address of the `_mh_execute_header` symbol usually at 0x100000000 and loaded near 0x100000000
25 /// linux: this is the address of the `__executable_start` symbol usually at 0x0 but loaded around 0x555555550000
26 /// windows: this is the address of the `ImageBase` field of the PE header
27 /// wasm: not useful since there's no ASLR
28 ///
29 /// While we can generally guess that these values are, it's possible they are different and thus reading
30 /// them dynamically is worthwhile.
31 pub aslr_reference: u64,
32
33 /// the address of the base address of the new binary
34 ///
35 /// machos: this is the address of the `_mh_execute_header` symbol usually at 0x100000000 and loaded near 0x100000000
36 /// linux: this is the address of the `__executable_start` symbol usually at 0x0 but loaded around 0x555555550000
37 /// windows: this is the address of the `ImageBase` field of the PE header
38 /// wasm: not useful since there's no ASLR
39 ///
40 /// While we can generally guess that these values are, it's possible they are different and thus reading
41 /// them dynamically is worthwhile.
42 pub new_base_address: u64,
43
44 /// The amount of ifuncs this will register. This is used by WASM to know how much space to allocate
45 /// for the ifuncs in the ifunc table
46 pub ifunc_count: u64,
47}
48
49/// An address to address hashmap that does not hash addresses since addresses are by definition unique.
50pub type AddressMap = HashMap<u64, u64, BuildAddressHasher>;
51pub type BuildAddressHasher = BuildHasherDefault<AddressHasher>;
52
53#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
54pub struct AddressHasher(u64);
55impl Hasher for AddressHasher {
56 fn write(&mut self, _: &[u8]) {
57 panic!("Invalid use of NoHashHasher")
58 }
59 fn write_u8(&mut self, n: u8) {
60 self.0 = u64::from(n)
61 }
62 fn write_u16(&mut self, n: u16) {
63 self.0 = u64::from(n)
64 }
65 fn write_u32(&mut self, n: u32) {
66 self.0 = u64::from(n)
67 }
68 fn write_u64(&mut self, n: u64) {
69 self.0 = n
70 }
71 fn write_usize(&mut self, n: usize) {
72 self.0 = n as u64
73 }
74 fn write_i8(&mut self, n: i8) {
75 self.0 = n as u64
76 }
77 fn write_i16(&mut self, n: i16) {
78 self.0 = n as u64
79 }
80 fn write_i32(&mut self, n: i32) {
81 self.0 = n as u64
82 }
83 fn write_i64(&mut self, n: i64) {
84 self.0 = n as u64
85 }
86 fn write_isize(&mut self, n: isize) {
87 self.0 = n as u64
88 }
89 fn finish(&self) -> u64 {
90 self.0
91 }
92}