diff options
| author | Mason Reed <mason@vector35.com> | 2025-01-31 13:02:22 -0500 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-01-31 16:17:30 -0500 |
| commit | f5b7f5b2779b1b29e14856efd2a2e56a7c3b0113 (patch) | |
| tree | b1722f62166390c0d4b245a6695e359652ec6cf5 /rust | |
| parent | c00727ed11624018b286f57215a677b1140de2ff (diff) | |
Add LLIL_REG_STACK_POP and LLIL_REG_STACK_PUSH to Rust API
These were unhandled and x87 register stack LLIL would emit a bunch of warnings
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/src/architecture.rs | 4 | ||||
| -rw-r--r-- | rust/src/low_level_il/expression.rs | 13 | ||||
| -rw-r--r-- | rust/src/low_level_il/instruction.rs | 7 | ||||
| -rw-r--r-- | rust/src/low_level_il/operation.rs | 86 |
4 files changed, 106 insertions, 4 deletions
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 857a6e88..997089f8 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -305,7 +305,7 @@ pub trait RegisterStackInfo: Sized { fn stack_top_reg(&self) -> Self::RegType; } -pub trait RegisterStack: Sized + Clone + Copy { +pub trait RegisterStack: Debug + Sized + Clone + Copy { type InfoType: RegisterStackInfo< RegType = Self::RegType, RegInfoType = Self::RegInfoType, @@ -641,7 +641,7 @@ pub struct UnusedRegisterStackInfo<R: Register> { _reg: std::marker::PhantomData<R>, } -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UnusedRegisterStack<R: Register> { _reg: std::marker::PhantomData<R>, } diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs index 2fc9f93d..7bae22c1 100644 --- a/rust/src/low_level_il/expression.rs +++ b/rust/src/low_level_il/expression.rs @@ -236,6 +236,8 @@ where FlagBit(Operation<'func, A, M, F, operation::FlagBit>), ExternPtr(Operation<'func, A, M, F, operation::Extern>), + RegStackPop(Operation<'func, A, M, F, operation::RegStackPop>), + Add(Operation<'func, A, M, F, operation::BinaryOp>), Adc(Operation<'func, A, M, F, operation::BinaryOpCarry>), Sub(Operation<'func, A, M, F, operation::BinaryOp>), @@ -357,6 +359,10 @@ where } LLIL_EXTERN_PTR => LowLevelILExpressionKind::ExternPtr(Operation::new(function, op)), + LLIL_REG_STACK_POP => { + LowLevelILExpressionKind::RegStackPop(Operation::new(function, op)) + } + LLIL_ADD => LowLevelILExpressionKind::Add(Operation::new(function, op)), LLIL_ADC => LowLevelILExpressionKind::Adc(Operation::new(function, op)), LLIL_SUB => LowLevelILExpressionKind::Sub(Operation::new(function, op)), @@ -597,7 +603,8 @@ where } // Do not have any sub expressions. Pop(_) | Reg(_) | RegSplit(_) | Const(_) | ConstPtr(_) | Flag(_) | FlagBit(_) - | ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) => {} + | ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) | RegStackPop(_) => { + } } VisitorAction::Sibling @@ -635,6 +642,8 @@ where ExternPtr(ref op) => &op.op, + RegStackPop(ref op) => &op.op, + Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => &op.op, Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op) @@ -692,6 +701,8 @@ where ExternPtr(ref op) => op.flag_write(), + RegStackPop(ref op) => op.flag_write(), + Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => op.flag_write(), Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op) diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs index 5c3010ea..b023ad49 100644 --- a/rust/src/low_level_il/instruction.rs +++ b/rust/src/low_level_il/instruction.rs @@ -227,6 +227,8 @@ where // TODO needs a real op Push(Operation<'func, A, M, F, operation::UnaryOp>), + RegStackPush(Operation<'func, A, M, F, operation::RegStackPush>), + Jump(Operation<'func, A, M, F, operation::Jump>), JumpTo(Operation<'func, A, M, F, operation::JumpTo>), @@ -278,6 +280,10 @@ where } LLIL_PUSH => LowLevelILInstructionKind::Push(Operation::new(function, op)), + LLIL_REG_STACK_PUSH => { + LowLevelILInstructionKind::RegStackPush(Operation::new(function, op)) + } + LLIL_JUMP => LowLevelILInstructionKind::Jump(Operation::new(function, op)), LLIL_JUMP_TO => LowLevelILInstructionKind::JumpTo(Operation::new(function, op)), @@ -330,6 +336,7 @@ where visit!(&op.source_expr()); } Push(ref op) => visit!(&op.operand()), + RegStackPush(ref op) => visit!(&op.source_expr()), Jump(ref op) => visit!(&op.target()), JumpTo(ref op) => visit!(&op.target()), Call(ref op) | TailCall(ref op) => visit!(&op.target()), diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index dcc761dd..46d99a97 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -15,7 +15,7 @@ use binaryninjacore_sys::{BNGetLowLevelILByIndex, BNLowLevelILInstruction}; use super::*; -use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId}; +use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId}; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; use std::marker::PhantomData; @@ -537,6 +537,88 @@ where } } +// LLIL_REG_STACK_PUSH +pub struct RegStackPush; + +impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPush> +where + A: Architecture, + M: FunctionMutability, + F: FunctionForm, +{ + pub fn size(&self) -> usize { + self.op.size + } + + pub fn dest_reg_stack(&self) -> A::RegisterStack { + let raw_id = self.op.operands[0] as u32; + self.function + .arch() + .register_stack_from_id(RegisterStackId(raw_id)) + .expect("Bad register stack ID") + } + + pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + LowLevelILExpression::new( + self.function, + LowLevelExpressionIndex(self.op.operands[1] as usize), + ) + } +} + +impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPush> +where + A: Architecture, + M: FunctionMutability, + F: FunctionForm, +{ + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("RegStackPush") + .field("address", &self.address()) + .field("size", &self.size()) + .field("dest_reg_stack", &self.dest_reg_stack()) + .field("source_expr", &self.source_expr()) + .finish() + } +} + +// LLIL_REG_STACK_POP +pub struct RegStackPop; + +impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPop> +where + A: Architecture, + M: FunctionMutability, + F: FunctionForm, +{ + pub fn size(&self) -> usize { + self.op.size + } + + pub fn source_reg_stack(&self) -> A::RegisterStack { + let raw_id = self.op.operands[0] as u32; + self.function + .arch() + .register_stack_from_id(RegisterStackId(raw_id)) + .expect("Bad register stack ID") + } +} + +impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPop> +where + A: Architecture, + M: FunctionMutability, + F: FunctionForm, +{ + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("RegStackPop") + .field("address", &self.address()) + .field("size", &self.size()) + .field("source_reg_stack", &self.source_reg_stack()) + .finish() + } +} + // LLIL_FLAG, LLIL_FLAG_SSA pub struct Flag; @@ -1343,6 +1425,8 @@ impl OperationArguments for Load {} impl OperationArguments for Store {} impl OperationArguments for Reg {} impl OperationArguments for RegSplit {} +impl OperationArguments for RegStackPush {} +impl OperationArguments for RegStackPop {} impl OperationArguments for Flag {} impl OperationArguments for FlagBit {} impl OperationArguments for Jump {} |
