diff options
| author | Mason Reed <mason@vector35.com> | 2024-06-28 11:32:21 -0400 |
|---|---|---|
| committer | mason <35282038+emesare@users.noreply.github.com> | 2024-07-01 12:35:51 +0000 |
| commit | c7d90297d41af6c178dbed4b8c389567aa4a4d06 (patch) | |
| tree | bcebdf11d6fa2fac07e558bdece6a823566f2844 /rust/src | |
| parent | 3765f2dce4addd02364af6fb2973ff8eb47a7cd9 (diff) | |
Add LLIL_REG_SPLIT to rust api
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/llil/expression.rs | 34 | ||||
| -rw-r--r-- | rust/src/llil/lifting.rs | 37 | ||||
| -rw-r--r-- | rust/src/llil/operation.rs | 57 |
3 files changed, 128 insertions, 0 deletions
diff --git a/rust/src/llil/expression.rs b/rust/src/llil/expression.rs index d8a3a643..4339787b 100644 --- a/rust/src/llil/expression.rs +++ b/rust/src/llil/expression.rs @@ -136,6 +136,8 @@ where LLIL_ZX => ExprInfo::Zx(Operation::new(function, op)), LLIL_LOW_PART => ExprInfo::LowPart(Operation::new(function, op)), + LLIL_REG_SPLIT => ExprInfo::RegSplit(Operation::new(function, op)), + LLIL_CMP_E => ExprInfo::CmpE(Operation::new(function, op)), LLIL_CMP_NE => ExprInfo::CmpNe(Operation::new(function, op)), LLIL_CMP_SLT => ExprInfo::CmpSlt(Operation::new(function, op)), @@ -273,6 +275,7 @@ where LLIL_LOAD => ExprInfo::Load(Operation::new(self.function, op)), LLIL_POP => ExprInfo::Pop(Operation::new(self.function, op)), LLIL_REG => ExprInfo::Reg(Operation::new(self.function, op)), + LLIL_REG_SPLIT => ExprInfo::RegSplit(Operation::new(self.function, op)), LLIL_FLAG => ExprInfo::Flag(Operation::new(self.function, op)), LLIL_FLAG_BIT => ExprInfo::FlagBit(Operation::new(self.function, op)), LLIL_FLAG_COND => ExprInfo::FlagCond(Operation::new(self.function, op)), // TODO lifted only @@ -327,6 +330,7 @@ where match op.operation { LLIL_LOAD_SSA => ExprInfo::Load(Operation::new(self.function, op)), LLIL_REG_SSA | LLIL_REG_SSA_PARTIAL => ExprInfo::Reg(Operation::new(self.function, op)), + LLIL_REG_SPLIT_SSA => ExprInfo::RegSplit(Operation::new(self.function, op)), LLIL_FLAG_SSA => ExprInfo::Flag(Operation::new(self.function, op)), LLIL_FLAG_BIT_SSA => ExprInfo::FlagBit(Operation::new(self.function, op)), _ => common_info(self.function, op), @@ -383,6 +387,7 @@ where Load(Operation<'func, A, M, F, operation::Load>), Pop(Operation<'func, A, M, F, operation::Pop>), Reg(Operation<'func, A, M, F, operation::Reg>), + RegSplit(Operation<'func, A, M, F, operation::RegSplit>), Const(Operation<'func, A, M, F, operation::Const>), ConstPtr(Operation<'func, A, M, F, operation::Const>), Flag(Operation<'func, A, M, F, operation::Flag>), @@ -595,6 +600,8 @@ where Reg(ref op) => &op.op, + RegSplit(ref op) => &op.op, + Flag(ref op) => &op.op, FlagBit(ref op) => &op.op, @@ -648,6 +655,8 @@ where Reg(ref op) => op.flag_write(), + RegSplit(ref op) => op.flag_write(), + Flag(ref op) => op.flag_write(), FlagBit(ref op) => op.flag_write(), @@ -735,6 +744,31 @@ where } } + RegSplit(ref op) => { + let low_reg = op.low_reg(); + let high_reg = op.high_reg(); + let size = op.size(); + + let low_size = match low_reg { + Register::Temp(_) => Some(size), + Register::ArchReg(ref r) if r.info().size() != size => Some(size), + _ => None, + }; + + let high_size = match high_reg { + Register::Temp(_) => Some(size), + Register::ArchReg(ref r) if r.info().size() != size => Some(size), + _ => None, + }; + + match (low_size, high_size) { + (Some(ls), Some(hs)) => write!(f, "{:?}.{}:{:?}.{}", high_reg, hs, low_reg, ls), + (Some(ls), None) => write!(f, "{:?}:{:?}.{}", high_reg, low_reg, ls), + (None, Some(hs)) => write!(f, "{:?}.{}:{:?}", high_reg, hs, low_reg), + _ => write!(f, "{:?}:{:?}", high_reg, low_reg), + } + } + Flag(ref _op) => write!(f, "flag"), // TODO FlagBit(ref _op) => write!(f, "flag_bit"), // TODO diff --git a/rust/src/llil/lifting.rs b/rust/src/llil/lifting.rs index daf95ac3..e6226070 100644 --- a/rust/src/llil/lifting.rs +++ b/rust/src/llil/lifting.rs @@ -1016,6 +1016,43 @@ where Expression::new(self, expr_idx) } + pub fn reg_split<H: Into<Register<A::Register>>, L: Into<Register<A::Register>>>( + &self, + size: usize, + hi_reg: H, + lo_reg: L, + ) -> Expression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + use binaryninjacore_sys::BNLowLevelILAddExpr; + use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG_SPLIT; + + // TODO verify valid id + let hi_reg = match hi_reg.into() { + Register::ArchReg(r) => r.id(), + Register::Temp(r) => 0x8000_0000 | r, + }; + + // TODO verify valid id + let lo_reg = match lo_reg.into() { + Register::ArchReg(r) => r.id(), + Register::Temp(r) => 0x8000_0000 | r, + }; + + let expr_idx = unsafe { + BNLowLevelILAddExpr( + self.handle, + LLIL_REG_SPLIT, + size, + 0, + hi_reg as u64, + lo_reg as u64, + 0, + 0, + ) + }; + + Expression::new(self, expr_idx) + } + pub fn set_reg<'a, R, E>( &'a self, size: usize, diff --git a/rust/src/llil/operation.rs b/rust/src/llil/operation.rs index dfcfbc17..f42b3693 100644 --- a/rust/src/llil/operation.rs +++ b/rust/src/llil/operation.rs @@ -290,6 +290,62 @@ where } } +// LLIL_REG_SPLIT +pub struct RegSplit; + +impl<'func, A, M, V> Operation<'func, A, M, NonSSA<V>, RegSplit> + where + A: 'func + Architecture, + M: FunctionMutability, + V: NonSSAVariant, +{ + pub fn size(&self) -> usize { + self.op.size + } + + pub fn low_reg(&self) -> Register<A::Register> { + let raw_id = self.op.operands[0] as u32; + + if raw_id >= 0x8000_0000 { + Register::Temp(raw_id & 0x7fff_ffff) + } else { + self.function + .arch() + .register_from_id(raw_id) + .map(Register::ArchReg) + .unwrap_or_else(|| { + error!( + "got garbage register from LLIL_REG @ 0x{:x}", + self.op.address + ); + + Register::Temp(0) + }) + } + } + + pub fn high_reg(&self) -> Register<A::Register> { + let raw_id = self.op.operands[1] as u32; + + if raw_id >= 0x8000_0000 { + Register::Temp(raw_id & 0x7fff_ffff) + } else { + self.function + .arch() + .register_from_id(raw_id) + .map(Register::ArchReg) + .unwrap_or_else(|| { + error!( + "got garbage register from LLIL_REG @ 0x{:x}", + self.op.address + ); + + Register::Temp(0) + }) + } + } +} + // LLIL_FLAG, LLIL_FLAG_SSA pub struct Flag; @@ -702,6 +758,7 @@ impl OperationArguments for SetFlag {} impl OperationArguments for Load {} impl OperationArguments for Store {} impl OperationArguments for Reg {} +impl OperationArguments for RegSplit {} impl OperationArguments for Flag {} impl OperationArguments for FlagBit {} impl OperationArguments for Jump {} |
