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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
//! # MinHook-rs
//!
//! A Rust implementation of MinHook library for Windows x64 function hooking.
//!
//! This library provides a simple, thread-safe API for intercepting Win32 functions
//! with precise instruction decoding and minimal overhead.
//!
//! ## Features
//!
//! - **Precise instruction decoder** - Custom x64 disassembler optimized for hook creation
//! - **Thread-safe operations** - All APIs are thread-safe with proper synchronization
//! - **Memory efficient** - Optimized data structures with minimal memory footprint
//! - **Comprehensive error handling** - Detailed error reporting for all edge cases
//! - **Production ready** - Extensively tested with multiple hook scenarios
//! - **Zero-copy design** - Efficient instruction processing without unnecessary allocations
//!
//! ## Basic Usage
//!
//! The typical workflow involves initialization, hook creation, activation, and cleanup:
//!
//! ```rust,no_run
//! use min_hook_rs::*;
//! use std::ffi::c_void;
//! use std::ptr;
//! use windows_sys::Win32::UI::WindowsAndMessaging::*;
//!
//! // Define function signature
//! type MessageBoxAFn = unsafe extern "system" fn(HWND, PCSTR, PCSTR, u32) -> i32;
//! static mut ORIGINAL_MESSAGEBOX: Option<MessageBoxAFn> = None;
//!
//! // Hook function
//! unsafe extern "system" fn hooked_messagebox(
//! hwnd: HWND, _text: PCSTR, _caption: PCSTR, utype: u32
//! ) -> i32 {
//! let new_text = "Hooked by MinHook-rs!\0";
//! let new_caption = "Hook Demo\0";
//!
//! // Call original function safely
//! let original = ptr::addr_of!(ORIGINAL_MESSAGEBOX).read().unwrap();
//! original(hwnd, new_text.as_ptr(), new_caption.as_ptr(), utype)
//! }
//!
//! fn main() -> Result<()> {
//! // Initialize the hooking system
//! initialize()?;
//!
//! // Create hook by API name
//! let (trampoline, target) = create_hook_api(
//! "user32",
//! "MessageBoxA",
//! hooked_messagebox as *mut c_void
//! )?;
//!
//! // Store original function for later use
//! unsafe {
//! ORIGINAL_MESSAGEBOX = Some(std::mem::transmute(trampoline));
//! }
//!
//! // Activate the hook
//! enable_hook(target)?;
//!
//! // Test the hook
//! unsafe {
//! MessageBoxA(ptr::null_mut(), "Test\0".as_ptr(), "Title\0".as_ptr(), MB_OK);
//! }
//!
//! // Cleanup
//! disable_hook(target)?;
//! remove_hook(target)?;
//! uninitialize()?;
//!
//! Ok(())
//! }
//! ```
//!
//! ## Hook by Function Address
//!
//! You can also hook functions by their memory address:
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! # use std::ffi::c_void;
//! # unsafe fn my_hook() {}
//! # fn main() -> Result<()> {
//! // Get function address (example)
//! let target_address = 0x12345678 as *mut c_void;
//!
//! // Create hook by address
//! let (trampoline, target) = create_hook(target_address, my_hook as *mut c_void)?;
//!
//! // Enable the hook
//! enable_hook(target)?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Multiple Hook Management
//!
//! MinHook-rs supports managing multiple hooks simultaneously:
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! # use std::ffi::c_void;
//! # unsafe fn hook1() {}
//! # unsafe fn hook2() {}
//! # fn main() -> Result<()> {
//! // Create multiple hooks
//! let (_, target1) = create_hook_api("user32", "MessageBoxA", hook1 as *mut c_void)?;
//! let (_, target2) = create_hook_api("kernel32", "GetTickCount", hook2 as *mut c_void)?;
//!
//! // Enable all hooks at once
//! enable_hook(ALL_HOOKS)?;
//!
//! // Your code here...
//!
//! // Disable all hooks at once
//! disable_hook(ALL_HOOKS)?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Queued Operations
//!
//! For atomic operations on multiple hooks, use queued operations:
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! # use std::ffi::c_void;
//! # fn main() -> Result<()> {
//! # let target = std::ptr::null_mut();
//! // Queue multiple operations
//! queue_enable_hook(target)?;
//! queue_disable_hook(target)?;
//! queue_enable_hook(target)?;
//!
//! // Apply all operations atomically
//! apply_queued()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Error Handling
//!
//! MinHook-rs provides comprehensive error handling for all edge cases:
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! # use std::ffi::c_void;
//! # unsafe fn hook_fn() {}
//! match create_hook_api("user32", "MessageBoxA", hook_fn as *mut c_void) {
//! Ok((trampoline, target)) => {
//! println!("Hook created at {:p}", target);
//! },
//! Err(HookError::ModuleNotFound) => {
//! println!("Module not loaded");
//! },
//! Err(HookError::FunctionNotFound) => {
//! println!("Function not exported");
//! },
//! Err(HookError::AlreadyCreated) => {
//! println!("Hook already exists");
//! },
//! Err(e) => {
//! println!("Other error: {}", status_to_string(&e));
//! }
//! }
//! ```
//!
//! ## Advanced Usage
//!
//! ### Custom Hook Detection
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! # fn main() -> Result<()> {
//! // Check if a code region can be safely hooked
//! let code_bytes = &[0x48, 0x83, 0xEC, 0x28]; // SUB RSP, 28h
//! if can_hook_safely(code_bytes, 5) {
//! println!("Safe to install 5-byte hook");
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ### Instruction Analysis
//!
//! ```rust,no_run
//! # use min_hook_rs::*;
//! let code_bytes = &[0x48, 0x8B, 0x05, 0x12, 0x34, 0x56, 0x78]; // MOV RAX, [RIP+12345678h]
//! let inst = decode_instruction(code_bytes);
//!
//! println!("Instruction length: {}", inst.len);
//! println!("Is RIP-relative: {}", inst.is_rip_relative());
//! println!("Displacement: 0x{:08X}", inst.displacement);
//! ```
//!
//! ## Hook Function Guidelines
//!
//! When writing hook functions, follow these guidelines:
//!
//! 1. **Match signatures exactly**: Hook functions must have the same calling convention and signature as the target
//! 2. **Store originals safely**: Use `ptr::addr_of!` for thread-safe access to original function pointers
//! 3. **Handle errors gracefully**: Always check for null pointers and handle edge cases
//! 4. **Minimize hook overhead**: Keep hook functions lightweight to avoid performance impact
//!
//! ## Safety Considerations
//!
//! This library uses unsafe operations for low-level memory manipulation.
//! Users must ensure:
//!
//! - Hook functions have the exact same signature as target functions
//! - Target functions are valid and executable
//! - Proper initialization and cleanup order
//! - Thread-safe access to shared hook state
//!
//! ## Platform Requirements
//!
//! - **Architecture**: x86_64 only
//! - **Operating System**: Windows only
//! - **Minimum Rust Version**: 1.85.0
compile_error!;
compile_error!;
// Re-export main API
pub use ;
pub use ;
// Re-export for advanced usage
pub use ;
/// Library version
pub const VERSION: &str = env!;
/// Check if the current platform is supported
///
/// Returns `true` if running on x86_64 Windows, `false` otherwise.
///
/// # Example
///
/// ```rust
/// # use min_hook_rs::is_supported;
/// if !is_supported() {
/// eprintln!("MinHook-rs only supports x86_64 Windows");
/// return;
/// }
/// ```
/// Get library version string
///
/// Returns the current version of MinHook-rs.
///
/// # Example
///
/// ```rust
/// # use min_hook_rs::get_version;
/// println!("MinHook-rs version: {}", get_version());
/// ```