#[cfg(not(target_arch = "x86_64"))]
compile_error!("This instruction module only supports x86_64 architecture");
use std::ffi::c_void;
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct JmpRelShort {
pub opcode: u8,
pub operand: u8,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct JmpRel {
pub opcode: u8,
pub operand: u32,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct JmpAbs {
pub opcode0: u8,
pub opcode1: u8,
pub dummy: u32,
pub address: u64,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct CallAbs {
pub opcode0: u8,
pub opcode1: u8,
pub dummy0: u32,
pub dummy1: u8,
pub dummy2: u8,
pub address: u64,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct JccRel {
pub opcode0: u8,
pub opcode1: u8,
pub operand: u32,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct JccAbs {
pub opcode: u8,
pub dummy0: u8,
pub dummy1: u8,
pub dummy2: u8,
pub dummy3: u32,
pub address: u64,
}
pub struct Trampoline {
pub target: *mut c_void,
pub detour: *mut c_void,
pub trampoline: *mut c_void,
pub relay: *mut c_void,
pub patch_above: bool,
pub n_ip: u32,
pub old_ips: [u8; 8],
pub new_ips: [u8; 8],
}
impl JmpRelShort {
pub fn new(offset: i8) -> Self {
Self {
opcode: 0xEB,
operand: offset as u8,
}
}
}
impl JmpRel {
pub fn new_jmp(offset: i32) -> Self {
Self {
opcode: 0xE9,
operand: offset as u32,
}
}
pub fn new_call(offset: i32) -> Self {
Self {
opcode: 0xE8,
operand: offset as u32,
}
}
}
impl JmpAbs {
pub fn new(address: u64) -> Self {
Self {
opcode0: 0xFF,
opcode1: 0x25,
dummy: 0x00000000,
address,
}
}
}
impl CallAbs {
pub fn new(address: u64) -> Self {
Self {
opcode0: 0xFF,
opcode1: 0x15,
dummy0: 0x00000002,
dummy1: 0xEB,
dummy2: 0x08,
address,
}
}
}
impl JccRel {
pub fn new(condition: u8, offset: i32) -> Self {
Self {
opcode0: 0x0F,
opcode1: 0x80 | (condition & 0x0F),
operand: offset as u32,
}
}
}
impl JccAbs {
pub fn new(condition: u8, address: u64) -> Self {
Self {
opcode: 0x70 | (condition & 0x0F),
dummy0: 0x0E,
dummy1: 0xFF,
dummy2: 0x25,
dummy3: 0x00000000,
address,
}
}
}
impl Trampoline {
pub fn new(target: *mut c_void, detour: *mut c_void, trampoline: *mut c_void) -> Self {
Self {
target,
detour,
trampoline,
relay: std::ptr::null_mut(),
patch_above: false,
n_ip: 0,
old_ips: [0; 8],
new_ips: [0; 8],
}
}
}