summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2023-11-09 18:39:55 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2023-12-06 13:48:37 -0500
commite9604c37df479a991d131d9540fafe78c7a0f7d4 (patch)
treed1ac45fbc0da8dbfd3d09fec0625d11a5cfbc69e /rust/src
parent6e1a863a4b20d73610e88cb7d9adf676c1053fce (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.rs12
-rw-r--r--rust/src/mlil/lift.rs2
-rw-r--r--rust/src/mlil/operation.rs118
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 {