update
This commit is contained in:
@@ -21,7 +21,7 @@ impl Iterator for MediumLevelILBlockIter {
|
||||
.map(|i| unsafe {
|
||||
BNGetMediumLevelILIndexForInstruction(self.function.handle, i as usize)
|
||||
})
|
||||
.map(|i| MediumLevelILInstruction::new(&self.function, i))
|
||||
.map(|i| MediumLevelILInstruction::new(self.function.to_owned(), i))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl BlockContext for MediumLevelILBlock {
|
||||
let expr_idx = unsafe {
|
||||
BNGetMediumLevelILIndexForInstruction(self.function.handle, block.raw_start() as usize)
|
||||
};
|
||||
MediumLevelILInstruction::new(&self.function, expr_idx)
|
||||
MediumLevelILInstruction::new(self.function.to_owned(), expr_idx)
|
||||
}
|
||||
|
||||
fn iter(&self, block: &BasicBlock<Self>) -> MediumLevelILBlockIter {
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::function::Function;
|
||||
use crate::function::Location;
|
||||
use crate::rc::{Array, Ref, RefCountable};
|
||||
|
||||
use super::{MediumLevelILBlock, MediumLevelILInstruction};
|
||||
use super::{MediumLevelILBlock, MediumLevelILInstruction, MediumLevelILLiftedInstruction};
|
||||
|
||||
pub struct MediumLevelILFunction {
|
||||
pub(crate) handle: *mut BNMediumLevelILFunction,
|
||||
@@ -26,21 +26,21 @@ unsafe impl Sync for MediumLevelILFunction {}
|
||||
impl Eq for MediumLevelILFunction {}
|
||||
impl PartialEq for MediumLevelILFunction {
|
||||
fn eq(&self, rhs: &Self) -> bool {
|
||||
self.handle == rhs.handle
|
||||
self.get_function().eq(&rhs.get_function())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for MediumLevelILFunction {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.handle.hash(state);
|
||||
self.get_function().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl MediumLevelILFunction {
|
||||
pub(crate) unsafe fn from_raw(handle: *mut BNMediumLevelILFunction) -> Self {
|
||||
pub(crate) unsafe fn ref_from_raw(handle: *mut BNMediumLevelILFunction) -> Ref<Self> {
|
||||
debug_assert!(!handle.is_null());
|
||||
|
||||
Self { handle }
|
||||
Self { handle }.to_owned()
|
||||
}
|
||||
|
||||
pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<MediumLevelILInstruction> {
|
||||
@@ -53,12 +53,16 @@ impl MediumLevelILFunction {
|
||||
if expr_idx >= self.instruction_count() {
|
||||
None
|
||||
} else {
|
||||
Some(MediumLevelILInstruction::new(self, expr_idx))
|
||||
Some(MediumLevelILInstruction::new(self.to_owned(), expr_idx))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instruction_from_idx(&self, expr_idx: usize) -> MediumLevelILInstruction {
|
||||
MediumLevelILInstruction::new(self, expr_idx)
|
||||
MediumLevelILInstruction::new(self.to_owned(), expr_idx)
|
||||
}
|
||||
|
||||
pub fn lifted_instruction_from_idx(&self, expr_idx: usize) -> MediumLevelILLiftedInstruction {
|
||||
self.instruction_from_idx(expr_idx).lift()
|
||||
}
|
||||
|
||||
pub fn instruction_count(&self) -> usize {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
258
src/mlil/lift.rs
258
src/mlil/lift.rs
@@ -1,25 +1,48 @@
|
||||
use super::operation::*;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MediumLevelILLiftedInstruction {
|
||||
pub address: u64,
|
||||
pub operation: MediumLevelILLiftedOperation,
|
||||
use crate::rc::Ref;
|
||||
use crate::types::{ConstantData, ILIntrinsic, SSAVariable, Variable};
|
||||
|
||||
use super::operation::*;
|
||||
use super::MediumLevelILFunction;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum MediumLevelILLiftedOperand {
|
||||
ConstantData(ConstantData),
|
||||
Intrinsic(ILIntrinsic),
|
||||
Expr(MediumLevelILLiftedInstruction),
|
||||
ExprList(Vec<MediumLevelILLiftedInstruction>),
|
||||
Float(f64),
|
||||
Int(u64),
|
||||
IntList(Vec<u64>),
|
||||
TargetMap(BTreeMap<u64, u64>),
|
||||
Var(Variable),
|
||||
VarList(Vec<Variable>),
|
||||
VarSsa(SSAVariable),
|
||||
VarSsaList(Vec<SSAVariable>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MediumLevelILLiftedOperation {
|
||||
Nop(NoArgs),
|
||||
Noret(NoArgs),
|
||||
Bp(NoArgs),
|
||||
Undef(NoArgs),
|
||||
Unimpl(NoArgs),
|
||||
pub struct MediumLevelILLiftedInstruction {
|
||||
pub function: Ref<MediumLevelILFunction>,
|
||||
pub address: u64,
|
||||
pub kind: MediumLevelILLiftedInstructionKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MediumLevelILLiftedInstructionKind {
|
||||
Nop,
|
||||
Noret,
|
||||
Bp,
|
||||
Undef,
|
||||
Unimpl,
|
||||
If(LiftedIf),
|
||||
FloatConst(FloatConst),
|
||||
Const(Constant),
|
||||
ConstPtr(Constant),
|
||||
Import(Constant),
|
||||
ExternPtr(ExternPtr),
|
||||
ConstData(ConstantData),
|
||||
ConstData(LiftedConstData),
|
||||
Jump(LiftedJump),
|
||||
RetHint(LiftedJump),
|
||||
StoreSsa(LiftedStoreSsa),
|
||||
@@ -93,8 +116,8 @@ pub enum MediumLevelILLiftedOperation {
|
||||
Rrc(LiftedBinaryOpCarry),
|
||||
Call(LiftedCall),
|
||||
Tailcall(LiftedCall),
|
||||
Intrinsic(LiftedInnerCall),
|
||||
Syscall(LiftedInnerCall),
|
||||
Intrinsic(LiftedIntrinsic),
|
||||
Syscall(LiftedSyscallCall),
|
||||
IntrinsicSsa(LiftedIntrinsicSsa),
|
||||
CallSsa(LiftedCallSsa),
|
||||
TailcallSsa(LiftedCallSsa),
|
||||
@@ -139,3 +162,210 @@ pub enum MediumLevelILLiftedOperation {
|
||||
VarAliasedField(VarSsaField),
|
||||
Trap(Trap),
|
||||
}
|
||||
|
||||
impl MediumLevelILLiftedInstruction {
|
||||
pub fn operands(&self) -> Vec<(&'static str, MediumLevelILLiftedOperand)> {
|
||||
use MediumLevelILLiftedInstructionKind::*;
|
||||
use MediumLevelILLiftedOperand as Operand;
|
||||
match &self.kind {
|
||||
Nop | Noret | Bp | Undef | Unimpl => vec![],
|
||||
If(op) => vec![
|
||||
("condition", Operand::Expr(*op.condition.clone())),
|
||||
("dest_true", Operand::Int(op.dest_true)),
|
||||
("dest_false", Operand::Int(op.dest_false)),
|
||||
],
|
||||
FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
|
||||
Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
|
||||
ExternPtr(op) => vec![
|
||||
("constant", Operand::Int(op.constant)),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
],
|
||||
ConstData(op) => vec![(
|
||||
"constant_data",
|
||||
Operand::ConstantData(op.constant_data.clone()),
|
||||
)],
|
||||
Jump(op) | RetHint(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
|
||||
StoreSsa(op) => vec![
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("dest_memory", Operand::Int(op.dest_memory)),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
StoreStructSsa(op) => vec![
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
("dest_memory", Operand::Int(op.dest_memory)),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
StoreStruct(op) => vec![
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
Store(op) => vec![
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
JumpTo(op) => vec![
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("targets", Operand::TargetMap(op.targets.clone())),
|
||||
],
|
||||
Goto(op) => vec![("dest", Operand::Int(op.dest))],
|
||||
FreeVarSlot(op) => vec![("dest", Operand::Var(op.dest))],
|
||||
SetVarField(op) => vec![
|
||||
("dest", Operand::Var(op.dest)),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
SetVar(op) => vec![
|
||||
("dest", Operand::Var(op.dest)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
FreeVarSlotSsa(op) => vec![
|
||||
("dest", Operand::VarSsa(op.dest)),
|
||||
("prev", Operand::VarSsa(op.prev)),
|
||||
],
|
||||
SetVarSsaField(op) | SetVarAliasedField(op) => vec![
|
||||
("dest", Operand::VarSsa(op.dest)),
|
||||
("prev", Operand::VarSsa(op.prev)),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
SetVarAliased(op) => vec![
|
||||
("dest", Operand::VarSsa(op.dest)),
|
||||
("prev", Operand::VarSsa(op.prev)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
SetVarSsa(op) => vec![
|
||||
("dest", Operand::VarSsa(op.dest)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
VarPhi(op) => vec![
|
||||
("dest", Operand::VarSsa(op.dest)),
|
||||
("src", Operand::VarSsaList(op.src.clone())),
|
||||
],
|
||||
MemPhi(op) => vec![
|
||||
("dest_memory", Operand::Int(op.dest_memory)),
|
||||
("src_memory", Operand::IntList(op.src_memory.clone())),
|
||||
],
|
||||
VarSplit(op) => vec![
|
||||
("high", Operand::Var(op.high)),
|
||||
("low", Operand::Var(op.low)),
|
||||
],
|
||||
SetVarSplit(op) => vec![
|
||||
("high", Operand::Var(op.high)),
|
||||
("low", Operand::Var(op.low)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
VarSplitSsa(op) => vec![
|
||||
("high", Operand::VarSsa(op.high)),
|
||||
("low", Operand::VarSsa(op.low)),
|
||||
],
|
||||
SetVarSplitSsa(op) => vec![
|
||||
("high", Operand::VarSsa(op.high)),
|
||||
("low", Operand::VarSsa(op.low)),
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
],
|
||||
Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
|
||||
| Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
|
||||
| Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
|
||||
| CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
|
||||
| CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | FcmpE(op)
|
||||
| FcmpNe(op) | FcmpLt(op) | FcmpLe(op) | FcmpGe(op) | FcmpGt(op) | FcmpO(op)
|
||||
| FcmpUo(op) | Fadd(op) | Fsub(op) | Fmul(op) | Fdiv(op) => vec![
|
||||
("left", Operand::Expr(*op.left.clone())),
|
||||
("right", Operand::Expr(*op.right.clone())),
|
||||
],
|
||||
Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
|
||||
("left", Operand::Expr(*op.left.clone())),
|
||||
("right", Operand::Expr(*op.right.clone())),
|
||||
("carry", Operand::Expr(*op.carry.clone())),
|
||||
],
|
||||
Call(op) | Tailcall(op) => vec![
|
||||
("output", Operand::VarList(op.output.clone())),
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
],
|
||||
Syscall(op) => vec![
|
||||
("output", Operand::VarList(op.output.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
],
|
||||
Intrinsic(op) => vec![
|
||||
("output", Operand::VarList(op.output.clone())),
|
||||
("intrinsic", Operand::Intrinsic(op.intrinsic)),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
],
|
||||
IntrinsicSsa(op) => vec![
|
||||
("output", Operand::VarSsaList(op.output.clone())),
|
||||
("intrinsic", Operand::Intrinsic(op.intrinsic)),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
],
|
||||
CallSsa(op) | TailcallSsa(op) => vec![
|
||||
("output", Operand::VarSsaList(op.output.clone())),
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
],
|
||||
CallUntypedSsa(op) | TailcallUntypedSsa(op) => vec![
|
||||
("output", Operand::VarSsaList(op.output.clone())),
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("stack", Operand::Expr(*op.stack.clone())),
|
||||
],
|
||||
SyscallSsa(op) => vec![
|
||||
("output", Operand::VarSsaList(op.output.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
],
|
||||
SyscallUntypedSsa(op) => vec![
|
||||
("output", Operand::VarSsaList(op.output.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("stack", Operand::Expr(*op.stack.clone())),
|
||||
],
|
||||
CallUntyped(op) | TailcallUntyped(op) => vec![
|
||||
("output", Operand::VarList(op.output.clone())),
|
||||
("dest", Operand::Expr(*op.dest.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("stack", Operand::Expr(*op.stack.clone())),
|
||||
],
|
||||
SyscallUntyped(op) => vec![
|
||||
("output", Operand::VarList(op.output.clone())),
|
||||
("params", Operand::ExprList(op.params.clone())),
|
||||
("stack", Operand::Expr(*op.stack.clone())),
|
||||
],
|
||||
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) => {
|
||||
vec![("src", Operand::Expr(*op.src.clone()))]
|
||||
}
|
||||
LoadStruct(op) => vec![
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
],
|
||||
LoadStructSsa(op) => vec![
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
],
|
||||
LoadSsa(op) => vec![
|
||||
("src", Operand::Expr(*op.src.clone())),
|
||||
("src_memory", Operand::Int(op.src_memory)),
|
||||
],
|
||||
Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
|
||||
SeparateParamList(op) => vec![("params", Operand::ExprList(op.params.clone()))],
|
||||
SharedParamSlot(op) => vec![("params", Operand::ExprList(op.params.clone()))],
|
||||
Var(op) | AddressOf(op) => vec![("src", Operand::Var(op.src))],
|
||||
VarField(op) | AddressOfField(op) => vec![
|
||||
("src", Operand::Var(op.src)),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
],
|
||||
VarSsa(op) | VarAliased(op) => vec![("src", Operand::VarSsa(op.src))],
|
||||
VarSsaField(op) | VarAliasedField(op) => vec![
|
||||
("src", Operand::VarSsa(op.src)),
|
||||
("offset", Operand::Int(op.offset)),
|
||||
],
|
||||
Trap(op) => vec![("vector", Operand::Int(op.vector))],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user