pub struct Hook<'a, T> {
pub item: &'a mut T,
/* private fields */
}
Fields§
§item: &'a mut T
Implementations§
Source§impl<'a, T> Hook<'a, T>
impl<'a, T> Hook<'a, T>
Sourcepub unsafe fn new(
item: &'a mut T,
vtable_offset: Option<usize>,
methods_count: Option<usize>,
) -> Self
pub unsafe fn new( item: &'a mut T, vtable_offset: Option<usize>, methods_count: Option<usize>, ) -> Self
Examples found in repository?
examples/copy.rs (line 54)
35fn main() {
36 unsafe {
37 /* The same classes, but one is our victim, and the other is unaffected. */
38 let mut victim_cpp_class = CppClass::default();
39 let unaffected_cpp_class = CppClass::default();
40
41 /* If you can, use Hook over RawHook. It uses Rust's lifetime system
42 * to force victim_cpp_class to stay valid while hook is set because
43 * you can't drop victim_cpp_class while its being borrowed inside
44 * copy::Hook */
45 {
46 /* Setting up hook */
47 /* To get VTable size you can use multiple methods:
48 * Calculate it on runtime by passing None as methods_count arg inside Hook::new() (very unsafe!)
49 * If your VTable struct implementation is 100% valid, you can use
50 * std::mem::size_of::<VTableStruct>() / std::mem::size_of::<usize>() to get
51 * methods count at compile time, or just specify it manually: Some(2) */
52 let vtable_size = std::mem::size_of::<CppClassVTable>() / std::mem::size_of::<usize>();
53 let mut hook =
54 vtable_hook::hook::copy::Hook::new(&mut victim_cpp_class, None, Some(vtable_size));
55 eprintln!("Hook: {hook:#?}");
56 /* Since we are mutually borrowing victim_cpp_class in hook we can't use it directly
57 * but we can use hook's reference instead:
58 * &hook.item */
59
60 /* Hooks are unset now, let's test that its true */
61 eprintln!("-- Hook is disabled -- ");
62 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
63 {
64 let victim_cpp_class = &hook.item;
65 eprintln!(
66 "victim_cpp_class bar() result = {}",
67 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
68 );
69 }
70 eprintln!(
71 "unaffected_cpp_class bar() result = {}",
72 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
73 );
74 /* victim_cpp_class's hook is_enabled false
75 * victim_cpp_class bar() result = 0
76 * unaffected_cpp_class bar() result = 0 */
77
78 /* Replacing bar inside raw_hook */
79 hook.replace_method(1, bar_hooked as _);
80 /* Replacing victim_cpp_class's VTable */
81 hook.enable();
82 /* Testing */
83 eprintln!("-- Hook is enabled -- ");
84 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
85 {
86 let victim_cpp_class = &hook.item;
87 eprintln!(
88 "victim_cpp_class bar() result = {}",
89 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
90 );
91 }
92 eprintln!(
93 "unaffected_cpp_class bar() result = {}",
94 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
95 );
96 /* victim_cpp_class's hook is_enabled true
97 * victim_cpp_class bar() result = 1
98 * unaffected_cpp_class bar() result = 0 */
99
100 /* hook will disable itself on drop() */
101 }
102 eprintln!("-- Hook is disabled (drop) -- ");
103 eprintln!(
104 "victim_cpp_class bar() result = {}",
105 (victim_cpp_class.vtable.read().bar)(&victim_cpp_class)
106 );
107 eprintln!(
108 "unaffected_cpp_class bar() result = {}",
109 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
110 );
111 /* victim_cpp_class bar() result = 0
112 * unaffected_cpp_class bar() result = 0 */
113 }
114}
Sourcepub unsafe fn is_enabled(&self) -> bool
pub unsafe fn is_enabled(&self) -> bool
Examples found in repository?
examples/copy.rs (line 62)
35fn main() {
36 unsafe {
37 /* The same classes, but one is our victim, and the other is unaffected. */
38 let mut victim_cpp_class = CppClass::default();
39 let unaffected_cpp_class = CppClass::default();
40
41 /* If you can, use Hook over RawHook. It uses Rust's lifetime system
42 * to force victim_cpp_class to stay valid while hook is set because
43 * you can't drop victim_cpp_class while its being borrowed inside
44 * copy::Hook */
45 {
46 /* Setting up hook */
47 /* To get VTable size you can use multiple methods:
48 * Calculate it on runtime by passing None as methods_count arg inside Hook::new() (very unsafe!)
49 * If your VTable struct implementation is 100% valid, you can use
50 * std::mem::size_of::<VTableStruct>() / std::mem::size_of::<usize>() to get
51 * methods count at compile time, or just specify it manually: Some(2) */
52 let vtable_size = std::mem::size_of::<CppClassVTable>() / std::mem::size_of::<usize>();
53 let mut hook =
54 vtable_hook::hook::copy::Hook::new(&mut victim_cpp_class, None, Some(vtable_size));
55 eprintln!("Hook: {hook:#?}");
56 /* Since we are mutually borrowing victim_cpp_class in hook we can't use it directly
57 * but we can use hook's reference instead:
58 * &hook.item */
59
60 /* Hooks are unset now, let's test that its true */
61 eprintln!("-- Hook is disabled -- ");
62 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
63 {
64 let victim_cpp_class = &hook.item;
65 eprintln!(
66 "victim_cpp_class bar() result = {}",
67 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
68 );
69 }
70 eprintln!(
71 "unaffected_cpp_class bar() result = {}",
72 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
73 );
74 /* victim_cpp_class's hook is_enabled false
75 * victim_cpp_class bar() result = 0
76 * unaffected_cpp_class bar() result = 0 */
77
78 /* Replacing bar inside raw_hook */
79 hook.replace_method(1, bar_hooked as _);
80 /* Replacing victim_cpp_class's VTable */
81 hook.enable();
82 /* Testing */
83 eprintln!("-- Hook is enabled -- ");
84 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
85 {
86 let victim_cpp_class = &hook.item;
87 eprintln!(
88 "victim_cpp_class bar() result = {}",
89 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
90 );
91 }
92 eprintln!(
93 "unaffected_cpp_class bar() result = {}",
94 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
95 );
96 /* victim_cpp_class's hook is_enabled true
97 * victim_cpp_class bar() result = 1
98 * unaffected_cpp_class bar() result = 0 */
99
100 /* hook will disable itself on drop() */
101 }
102 eprintln!("-- Hook is disabled (drop) -- ");
103 eprintln!(
104 "victim_cpp_class bar() result = {}",
105 (victim_cpp_class.vtable.read().bar)(&victim_cpp_class)
106 );
107 eprintln!(
108 "unaffected_cpp_class bar() result = {}",
109 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
110 );
111 /* victim_cpp_class bar() result = 0
112 * unaffected_cpp_class bar() result = 0 */
113 }
114}
Sourcepub unsafe fn enable(&mut self) -> bool
pub unsafe fn enable(&mut self) -> bool
Examples found in repository?
examples/copy.rs (line 81)
35fn main() {
36 unsafe {
37 /* The same classes, but one is our victim, and the other is unaffected. */
38 let mut victim_cpp_class = CppClass::default();
39 let unaffected_cpp_class = CppClass::default();
40
41 /* If you can, use Hook over RawHook. It uses Rust's lifetime system
42 * to force victim_cpp_class to stay valid while hook is set because
43 * you can't drop victim_cpp_class while its being borrowed inside
44 * copy::Hook */
45 {
46 /* Setting up hook */
47 /* To get VTable size you can use multiple methods:
48 * Calculate it on runtime by passing None as methods_count arg inside Hook::new() (very unsafe!)
49 * If your VTable struct implementation is 100% valid, you can use
50 * std::mem::size_of::<VTableStruct>() / std::mem::size_of::<usize>() to get
51 * methods count at compile time, or just specify it manually: Some(2) */
52 let vtable_size = std::mem::size_of::<CppClassVTable>() / std::mem::size_of::<usize>();
53 let mut hook =
54 vtable_hook::hook::copy::Hook::new(&mut victim_cpp_class, None, Some(vtable_size));
55 eprintln!("Hook: {hook:#?}");
56 /* Since we are mutually borrowing victim_cpp_class in hook we can't use it directly
57 * but we can use hook's reference instead:
58 * &hook.item */
59
60 /* Hooks are unset now, let's test that its true */
61 eprintln!("-- Hook is disabled -- ");
62 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
63 {
64 let victim_cpp_class = &hook.item;
65 eprintln!(
66 "victim_cpp_class bar() result = {}",
67 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
68 );
69 }
70 eprintln!(
71 "unaffected_cpp_class bar() result = {}",
72 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
73 );
74 /* victim_cpp_class's hook is_enabled false
75 * victim_cpp_class bar() result = 0
76 * unaffected_cpp_class bar() result = 0 */
77
78 /* Replacing bar inside raw_hook */
79 hook.replace_method(1, bar_hooked as _);
80 /* Replacing victim_cpp_class's VTable */
81 hook.enable();
82 /* Testing */
83 eprintln!("-- Hook is enabled -- ");
84 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
85 {
86 let victim_cpp_class = &hook.item;
87 eprintln!(
88 "victim_cpp_class bar() result = {}",
89 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
90 );
91 }
92 eprintln!(
93 "unaffected_cpp_class bar() result = {}",
94 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
95 );
96 /* victim_cpp_class's hook is_enabled true
97 * victim_cpp_class bar() result = 1
98 * unaffected_cpp_class bar() result = 0 */
99
100 /* hook will disable itself on drop() */
101 }
102 eprintln!("-- Hook is disabled (drop) -- ");
103 eprintln!(
104 "victim_cpp_class bar() result = {}",
105 (victim_cpp_class.vtable.read().bar)(&victim_cpp_class)
106 );
107 eprintln!(
108 "unaffected_cpp_class bar() result = {}",
109 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
110 );
111 /* victim_cpp_class bar() result = 0
112 * unaffected_cpp_class bar() result = 0 */
113 }
114}
pub unsafe fn disable(&mut self) -> bool
Sourcepub unsafe fn replace_method(
&mut self,
index: usize,
our_method: Method,
) -> Option<()>
pub unsafe fn replace_method( &mut self, index: usize, our_method: Method, ) -> Option<()>
Examples found in repository?
examples/copy.rs (line 79)
35fn main() {
36 unsafe {
37 /* The same classes, but one is our victim, and the other is unaffected. */
38 let mut victim_cpp_class = CppClass::default();
39 let unaffected_cpp_class = CppClass::default();
40
41 /* If you can, use Hook over RawHook. It uses Rust's lifetime system
42 * to force victim_cpp_class to stay valid while hook is set because
43 * you can't drop victim_cpp_class while its being borrowed inside
44 * copy::Hook */
45 {
46 /* Setting up hook */
47 /* To get VTable size you can use multiple methods:
48 * Calculate it on runtime by passing None as methods_count arg inside Hook::new() (very unsafe!)
49 * If your VTable struct implementation is 100% valid, you can use
50 * std::mem::size_of::<VTableStruct>() / std::mem::size_of::<usize>() to get
51 * methods count at compile time, or just specify it manually: Some(2) */
52 let vtable_size = std::mem::size_of::<CppClassVTable>() / std::mem::size_of::<usize>();
53 let mut hook =
54 vtable_hook::hook::copy::Hook::new(&mut victim_cpp_class, None, Some(vtable_size));
55 eprintln!("Hook: {hook:#?}");
56 /* Since we are mutually borrowing victim_cpp_class in hook we can't use it directly
57 * but we can use hook's reference instead:
58 * &hook.item */
59
60 /* Hooks are unset now, let's test that its true */
61 eprintln!("-- Hook is disabled -- ");
62 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
63 {
64 let victim_cpp_class = &hook.item;
65 eprintln!(
66 "victim_cpp_class bar() result = {}",
67 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
68 );
69 }
70 eprintln!(
71 "unaffected_cpp_class bar() result = {}",
72 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
73 );
74 /* victim_cpp_class's hook is_enabled false
75 * victim_cpp_class bar() result = 0
76 * unaffected_cpp_class bar() result = 0 */
77
78 /* Replacing bar inside raw_hook */
79 hook.replace_method(1, bar_hooked as _);
80 /* Replacing victim_cpp_class's VTable */
81 hook.enable();
82 /* Testing */
83 eprintln!("-- Hook is enabled -- ");
84 eprintln!("victim_cpp_class's hook is_enabled {}", hook.is_enabled());
85 {
86 let victim_cpp_class = &hook.item;
87 eprintln!(
88 "victim_cpp_class bar() result = {}",
89 (victim_cpp_class.vtable.read().bar)(*victim_cpp_class)
90 );
91 }
92 eprintln!(
93 "unaffected_cpp_class bar() result = {}",
94 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
95 );
96 /* victim_cpp_class's hook is_enabled true
97 * victim_cpp_class bar() result = 1
98 * unaffected_cpp_class bar() result = 0 */
99
100 /* hook will disable itself on drop() */
101 }
102 eprintln!("-- Hook is disabled (drop) -- ");
103 eprintln!(
104 "victim_cpp_class bar() result = {}",
105 (victim_cpp_class.vtable.read().bar)(&victim_cpp_class)
106 );
107 eprintln!(
108 "unaffected_cpp_class bar() result = {}",
109 (unaffected_cpp_class.vtable.read().bar)(&unaffected_cpp_class)
110 );
111 /* victim_cpp_class bar() result = 0
112 * unaffected_cpp_class bar() result = 0 */
113 }
114}
pub unsafe fn restore_method(&mut self, index: usize) -> Option<()>
pub unsafe fn restore_all(&mut self)
Trait Implementations§
Auto Trait Implementations§
impl<'a, T> Freeze for Hook<'a, T>
impl<'a, T> RefUnwindSafe for Hook<'a, T>where
T: RefUnwindSafe,
impl<'a, T> !Send for Hook<'a, T>
impl<'a, T> !Sync for Hook<'a, T>
impl<'a, T> Unpin for Hook<'a, T>
impl<'a, T> !UnwindSafe for Hook<'a, T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more