diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2023-11-09 18:39:55 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2023-12-06 13:48:37 -0500 |
| commit | e9604c37df479a991d131d9540fafe78c7a0f7d4 (patch) | |
| tree | d1ac45fbc0da8dbfd3d09fec0625d11a5cfbc69e /rust/src | |
| parent | 6e1a863a4b20d73610e88cb7d9adf676c1053fce (diff) | |
Add LLIL/MLIL instructions to describe integer vs. floating point argument usage
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/mlil/instruction.rs | 12 | ||||
| -rw-r--r-- | rust/src/mlil/lift.rs | 2 | ||||
| -rw-r--r-- | rust/src/mlil/operation.rs | 118 |
3 files changed, 112 insertions, 20 deletions
diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs index 5e237128..139abe20 100644 --- a/rust/src/mlil/instruction.rs +++ b/rust/src/mlil/instruction.rs @@ -113,6 +113,8 @@ pub enum MediumLevelILOperation { CallUntyped(CallUntyped), TailcallUntyped(CallUntyped), SyscallUntyped(SyscallUntyped), + SeparateParamList(SeparateParamList), + SharedParamSlot(SharedParamSlot), Neg(UnaryOp), Not(UnaryOp), Sx(UnaryOp), @@ -535,6 +537,12 @@ impl MediumLevelILInstruction { op.operands[1] as usize, op.operands[2] as usize, )), + MLIL_SEPARATE_PARAM_LIST => Op::SeparateParamList(SeparateParamList::new( + (op.operands[0] as usize, op.operands[1] as usize) + )), + MLIL_SHARED_PARAM_SLOT => Op::SharedParamSlot(SharedParamSlot::new( + (op.operands[0] as usize, op.operands[1] as usize) + )), MLIL_NEG => Op::Neg(UnaryOp::new(op.operands[0] as usize)), MLIL_NOT => Op::Not(UnaryOp::new(op.operands[0] as usize)), MLIL_SX => Op::Sx(UnaryOp::new(op.operands[0] as usize)), @@ -706,6 +714,8 @@ impl MediumLevelILInstruction { CallUntyped(op) => Lifted::CallUntyped(op.lift(&self.function)), TailcallUntyped(op) => Lifted::TailcallUntyped(op.lift(&self.function)), SyscallUntyped(op) => Lifted::SyscallUntyped(op.lift(&self.function)), + SeparateParamList(op) => Lifted::SeparateParamList(op.lift(&self.function)), + SharedParamSlot(op) => Lifted::SharedParamSlot(op.lift(&self.function)), Neg(op) => Lifted::Neg(op.lift(&self.function)), Not(op) => Lifted::Not(op.lift(&self.function)), Sx(op) => Lifted::Sx(op.lift(&self.function)), @@ -793,6 +803,8 @@ impl MediumLevelILInstruction { SyscallUntypedSsa(op) => Box::new(op.operands(&self.function)), CallUntyped(op) | TailcallUntyped(op) => Box::new(op.operands(&self.function)), SyscallUntyped(op) => Box::new(op.operands(&self.function)), + SeparateParamList(op) => Box::new(op.operands(&self.function)), + SharedParamSlot(op) => Box::new(op.operands(&self.function)), Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) | Load(op) => { diff --git a/rust/src/mlil/lift.rs b/rust/src/mlil/lift.rs index 68a7884e..fc996cb4 100644 --- a/rust/src/mlil/lift.rs +++ b/rust/src/mlil/lift.rs @@ -105,6 +105,8 @@ pub enum MediumLevelILLiftedOperation { CallUntyped(LiftedCallUntyped), TailcallUntyped(LiftedCallUntyped), SyscallUntyped(LiftedSyscallUntyped), + SeparateParamList(LiftedSeparateParamList), + SharedParamSlot(LiftedSharedParamSlot), Neg(LiftedUnaryOp), Not(LiftedUnaryOp), Sx(LiftedUnaryOp), diff --git a/rust/src/mlil/operation.rs b/rust/src/mlil/operation.rs index cdff02b2..880155e3 100644 --- a/rust/src/mlil/operation.rs +++ b/rust/src/mlil/operation.rs @@ -252,12 +252,22 @@ fn get_call_list( OperandList::new(function, op.operands[1] as usize, op.operands[0] as usize).map_var() } +fn get_call_exprs( + function: &MediumLevelILFunction, + op_type: BNMediumLevelILOperation, + idx: usize, +) -> OperandExprList { + let op = unsafe { BNGetMediumLevelILByIndex(function.handle, idx) }; + assert_eq!(op.operation, op_type); + OperandList::new(function, op.operands[1] as usize, op.operands[0] as usize).map_expr() +} + fn get_call_output(function: &MediumLevelILFunction, idx: usize) -> OperandVariableList { get_call_list(function, BNMediumLevelILOperation::MLIL_CALL_OUTPUT, idx) } -fn get_call_params(function: &MediumLevelILFunction, idx: usize) -> OperandVariableList { - get_call_list(function, BNMediumLevelILOperation::MLIL_CALL_PARAM, idx) +fn get_call_params(function: &MediumLevelILFunction, idx: usize) -> OperandExprList { + get_call_exprs(function, BNMediumLevelILOperation::MLIL_CALL_PARAM, idx) } fn get_call_list_ssa( @@ -270,6 +280,16 @@ fn get_call_list_ssa( OperandList::new(function, op.operands[2] as usize, op.operands[1] as usize).map_ssa_var() } +fn get_call_exprs_ssa( + function: &MediumLevelILFunction, + op_type: BNMediumLevelILOperation, + idx: usize, +) -> OperandExprList { + let op = get_raw_operation(function, idx); + assert_eq!(op.operation, op_type); + OperandList::new(function, op.operands[2] as usize, op.operands[1] as usize).map_expr() +} + fn get_call_output_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandSSAVariableList { get_call_list_ssa( function, @@ -278,8 +298,8 @@ fn get_call_output_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandS ) } -fn get_call_params_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandSSAVariableList { - get_call_list_ssa(function, BNMediumLevelILOperation::MLIL_CALL_PARAM_SSA, idx) +fn get_call_params_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandExprList { + get_call_exprs_ssa(function, BNMediumLevelILOperation::MLIL_CALL_PARAM_SSA, idx) } // NOP, NORET, BP, UNDEF, UNIMPL @@ -1605,7 +1625,7 @@ pub struct CallUntypedSsa { pub struct LiftedCallUntypedSsa { pub output: Vec<SSAVariable>, pub dest: Box<MediumLevelILLiftedInstruction>, - pub params: Vec<SSAVariable>, + pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } impl CallUntypedSsa { @@ -1623,7 +1643,7 @@ impl CallUntypedSsa { pub fn dest(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { get_operation(function, self.dest) } - pub fn params(&self, function: &MediumLevelILFunction) -> OperandSSAVariableList { + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { get_call_params_ssa(function, self.params) } pub fn stack(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { @@ -1633,7 +1653,7 @@ impl CallUntypedSsa { LiftedCallUntypedSsa { output: self.output(function).collect(), dest: Box::new(self.dest(function).lift()), - params: self.params(function).collect(), + params: self.params(function).map(|instr| instr.lift()).collect(), stack: Box::new(self.stack(function).lift()), } } @@ -1645,7 +1665,7 @@ impl CallUntypedSsa { [ ("output", VarSsaList(self.output(function))), ("dest", Expr(self.dest(function))), - ("params", VarSsaList(self.params(function))), + ("params", ExprList(self.params(function))), ("stack", Expr(self.stack(function))), ] .into_iter() @@ -1713,7 +1733,7 @@ pub struct SyscallUntypedSsa { #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntypedSsa { pub output: Vec<SSAVariable>, - pub params: Vec<SSAVariable>, + pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } impl SyscallUntypedSsa { @@ -1727,7 +1747,7 @@ impl SyscallUntypedSsa { pub fn output(&self, function: &MediumLevelILFunction) -> OperandSSAVariableList { get_call_output_ssa(function, self.output) } - pub fn params(&self, function: &MediumLevelILFunction) -> OperandSSAVariableList { + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { get_call_params_ssa(function, self.params) } pub fn stack(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { @@ -1736,7 +1756,7 @@ impl SyscallUntypedSsa { pub fn lift(&self, function: &MediumLevelILFunction) -> LiftedSyscallUntypedSsa { LiftedSyscallUntypedSsa { output: self.output(function).collect(), - params: self.params(function).collect(), + params: self.params(function).map(|instr| instr.lift()).collect(), stack: Box::new(self.stack(function).lift()), } } @@ -1747,7 +1767,7 @@ impl SyscallUntypedSsa { use MediumLevelILOperand::*; [ ("output", VarSsaList(self.output(function))), - ("params", VarSsaList(self.params(function))), + ("params", ExprList(self.params(function))), ("stack", Expr(self.stack(function))), ] .into_iter() @@ -1766,7 +1786,7 @@ pub struct CallUntyped { pub struct LiftedCallUntyped { pub output: Vec<Variable>, pub dest: Box<MediumLevelILLiftedInstruction>, - pub params: Vec<Variable>, + pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } impl CallUntyped { @@ -1784,7 +1804,7 @@ impl CallUntyped { pub fn dest(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { get_operation(function, self.dest) } - pub fn params(&self, function: &MediumLevelILFunction) -> OperandVariableList { + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { get_call_params(function, self.params) } pub fn stack(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { @@ -1794,7 +1814,7 @@ impl CallUntyped { LiftedCallUntyped { output: self.output(function).collect(), dest: Box::new(self.dest(function).lift()), - params: self.params(function).collect(), + params: self.params(function).map(|instr| instr.lift()).collect(), stack: Box::new(self.stack(function).lift()), } } @@ -1806,7 +1826,7 @@ impl CallUntyped { [ ("output", VarList(self.output(function))), ("dest", Expr(self.dest(function))), - ("params", VarList(self.params(function))), + ("params", ExprList(self.params(function))), ("stack", Expr(self.stack(function))), ] .into_iter() @@ -1823,7 +1843,7 @@ pub struct SyscallUntyped { #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntyped { pub output: Vec<Variable>, - pub params: Vec<Variable>, + pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } impl SyscallUntyped { @@ -1837,7 +1857,7 @@ impl SyscallUntyped { pub fn output(&self, function: &MediumLevelILFunction) -> OperandVariableList { get_call_output(function, self.output) } - pub fn params(&self, function: &MediumLevelILFunction) -> OperandVariableList { + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { get_call_params(function, self.params) } pub fn stack(&self, function: &MediumLevelILFunction) -> MediumLevelILInstruction { @@ -1846,7 +1866,7 @@ impl SyscallUntyped { pub fn lift(&self, function: &MediumLevelILFunction) -> LiftedSyscallUntyped { LiftedSyscallUntyped { output: self.output(function).collect(), - params: self.params(function).collect(), + params: self.params(function).map(|instr| instr.lift()).collect(), stack: Box::new(self.stack(function).lift()), } } @@ -1857,7 +1877,7 @@ impl SyscallUntyped { use MediumLevelILOperand::*; [ ("output", VarList(self.output(function))), - ("params", VarList(self.params(function))), + ("params", ExprList(self.params(function))), ("stack", Expr(self.stack(function))), ] .into_iter() @@ -2050,6 +2070,64 @@ impl Ret { } } +// SEPARATE_PARAM_LIST +#[derive(Copy, Clone)] +pub struct SeparateParamList { + params: (usize, usize), +} +#[derive(Clone, Debug, PartialEq)] +pub struct LiftedSeparateParamList { + pub params: Vec<MediumLevelILLiftedInstruction>, +} +impl SeparateParamList { + pub fn new(params: (usize, usize)) -> Self { + Self { params } + } + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { + OperandList::new(function, self.params.1, self.params.0).map_expr() + } + pub fn lift(&self, function: &MediumLevelILFunction) -> LiftedSeparateParamList { + LiftedSeparateParamList { + params: self.params(function).map(|instr| instr.lift()).collect(), + } + } + pub fn operands( + &self, + function: &MediumLevelILFunction, + ) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> { + [("params", MediumLevelILOperand::ExprList(self.params(function)))].into_iter() + } +} + +// SHARED_PARAM_SLOT +#[derive(Copy, Clone)] +pub struct SharedParamSlot { + params: (usize, usize), +} +#[derive(Clone, Debug, PartialEq)] +pub struct LiftedSharedParamSlot { + pub params: Vec<MediumLevelILLiftedInstruction>, +} +impl SharedParamSlot { + pub fn new(params: (usize, usize)) -> Self { + Self { params } + } + pub fn params(&self, function: &MediumLevelILFunction) -> OperandExprList { + OperandList::new(function, self.params.1, self.params.0).map_expr() + } + pub fn lift(&self, function: &MediumLevelILFunction) -> LiftedSharedParamSlot { + LiftedSharedParamSlot { + params: self.params(function).map(|instr| instr.lift()).collect(), + } + } + pub fn operands( + &self, + function: &MediumLevelILFunction, + ) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> { + [("params", MediumLevelILOperand::ExprList(self.params(function)))].into_iter() + } +} + // VAR, ADDRESS_OF #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Var { |
