199 lines
5.7 KiB
Rust
199 lines
5.7 KiB
Rust
#![cfg_attr(target_arch = "arm", feature(arm_target_feature))]
|
|
|
|
#[cfg(test)]
|
|
#[cfg(feature = "libc")]
|
|
#[cfg(not(target_arch = "arm"))]
|
|
mod tests {
|
|
use asan::{
|
|
GuestAddr,
|
|
mmap::{Mmap, MmapProt, linux::LinuxMmap},
|
|
patch::{Patch, raw::RawPatch},
|
|
};
|
|
use libc::{_SC_PAGESIZE, sysconf};
|
|
use log::info;
|
|
|
|
#[unsafe(no_mangle)]
|
|
extern "C" fn test1(a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> usize {
|
|
assert_eq!(a1, 1);
|
|
assert_eq!(a2, 2);
|
|
assert_eq!(a3, 3);
|
|
assert_eq!(a4, 4);
|
|
assert_eq!(a5, 5);
|
|
assert_eq!(a6, 6);
|
|
0xdeadface
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
extern "C" fn test2(a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> usize {
|
|
assert_eq!(a1, 1);
|
|
assert_eq!(a2, 2);
|
|
assert_eq!(a3, 3);
|
|
assert_eq!(a4, 4);
|
|
assert_eq!(a5, 5);
|
|
assert_eq!(a6, 6);
|
|
0xd00df00d
|
|
}
|
|
|
|
#[test]
|
|
fn test_patch() {
|
|
let ret1 = test1(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret1, 0xdeadface);
|
|
|
|
let ret2 = test2(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret2, 0xd00df00d);
|
|
|
|
let ptest1 = test1 as *const () as GuestAddr;
|
|
let ptest2 = test2 as *const () as GuestAddr;
|
|
info!("pfn: {:#x}", ptest1);
|
|
let aligned_pfn = ptest1 & !0xfff;
|
|
let page_size = unsafe { sysconf(_SC_PAGESIZE) as usize };
|
|
info!("aligned_pfn: {:#x}", aligned_pfn);
|
|
info!("page_size: {:#x}", page_size);
|
|
LinuxMmap::protect(
|
|
aligned_pfn,
|
|
page_size * 2,
|
|
MmapProt::READ | MmapProt::WRITE | MmapProt::EXEC,
|
|
)
|
|
.unwrap();
|
|
|
|
RawPatch::patch(ptest1, ptest2).unwrap();
|
|
let ret = test1(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret, 0xd00df00d);
|
|
LinuxMmap::protect(aligned_pfn, page_size * 2, MmapProt::READ | MmapProt::EXEC).unwrap();
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[cfg(feature = "libc")]
|
|
#[cfg(target_arch = "arm")]
|
|
mod tests {
|
|
use asan::{
|
|
GuestAddr,
|
|
mmap::{Mmap, MmapProt, linux::LinuxMmap},
|
|
patch::{Patch, raw::RawPatch},
|
|
};
|
|
use libc::{_SC_PAGESIZE, sysconf};
|
|
use log::info;
|
|
|
|
macro_rules! define_test_function {
|
|
($fn_name:ident, $ret_val:expr) => {
|
|
define_test_function!([], $fn_name, $ret_val);
|
|
};
|
|
|
|
($attr:meta, $fn_name:ident, $ret_val:expr) => {
|
|
define_test_function!([$attr], $fn_name, $ret_val);
|
|
};
|
|
|
|
([$($attr:meta)*], $fn_name:ident, $ret_val:expr) => {
|
|
#[unsafe(no_mangle)]
|
|
$(#[$attr])*
|
|
extern "C" fn $fn_name(
|
|
a1: usize,
|
|
a2: usize,
|
|
a3: usize,
|
|
a4: usize,
|
|
a5: usize,
|
|
a6: usize,
|
|
) -> usize {
|
|
assert_eq!(a1, 1);
|
|
assert_eq!(a2, 2);
|
|
assert_eq!(a3, 3);
|
|
assert_eq!(a4, 4);
|
|
assert_eq!(a5, 5);
|
|
assert_eq!(a6, 6);
|
|
return $ret_val;
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! define_test {
|
|
(
|
|
$fn_name:ident,
|
|
$test_fn1:ident,
|
|
$test_fn2:ident,
|
|
$test_ret_val1:expr,
|
|
$test_ret_val2:expr
|
|
) => {
|
|
#[test]
|
|
fn $fn_name() {
|
|
#[allow(unused_unsafe)]
|
|
unsafe {
|
|
let ret1 = $test_fn1(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret1, $test_ret_val1);
|
|
|
|
let ret2 = $test_fn2(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret2, $test_ret_val2);
|
|
|
|
let ptest1 = $test_fn1 as *const () as GuestAddr;
|
|
let ptest2 = $test_fn2 as *const () as GuestAddr;
|
|
info!("pfn: {:#x}", ptest1);
|
|
let aligned_pfn = ptest1 & !0xfff;
|
|
let page_size = unsafe { sysconf(_SC_PAGESIZE) as usize };
|
|
info!("aligned_pfn: {:#x}", aligned_pfn);
|
|
info!("page_size: {:#x}", page_size);
|
|
LinuxMmap::protect(
|
|
aligned_pfn,
|
|
page_size * 2,
|
|
MmapProt::READ | MmapProt::WRITE | MmapProt::EXEC,
|
|
)
|
|
.unwrap();
|
|
|
|
RawPatch::patch(ptest1, ptest2).unwrap();
|
|
let ret = $test_fn1(1, 2, 3, 4, 5, 6);
|
|
assert_eq!(ret, $test_ret_val2);
|
|
LinuxMmap::protect(aligned_pfn, page_size * 2, MmapProt::READ | MmapProt::EXEC)
|
|
.unwrap();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
define_test_function!(arm_patch_target, 0xdeadface);
|
|
define_test_function!(patched_arm_to_arm, 0xd00df00d);
|
|
define_test_function!(patched_arm_to_thumb, 0xfeeddeaf);
|
|
define_test_function!(
|
|
target_feature(enable = "thumb-mode"),
|
|
thumb_patch_target,
|
|
0xcafebabe
|
|
);
|
|
define_test_function!(
|
|
target_feature(enable = "thumb-mode"),
|
|
patched_thumb_to_thumb,
|
|
0xbeeffade
|
|
);
|
|
define_test_function!(
|
|
target_feature(enable = "thumb-mode"),
|
|
patched_thumb_to_arm,
|
|
0xdeedcede
|
|
);
|
|
|
|
define_test!(
|
|
test_patch_arm_to_arm,
|
|
patched_arm_to_arm,
|
|
arm_patch_target,
|
|
0xd00df00d,
|
|
0xdeadface
|
|
);
|
|
define_test!(
|
|
test_patch_arm_to_thumb,
|
|
patched_arm_to_thumb,
|
|
thumb_patch_target,
|
|
0xfeeddeaf,
|
|
0xcafebabe
|
|
);
|
|
define_test!(
|
|
test_patch_thumb_to_arm,
|
|
patched_thumb_to_arm,
|
|
arm_patch_target,
|
|
0xdeedcede,
|
|
0xdeadface
|
|
);
|
|
define_test!(
|
|
test_patch_thumb_to_thumb,
|
|
patched_thumb_to_thumb,
|
|
thumb_patch_target,
|
|
0xbeeffade,
|
|
0xcafebabe
|
|
);
|
|
}
|