imping_hook/lib.rs
1//! In-process function hooking for the imping toolkit.
2//!
3//! Installs typed function detours and code injections at arbitrary addresses
4//! in the running process, and depends on nothing else in imping.
5//! Relocation, near-memory allocation and thread-safe patching come from the
6//! [`detour`] crate, wrapped behind this crate's types.
7//!
8//! # Examples
9//!
10//! ```no_run
11//! use imping_hook::Hook;
12//!
13//! #[inline(never)]
14//! extern "C" fn add(a: i32, b: i32) -> i32 { a + b }
15//! extern "C" fn sub(a: i32, b: i32) -> i32 { a - b }
16//!
17//! # fn main() -> imping_hook::Result<()> {
18//! // SAFETY: `add` is a real function with the signature below, and `sub`
19//! // shares it.
20//! let hook = unsafe {
21//! Hook::at(add as *const ())
22//! .redirect(sub as extern "C" fn(i32, i32) -> i32)
23//! .install()?
24//! };
25//!
26//! hook.enable()?;
27//! assert_eq!(add(3, 2), 1);
28//! assert_eq!(hook.original().call(3, 2), 5);
29//! # Ok(())
30//! # }
31//! ```
32//!
33//! # Main items
34//!
35//! - [`Hook`] redirects a function to another of the same signature and keeps
36//! the original callable. Its docs cover threads, batches and dropping.
37//! - [`Injection`] runs machine code, assembly or a register callback at an
38//! address, then the original code.
39//! - [`scan`] finds code by a byte pattern; [`Hook::scan`] and
40//! [`Injection::scan`] patch what it finds.
41//! - [`batch`] applies many enables and disables with one thread suspension.
42//! - [`Context`] holds the registers a register callback sees.
43//! - [`Error`] lists everything that can fail.
44
45#![warn(missing_docs)]
46
47mod batch;
48mod context;
49mod error;
50mod function;
51mod hook;
52mod inject;
53mod registry;
54pub mod scan;
55mod sys;
56
57pub use crate::batch::batch;
58pub use crate::context::{Context, Xmm};
59pub use crate::error::{Error, OsError, Result};
60pub use crate::function::{Function, Original};
61pub use crate::hook::{Hook, HookBuilder, HookScan, HookWith};
62pub use crate::inject::{Injection, InjectionBuilder, InjectionScan, InjectionWith};
63
64/// Re-exports the assembler used by
65/// [`InjectionBuilder::asm`](crate::InjectionBuilder::asm).
66///
67/// This is [`iced_x86`]'s `code_asm` module ([`CodeAssembler`], register
68/// constants such as `rax` and `xmm0`, operand helpers such as `qword_ptr`)
69/// plus [`IcedError`].
70///
71/// [`CodeAssembler`]: iced_x86::code_asm::CodeAssembler
72/// [`IcedError`]: iced_x86::IcedError
73#[cfg(target_arch = "x86_64")]
74pub mod asm {
75 pub use iced_x86::IcedError;
76 pub use iced_x86::code_asm::*;
77}