#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
mod x64;
mod x86;
pub use x64::X64;
pub use x86::X86;
#[cfg(target_arch = "x86_64")]
pub type NativeArch = X64;
#[cfg(target_arch = "x86")]
pub type NativeArch = X86;
pub trait Architecture: Sized + 'static {
const JMP_REL_SIZE: usize;
const JMP_ABS_SIZE: usize;
const PTR_SIZE: usize;
const CODE_ALIGNMENT: usize;
const MIN_HOOK_SIZE: usize;
fn encode_jmp_rel(source: usize, target: usize) -> Option<Vec<u8>>;
fn encode_jmp_abs(target: usize) -> Vec<u8>;
fn encode_call_rel(source: usize, target: usize) -> Option<Vec<u8>>;
fn encode_nop_sled(size: usize) -> Vec<u8>;
fn find_instruction_boundary(code: &[u8], required_size: usize) -> Option<usize>;
fn relocate_instruction(
instruction: &[u8],
old_address: usize,
new_address: usize,
) -> Option<Vec<u8>>;
fn needs_relocation(instruction: &[u8]) -> bool;
fn preferred_hook_size(target: usize, detour: usize) -> usize {
let distance = (target as i64 - detour as i64).abs();
if distance <= i32::MAX as i64 {
Self::JMP_REL_SIZE
} else {
Self::JMP_ABS_SIZE
}
}
}
#[derive(Debug, Clone)]
pub struct DecodedInstruction {
pub length: usize,
pub is_relative: bool,
pub relative_target: Option<usize>,
}
#[derive(Debug)]
pub struct RelocationResult {
pub bytes: Vec<u8>,
pub size_changed: bool,
}