balrog~ ELF file analysis tool to be used after firmware extraction |
| git clone https://github.com/djnnvx/balrog.git |
| log | files | refs | archive | README |
arm.rs (2681B)
1 use super::{imm, mem, reg, Kind, Op, HIGH_HALF_SHIFT, IMM16_MASK}; 2 use crate::load::Binary; 3 use capstone::arch::arm::ArmReg; 4 5 const PC_BIAS: u64 = 8; 6 const WORD: usize = 4; 7 8 pub const ARG_REGS: [u16; 4] = [ 9 ArmReg::ARM_REG_R0 as u16, 10 ArmReg::ARM_REG_R1 as u16, 11 ArmReg::ARM_REG_R2 as u16, 12 ArmReg::ARM_REG_R3 as u16, 13 ]; 14 15 pub const SP: u16 = ArmReg::ARM_REG_SP as u16; 16 17 fn pc_relative(addr: u64, disp: i64) -> u64 { 18 addr.wrapping_add(PC_BIAS).wrapping_add(disp as u64) 19 } 20 21 fn literal(addr: u64, disp: i64, bin: &Binary) -> Option<u64> { 22 let pool = pc_relative(addr, disp); 23 let word: [u8; WORD] = bin.read_vaddr(pool, WORD)?.try_into().ok()?; 24 Some(if bin.little { 25 u32::from_le_bytes(word) as u64 26 } else { 27 u32::from_be_bytes(word) as u64 28 }) 29 } 30 31 pub fn decode(mnemonic: &str, o: &[Op; 3], addr: u64, bin: &Binary) -> Option<Kind> { 32 match mnemonic { 33 "bl" | "blx" => match o[0] { 34 Op::Imm(target) => Some(Kind::Call(target as u64)), 35 Op::Reg(r) => Some(Kind::CallInd { reg: r }), 36 _ => None, 37 }, 38 "bx" => Some(Kind::Ret), 39 "movw" => { 40 let low_half = (imm(o, 1)? as u64) & IMM16_MASK; 41 Some(Kind::SetConst { 42 dst: reg(o, 0)?, 43 val: low_half, 44 }) 45 } 46 "movt" => { 47 let high_half = ((imm(o, 1)? as u64) << HIGH_HALF_SHIFT) as i64; 48 Some(Kind::AddImm { 49 dst: reg(o, 0)?, 50 base: reg(o, 0)?, 51 imm: high_half, 52 }) 53 } 54 "ldr" => { 55 let (base, disp) = mem(o, 1)?; 56 let dst = reg(o, 0)?; 57 if base == ArmReg::ARM_REG_PC as u16 { 58 Some(Kind::PcVal { 59 dst, 60 val: literal(addr, disp, bin)?, 61 }) 62 } else { 63 Some(Kind::Load { dst, base, disp }) 64 } 65 } 66 "add" => { 67 let (dst, base) = (reg(o, 0)?, reg(o, 1)?); 68 if base == ArmReg::ARM_REG_PC as u16 { 69 Some(Kind::SetConst { 70 dst, 71 val: pc_relative(addr, imm(o, 2)?), 72 }) 73 } else { 74 Some(Kind::AddImm { 75 dst, 76 base, 77 imm: imm(o, 2)?, 78 }) 79 } 80 } 81 "sub" => Some(Kind::AddImm { 82 dst: reg(o, 0)?, 83 base: reg(o, 1)?, 84 imm: -imm(o, 2)?, 85 }), 86 "mov" => Some(Kind::Mov { 87 dst: reg(o, 0)?, 88 src: reg(o, 1)?, 89 }), 90 _ => None, 91 } 92 }