use crate::tests::helpers;
use crate::*;
#[test]
fn aarch64_add_1_plus_1() {
helpers::setup();
let code: [u8; 12] = [
0x20, 0x00, 0x80, 0xd2, 0x21, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x01, 0x8b,
];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
emu.step(); assert_eq!(emu.regs_aarch64().x[0], 1);
emu.step(); assert_eq!(emu.regs_aarch64().x[1], 1);
emu.step(); assert_eq!(emu.regs_aarch64().x[2], 2);
}
#[test]
fn aarch64_sub_sets_flags() {
helpers::setup();
let code: [u8; 12] = [
0xa0, 0x00, 0x80, 0xd2, 0xa1, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x01, 0xeb,
];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
emu.step(); emu.step(); emu.step();
assert_eq!(emu.regs_aarch64().x[2], 0);
assert!(emu.regs_aarch64().nzcv.z); assert!(!emu.regs_aarch64().nzcv.n); assert!(emu.regs_aarch64().nzcv.c); }
#[test]
fn aarch64_str_ldr_stack() {
helpers::setup();
let code: [u8; 20] = [
0xff, 0x43, 0x00, 0xd1, 0x40, 0x05, 0x80, 0xd2, 0xe0, 0x03, 0x00, 0xf9, 0x00, 0x00, 0x80,
0xd2, 0xe1, 0x03, 0x40, 0xf9,
];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
emu.step(); emu.step(); assert_eq!(emu.regs_aarch64().x[0], 42);
emu.step(); emu.step(); assert_eq!(emu.regs_aarch64().x[0], 0);
emu.step(); assert_eq!(emu.regs_aarch64().x[1], 42);
}
#[test]
fn aarch64_branch_and_link() {
helpers::setup();
let code: [u8; 12] = [
0x02, 0x00, 0x00, 0x94, 0xa0, 0xd5, 0x9b, 0xd2, 0xe0, 0xdd, 0x97, 0xd2,
];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
let base = emu.regs_aarch64().pc;
emu.step(); assert_eq!(emu.regs_aarch64().pc, base + 8); assert_eq!(emu.regs_aarch64().x[30], base + 4);
emu.step(); assert_eq!(emu.regs_aarch64().x[0], 0xbeef);
}
#[test]
fn aarch64_cbz_taken() {
helpers::setup();
let code: [u8; 16] = [
0x00, 0x00, 0x80, 0xd2, 0x40, 0x00, 0x00, 0xb4, 0xa1, 0xd5, 0x9b, 0xd2, 0x21, 0x00, 0x80,
0xd2,
];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
emu.step(); emu.step();
let base = emu.cfg.code_base_addr;
assert_eq!(emu.regs_aarch64().pc, base + 12);
emu.step(); assert_eq!(emu.regs_aarch64().x[1], 1);
}
#[test]
fn aarch64_shellcode_sum_loop() {
helpers::setup();
let code: [u8; 20] = [
0x00, 0x00, 0x80, 0xd2, 0xa1, 0x00, 0x80, 0xd2, 0x00, 0x00, 0x01, 0x8b, 0x21, 0x04, 0x00, 0xd1, 0xc1, 0xff, 0xff, 0xb5, ];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
for _ in 0..17 {
emu.step();
}
assert_eq!(
emu.regs_aarch64().x[0],
15,
"x0 should be 1+2+3+4+5=15, got {}",
emu.regs_aarch64().x[0]
);
assert_eq!(
emu.regs_aarch64().x[1],
0,
"x1 (counter) should be 0 after loop"
);
}
#[test]
fn aarch64_shellcode_sum_loop_run_to() {
helpers::setup();
let code: [u8; 20] = [
0x00, 0x00, 0x80, 0xd2, 0xa1, 0x00, 0x80, 0xd2, 0x00, 0x00, 0x01, 0x8b, 0x21, 0x04, 0x00, 0xd1, 0xc1, 0xff, 0xff, 0xb5, ];
let mut emu = emu_aarch64();
emu.load_code_bytes(&code);
emu.run_to(17).unwrap_or_else(|e| {
panic!(
"run_to(17) failed: {} (pos={} pc=0x{:x})",
e,
emu.pos,
emu.regs_aarch64().pc
);
});
assert!(
emu.pos >= 17,
"expected >= 17 instructions, got pos={}",
emu.pos
);
assert_eq!(
emu.regs_aarch64().x[0],
15,
"x0 should be 15, got {}",
emu.regs_aarch64().x[0]
);
assert_eq!(emu.regs_aarch64().x[1], 0, "x1 should be 0 after loop");
}