pub mod arch;
pub mod asm;
pub mod builder;
pub mod guard;
pub mod hook;
#[cfg(feature = "std")]
pub mod registry;
pub mod trampoline;
pub use arch::{Architecture, NativeArch, X64, X86};
pub use builder::{state as BuilderState, HookBuilder};
pub use guard::{HookGuard, HookState, StatefulHookGuard};
pub use hook::{Hook, HookChain, HotPatchHook, InlineHook, MidFunctionHook};
#[cfg(feature = "std")]
pub use registry::{HookRegistry, HookType, RegisteredHook};
pub use trampoline::ExecutableMemory;
pub use hook::iat::{IatHook, IatHookGuard, IatEntry, enumerate_iat_entries, find_iat_entry, hook_import, hook_import_all};
pub use hook::eat::{EatHook, EatHookBuilder, EatHookGuard, EatEntry, enumerate_eat_entries, find_eat_entry, find_eat_entry_by_ordinal};
pub use hook::veh::{VehHook, VehHookType, DebugRegister, BreakCondition, BreakLength, get_available_debug_register};
pub use hook::vmt::{VmtHook, VmtHookGuard, VmtHookBuilder, ShadowVmt, VmtObject, get_vtable, get_vtable_entry, estimate_vtable_size};
#[cfg(target_arch = "x86_64")]
pub use hook::mid::HookContext;
#[cfg(target_arch = "x86")]
pub use hook::mid::HookContext;
pub use hook::mid::MidHookFn;
use crate::error::Result;
pub fn hook<A: Architecture>(target: usize, detour: usize) -> Result<HookGuard<A>> {
InlineHook::<A>::new(target, detour).install()
}
#[cfg(target_arch = "x86_64")]
pub fn hook_native(target: usize, detour: usize) -> Result<HookGuard<X64>> {
hook::<X64>(target, detour)
}
#[cfg(target_arch = "x86")]
pub fn hook_native(target: usize, detour: usize) -> Result<HookGuard<X86>> {
hook::<X86>(target, detour)
}
pub fn hotpatch<A: Architecture>(target: usize, detour: usize) -> Result<HookGuard<A>> {
HotPatchHook::<A>::new(target, detour).install()
}
pub fn is_hot_patchable(target: usize) -> bool {
hook::hotpatch::is_hot_patchable(target)
}
pub fn mid_hook<A: Architecture>(
address: usize,
detour: MidHookFn,
) -> Result<HookGuard<A>> {
MidFunctionHook::<A>::new(address, detour).install()
}
pub fn create_chain<A: Architecture>(target: usize) -> Result<HookChain<A>> {
HookChain::new(target)
}
#[cfg(feature = "navigation")]
pub fn hook_export<A: Architecture>(
module: &str,
export: &str,
detour: usize,
) -> Result<HookGuard<A>> {
use crate::navigation::ModuleQuery;
use crate::structures::Peb;
let peb = Peb::current()?;
let query = ModuleQuery::new(&peb);
let module = query.find_by_name(module)?;
let target = module.get_export(export)?;
hook::<A>(target, detour)
}
#[cfg(all(feature = "navigation", target_arch = "x86_64"))]
pub fn hook_export_native(
module: &str,
export: &str,
detour: usize,
) -> Result<HookGuard<X64>> {
hook_export::<X64>(module, export, detour)
}
#[cfg(all(feature = "navigation", target_arch = "x86"))]
pub fn hook_export_native(
module: &str,
export: &str,
detour: usize,
) -> Result<HookGuard<X86>> {
hook_export::<X86>(module, export, detour)
}
#[cfg(feature = "navigation")]
pub fn iat_hook(import_dll: &str, function_name: &str, detour: usize) -> Result<IatHook> {
hook_import(import_dll, function_name, detour)
}
#[cfg(feature = "navigation")]
pub fn iat_hook_in(
target_module: &str,
import_dll: &str,
function_name: &str,
detour: usize,
) -> Result<IatHook> {
IatHook::new(target_module, import_dll, function_name, detour)
}
#[cfg(feature = "navigation")]
pub fn eat_hook(module_name: &str, function_name: &str, detour: usize) -> Result<EatHook> {
EatHook::new(module_name, function_name, detour)
}
pub fn veh_hook_hardware(target: usize, detour: usize) -> Result<VehHook> {
let dr = get_available_debug_register()?;
VehHook::hardware(target, detour, dr)
}
pub fn veh_hook_int3(target: usize, detour: usize) -> Result<VehHook> {
VehHook::int3(target, detour)
}
pub unsafe fn vmt_hook(object: *const (), index: usize, detour: usize) -> Result<VmtHook> {
unsafe { VmtHook::new(object, index, detour) }
}
pub unsafe fn shadow_vmt<T>(object: *mut (), vtable_size: usize) -> Result<ShadowVmt<T>> {
unsafe { ShadowVmt::new(object, vtable_size) }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_native_arch_defined() {
let _: usize = NativeArch::JMP_REL_SIZE;
let _: usize = NativeArch::JMP_ABS_SIZE;
let _: usize = NativeArch::PTR_SIZE;
}
}