librasan: Simplify assembly patches (#3192)
Co-authored-by: Dongjia "toka" Zhang <tokazerkje@outlook.com>
This commit is contained in:
parent
df9b5b7e3d
commit
0d962bc561
@ -19,7 +19,7 @@ impl Patch for RawPatch {
|
||||
if target == destination {
|
||||
Err(RawPatchError::IdentityPatch(target))?;
|
||||
}
|
||||
let patch = Self::get_patch(target, destination)?;
|
||||
let patch = Self::get_patch(target, destination);
|
||||
|
||||
// Mask the thumb mode indicator bit
|
||||
#[cfg(target_arch = "arm")]
|
||||
@ -34,108 +34,88 @@ impl Patch for RawPatch {
|
||||
|
||||
impl RawPatch {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Result<Vec<u8>, RawPatchError> {
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Vec<u8> {
|
||||
// mov rax, 0xdeadfacef00dd00d
|
||||
// jmp rax
|
||||
let insns = [
|
||||
[0x48, 0xb8, 0x0d, 0xd0, 0x0d, 0xf0, 0xce, 0xfa, 0xad, 0xde].to_vec(),
|
||||
[0xff, 0xe0].to_vec(),
|
||||
let addr = destination.to_ne_bytes();
|
||||
#[rustfmt::skip]
|
||||
let insns: &[&[u8]] = &[
|
||||
&[0x48, 0xb8], &addr,
|
||||
&[0xff, 0xe0],
|
||||
];
|
||||
let addr = destination.to_le_bytes();
|
||||
let insn0_mod = [
|
||||
insns[0][0],
|
||||
insns[0][1],
|
||||
addr[0],
|
||||
addr[1],
|
||||
addr[2],
|
||||
addr[3],
|
||||
addr[4],
|
||||
addr[5],
|
||||
addr[6],
|
||||
addr[7],
|
||||
]
|
||||
.to_vec();
|
||||
let insns_mod = [&insn0_mod, &insns[1]];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
insns.concat()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Result<Vec<u8>, RawPatchError> {
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Vec<u8> {
|
||||
// mov eax, 0xdeadface
|
||||
// jmp eax
|
||||
let insns = [
|
||||
[0xb8, 0xce, 0xfa, 0xad, 0xde].to_vec(),
|
||||
[0xff, 0xe0].to_vec(),
|
||||
let addr = destination.to_ne_bytes();
|
||||
#[rustfmt::skip]
|
||||
let insns: &[&[u8]] = &[
|
||||
&[0xb8], &addr,
|
||||
&[0xff, 0xe0],
|
||||
];
|
||||
let addr = destination.to_le_bytes();
|
||||
let insn0_mod = [insns[0][0], addr[0], addr[1], addr[2], addr[3]].to_vec();
|
||||
let insns_mod = [&insn0_mod, &insns[1]];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
insns.concat()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
fn get_patch(target: GuestAddr, destination: GuestAddr) -> Result<Vec<u8>, RawPatchError> {
|
||||
fn get_patch(target: GuestAddr, destination: GuestAddr) -> Vec<u8> {
|
||||
let addr = destination.to_ne_bytes();
|
||||
// If our target is in thumb mode
|
||||
if target & 1 == 1 {
|
||||
#[rustfmt::skip]
|
||||
let insns: &[&[u8]] = if target & 1 == 1 {
|
||||
// ldr ip, [pc, #2]
|
||||
// bx ip
|
||||
// .long 0xdeadface
|
||||
let insns = [
|
||||
[0xdf, 0xf8, 0x02, 0xc0].to_vec(),
|
||||
[0x60, 0x47].to_vec(),
|
||||
[0xce, 0xfa, 0xad, 0xde].to_vec(),
|
||||
];
|
||||
let addr = destination.to_ne_bytes().to_vec();
|
||||
let insns_mod = [&insns[0], &insns[1], &addr];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
&[
|
||||
&[0xdf, 0xf8, 0x02, 0xc0],
|
||||
&[0x60, 0x47],
|
||||
&addr,
|
||||
]
|
||||
} else {
|
||||
// ldr ip, [pc]
|
||||
// bx ip
|
||||
// .long 0xdeadface
|
||||
let insns = [
|
||||
[0x00, 0xc0, 0x9f, 0xe5].to_vec(),
|
||||
[0x1c, 0xff, 0x2f, 0xe1].to_vec(),
|
||||
[0xce, 0xfa, 0xad, 0xde].to_vec(),
|
||||
];
|
||||
let addr = destination.to_ne_bytes().to_vec();
|
||||
let insns_mod = [&insns[0], &insns[1], &addr];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
}
|
||||
&[
|
||||
&[0x00, 0xc0, 0x9f, 0xe5],
|
||||
&[0x1c, 0xff, 0x2f, 0xe1],
|
||||
&addr,
|
||||
]
|
||||
};
|
||||
insns.concat()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Result<Vec<u8>, RawPatchError> {
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Vec<u8> {
|
||||
// ldr x16, #8
|
||||
// br x16
|
||||
// .quad 0xdeadfacef00dd00d
|
||||
let insns = [
|
||||
[0x50, 0x00, 0x00, 0x58].to_vec(),
|
||||
[0x00, 0x02, 0x1f, 0xd6].to_vec(),
|
||||
[0x0d, 0xd0, 0x0d, 0xf0].to_vec(),
|
||||
[0xce, 0xfa, 0xad, 0xde].to_vec(),
|
||||
let addr = destination.to_ne_bytes();
|
||||
#[rustfmt::skip]
|
||||
let insns: &[&[u8]] = &[
|
||||
&[0x50, 0x00, 0x00, 0x58],
|
||||
&[0x00, 0x02, 0x1f, 0xd6],
|
||||
&addr
|
||||
];
|
||||
let addr = destination.to_ne_bytes().to_vec();
|
||||
let insns_mod = [&insns[0], &insns[1], &addr];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
insns.concat()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Result<Vec<u8>, RawPatchError> {
|
||||
fn get_patch(_target: GuestAddr, destination: GuestAddr) -> Vec<u8> {
|
||||
// lis 12, 0xdead
|
||||
// ori 12, 12, 0xface
|
||||
// mtctr 12
|
||||
// bctr
|
||||
let insns = [
|
||||
[0x3d, 0x80, 0xde, 0xad].to_vec(),
|
||||
[0x61, 0x8c, 0xfa, 0xce].to_vec(),
|
||||
[0x7d, 0x89, 0x03, 0xa6].to_vec(),
|
||||
[0x4e, 0x80, 0x04, 0x20].to_vec(),
|
||||
let addr = destination.to_ne_bytes();
|
||||
#[rustfmt::skip]
|
||||
let insns: &[&[u8]] = &[
|
||||
&[0x3d, 0x80], &addr[..2],
|
||||
&[0x61, 0x8c], &addr[2..],
|
||||
&[0x7d, 0x89, 0x03, 0xa6],
|
||||
&[0x4e, 0x80, 0x04, 0x20],
|
||||
];
|
||||
let addr = destination.to_be_bytes().to_vec();
|
||||
let insn0_mod = [insns[0][0], insns[0][1], addr[0], addr[1]].to_vec();
|
||||
let insn1_mod = [insns[1][0], insns[1][1], addr[2], addr[3]].to_vec();
|
||||
let insns_mod = [&insn0_mod, &insn1_mod, &insns[2], &insns[3]];
|
||||
Ok(insns_mod.into_iter().flatten().cloned().collect())
|
||||
insns.concat()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user