diff options
| author | Michael Krasnitski <michael.krasnitski@gmail.com> | 2024-02-11 15:27:22 -0500 |
|---|---|---|
| committer | Kyle Martin <krm504@nyu.edu> | 2024-03-18 17:46:37 -0400 |
| commit | 9939d850f0b8ccaf1ae048bcb5f788a6c3e606bf (patch) | |
| tree | 91b582cd51820d826efcd5312e234e56617ca7f9 /rust/src/hlil/lift.rs | |
| parent | 970fe84875e2d6eed918f5bdc9ff689ef37b05ce (diff) | |
Refactor HLIL instructions
Similar to MLIL. Also, reintroduce `LiftedJump` and `LiftedLabel` types.
Diffstat (limited to 'rust/src/hlil/lift.rs')
| -rw-r--r-- | rust/src/hlil/lift.rs | 470 |
1 files changed, 205 insertions, 265 deletions
diff --git a/rust/src/hlil/lift.rs b/rust/src/hlil/lift.rs index 5ed7a33c..06338dea 100644 --- a/rust/src/hlil/lift.rs +++ b/rust/src/hlil/lift.rs @@ -1,7 +1,33 @@ use super::{operation::*, HighLevelILFunction}; +use crate::rc::Ref; +use crate::types::{ConstantData, ILIntrinsic, SSAVariable, Variable}; + +#[derive(Clone)] +pub enum HighLevelILLiftedOperand { + ConstantData(ConstantData), + Expr(HighLevelILLiftedInstruction), + ExprList(Vec<HighLevelILLiftedInstruction>), + Float(f64), + Int(u64), + IntList(Vec<u64>), + Intrinsic(ILIntrinsic), + Label(GotoLabel), + MemberIndex(Option<usize>), + Var(Variable), + VarSsa(SSAVariable), + VarSsaList(Vec<SSAVariable>), +} + #[derive(Clone, Debug, PartialEq)] -pub enum HighLevelILLiftedInstruction { +pub struct HighLevelILLiftedInstruction { + pub function: Ref<HighLevelILFunction>, + pub address: u64, + pub kind: HighLevelILLiftedInstructionKind, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum HighLevelILLiftedInstructionKind { Adc(LiftedBinaryOpCarry), Sbb(LiftedBinaryOpCarry), Rlc(LiftedBinaryOpCarry), @@ -91,21 +117,21 @@ pub enum HighLevelILLiftedInstruction { FloatConst(FloatConst), For(LiftedForLoop), ForSsa(LiftedForLoopSsa), - Goto(Label), - Label(Label), + Goto(LiftedLabel), + Label(LiftedLabel), If(LiftedIf), Intrinsic(LiftedIntrinsic), IntrinsicSsa(LiftedIntrinsicSsa), - Jump(Jump), + Jump(LiftedJump), MemPhi(LiftedMemPhi), - Nop(NoArgs), - Break(NoArgs), - Continue(NoArgs), - Noret(NoArgs), - Unreachable(NoArgs), - Bp(NoArgs), - Undef(NoArgs), - Unimpl(NoArgs), + Nop, + Break, + Continue, + Noret, + Unreachable, + Bp, + Undef, + Unimpl, Ret(LiftedRet), Split(LiftedSplit), StructField(LiftedStructField), @@ -127,259 +153,173 @@ pub enum HighLevelILLiftedInstruction { } impl HighLevelILLiftedInstruction { - pub fn address(&self) -> u64 { - use HighLevelILLiftedInstruction::*; - match self { - Adc(op) => op.address, - Sbb(op) => op.address, - Rlc(op) => op.address, - Rrc(op) => op.address, - Add(op) => op.address, - Sub(op) => op.address, - And(op) => op.address, - Or(op) => op.address, - Xor(op) => op.address, - Lsl(op) => op.address, - Lsr(op) => op.address, - Asr(op) => op.address, - Rol(op) => op.address, - Ror(op) => op.address, - Mul(op) => op.address, - MuluDp(op) => op.address, - MulsDp(op) => op.address, - Divu(op) => op.address, - DivuDp(op) => op.address, - Divs(op) => op.address, - DivsDp(op) => op.address, - Modu(op) => op.address, - ModuDp(op) => op.address, - Mods(op) => op.address, - ModsDp(op) => op.address, - CmpE(op) => op.address, - CmpNe(op) => op.address, - CmpSlt(op) => op.address, - CmpUlt(op) => op.address, - CmpSle(op) => op.address, - CmpUle(op) => op.address, - CmpSge(op) => op.address, - CmpUge(op) => op.address, - CmpSgt(op) => op.address, - CmpUgt(op) => op.address, - TestBit(op) => op.address, - AddOverflow(op) => op.address, - Fadd(op) => op.address, - Fsub(op) => op.address, - Fmul(op) => op.address, - Fdiv(op) => op.address, - FcmpE(op) => op.address, - FcmpNe(op) => op.address, - FcmpLt(op) => op.address, - FcmpLe(op) => op.address, - FcmpGe(op) => op.address, - FcmpGt(op) => op.address, - FcmpO(op) => op.address, - FcmpUo(op) => op.address, - ArrayIndex(op) => op.address, - ArrayIndexSsa(op) => op.address, - Assign(op) => op.address, - AssignMemSsa(op) => op.address, - AssignUnpack(op) => op.address, - AssignUnpackMemSsa(op) => op.address, - Block(op) => op.address, - Call(op) => op.address, - Tailcall(op) => op.address, - CallSsa(op) => op.address, - Case(op) => op.address, - Const(op) => op.address, - ConstPtr(op) => op.address, - Import(op) => op.address, - ConstData(op) => op.address, - Deref(op) => op.address, - AddressOf(op) => op.address, - Neg(op) => op.address, - Not(op) => op.address, - Sx(op) => op.address, - Zx(op) => op.address, - LowPart(op) => op.address, - BoolToInt(op) => op.address, - UnimplMem(op) => op.address, - Fsqrt(op) => op.address, - Fneg(op) => op.address, - Fabs(op) => op.address, - FloatToInt(op) => op.address, - IntToFloat(op) => op.address, - FloatConv(op) => op.address, - RoundToInt(op) => op.address, - Floor(op) => op.address, - Ceil(op) => op.address, - Ftrunc(op) => op.address, - DerefFieldSsa(op) => op.address, - DerefSsa(op) => op.address, - ExternPtr(op) => op.address, - FloatConst(op) => op.address, - For(op) => op.address, - ForSsa(op) => op.address, - Goto(op) => op.address, - Label(op) => op.address, - If(op) => op.address, - Intrinsic(op) => op.address, - IntrinsicSsa(op) => op.address, - Jump(op) => op.address, - MemPhi(op) => op.address, - Nop(op) => op.address, - Break(op) => op.address, - Continue(op) => op.address, - Noret(op) => op.address, - Unreachable(op) => op.address, - Bp(op) => op.address, - Undef(op) => op.address, - Unimpl(op) => op.address, - Ret(op) => op.address, - Split(op) => op.address, - StructField(op) => op.address, - DerefField(op) => op.address, - Switch(op) => op.address, - Syscall(op) => op.address, - SyscallSsa(op) => op.address, - Trap(op) => op.address, - VarDeclare(op) => op.address, - Var(op) => op.address, - VarInit(op) => op.address, - VarInitSsa(op) => op.address, - VarPhi(op) => op.address, - VarSsa(op) => op.address, - While(op) => op.address, - DoWhile(op) => op.address, - WhileSsa(op) => op.address, - DoWhileSsa(op) => op.address, - } - } - - pub fn function(&self) -> &HighLevelILFunction { - use HighLevelILLiftedInstruction::*; - match self { - Adc(op) => &op.function, - Sbb(op) => &op.function, - Rlc(op) => &op.function, - Rrc(op) => &op.function, - Add(op) => &op.function, - Sub(op) => &op.function, - And(op) => &op.function, - Or(op) => &op.function, - Xor(op) => &op.function, - Lsl(op) => &op.function, - Lsr(op) => &op.function, - Asr(op) => &op.function, - Rol(op) => &op.function, - Ror(op) => &op.function, - Mul(op) => &op.function, - MuluDp(op) => &op.function, - MulsDp(op) => &op.function, - Divu(op) => &op.function, - DivuDp(op) => &op.function, - Divs(op) => &op.function, - DivsDp(op) => &op.function, - Modu(op) => &op.function, - ModuDp(op) => &op.function, - Mods(op) => &op.function, - ModsDp(op) => &op.function, - CmpE(op) => &op.function, - CmpNe(op) => &op.function, - CmpSlt(op) => &op.function, - CmpUlt(op) => &op.function, - CmpSle(op) => &op.function, - CmpUle(op) => &op.function, - CmpSge(op) => &op.function, - CmpUge(op) => &op.function, - CmpSgt(op) => &op.function, - CmpUgt(op) => &op.function, - TestBit(op) => &op.function, - AddOverflow(op) => &op.function, - Fadd(op) => &op.function, - Fsub(op) => &op.function, - Fmul(op) => &op.function, - Fdiv(op) => &op.function, - FcmpE(op) => &op.function, - FcmpNe(op) => &op.function, - FcmpLt(op) => &op.function, - FcmpLe(op) => &op.function, - FcmpGe(op) => &op.function, - FcmpGt(op) => &op.function, - FcmpO(op) => &op.function, - FcmpUo(op) => &op.function, - ArrayIndex(op) => &op.function, - ArrayIndexSsa(op) => &op.function, - Assign(op) => &op.function, - AssignMemSsa(op) => &op.function, - AssignUnpack(op) => &op.function, - AssignUnpackMemSsa(op) => &op.function, - Block(op) => &op.function, - Call(op) => &op.function, - Tailcall(op) => &op.function, - CallSsa(op) => &op.function, - Case(op) => &op.function, - Const(op) => &op.function, - ConstPtr(op) => &op.function, - Import(op) => &op.function, - ConstData(op) => &op.function, - Deref(op) => &op.function, - AddressOf(op) => &op.function, - Neg(op) => &op.function, - Not(op) => &op.function, - Sx(op) => &op.function, - Zx(op) => &op.function, - LowPart(op) => &op.function, - BoolToInt(op) => &op.function, - UnimplMem(op) => &op.function, - Fsqrt(op) => &op.function, - Fneg(op) => &op.function, - Fabs(op) => &op.function, - FloatToInt(op) => &op.function, - IntToFloat(op) => &op.function, - FloatConv(op) => &op.function, - RoundToInt(op) => &op.function, - Floor(op) => &op.function, - Ceil(op) => &op.function, - Ftrunc(op) => &op.function, - DerefFieldSsa(op) => &op.function, - DerefSsa(op) => &op.function, - ExternPtr(op) => &op.function, - FloatConst(op) => &op.function, - For(op) => &op.function, - ForSsa(op) => &op.function, - Goto(op) => &op.function, - Label(op) => &op.function, - If(op) => &op.function, - Intrinsic(op) => &op.function, - IntrinsicSsa(op) => &op.function, - Jump(op) => &op.function, - MemPhi(op) => &op.function, - Nop(op) => &op.function, - Break(op) => &op.function, - Continue(op) => &op.function, - Noret(op) => &op.function, - Unreachable(op) => &op.function, - Bp(op) => &op.function, - Undef(op) => &op.function, - Unimpl(op) => &op.function, - Ret(op) => &op.function, - Split(op) => &op.function, - StructField(op) => &op.function, - DerefField(op) => &op.function, - Switch(op) => &op.function, - Syscall(op) => &op.function, - SyscallSsa(op) => &op.function, - Trap(op) => &op.function, - VarDeclare(op) => &op.function, - Var(op) => &op.function, - VarInit(op) => &op.function, - VarInitSsa(op) => &op.function, - VarPhi(op) => &op.function, - VarSsa(op) => &op.function, - While(op) => &op.function, - DoWhile(op) => &op.function, - WhileSsa(op) => &op.function, - DoWhileSsa(op) => &op.function, + pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> { + use HighLevelILLiftedInstructionKind::*; + use HighLevelILLiftedOperand as Operand; + match &self.kind { + 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())), + ], + 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) | Fadd(op) + | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) + | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![ + ("left", Operand::Expr(*op.left.clone())), + ("right", Operand::Expr(*op.right.clone())), + ], + ArrayIndex(op) => vec![ + ("src", Operand::Expr(*op.src.clone())), + ("index", Operand::Expr(*op.index.clone())), + ], + ArrayIndexSsa(op) => vec![ + ("src", Operand::Expr(*op.src.clone())), + ("src_memory", Operand::Int(op.src_memory)), + ("index", Operand::Expr(*op.index.clone())), + ], + Assign(op) => vec![ + ("dest", Operand::Expr(*op.dest.clone())), + ("src", Operand::Expr(*op.src.clone())), + ], + AssignMemSsa(op) => vec![ + ("dest", Operand::Expr(*op.dest.clone())), + ("dest_memory", Operand::Int(op.dest_memory)), + ("src", Operand::Expr(*op.src.clone())), + ("src_memory", Operand::Int(op.src_memory)), + ], + AssignUnpack(op) => vec![ + ("dest", Operand::ExprList(op.dest.clone())), + ("src", Operand::Expr(*op.src.clone())), + ], + AssignUnpackMemSsa(op) => vec![ + ("dest", Operand::ExprList(op.dest.clone())), + ("dest_memory", Operand::Int(op.dest_memory)), + ("src", Operand::Expr(*op.src.clone())), + ("src_memory", Operand::Int(op.src_memory)), + ], + Block(op) => vec![("body", Operand::ExprList(op.body.clone()))], + Call(op) | Tailcall(op) => vec![ + ("dest", Operand::Expr(*op.dest.clone())), + ("params", Operand::ExprList(op.params.clone())), + ], + CallSsa(op) => vec![ + ("dest", Operand::Expr(*op.dest.clone())), + ("params", Operand::ExprList(op.params.clone())), + ("dest_memory", Operand::Int(op.dest_memory)), + ("src_memory", Operand::Int(op.src_memory)), + ], + Case(op) => vec![ + ("values", Operand::ExprList(op.values.clone())), + ("body", Operand::Expr(*op.body.clone())), + ], + Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))], + ConstData(op) => vec![( + "constant_data", + Operand::ConstantData(op.constant_data.clone()), + )], + Deref(op) | AddressOf(op) | 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) => vec![("src", Operand::Expr(*op.src.clone()))], + DerefFieldSsa(op) => vec![ + ("src", Operand::Expr(*op.src.clone())), + ("src_memory", Operand::Int(op.src_memory)), + ("offset", Operand::Int(op.offset)), + ("member_index", Operand::MemberIndex(op.member_index)), + ], + DerefSsa(op) => vec![ + ("src", Operand::Expr(*op.src.clone())), + ("src_memory", Operand::Int(op.src_memory)), + ], + ExternPtr(op) => vec![ + ("constant", Operand::Int(op.constant)), + ("offset", Operand::Int(op.offset)), + ], + FloatConst(op) => vec![("constant", Operand::Float(op.constant))], + For(op) => vec![ + ("init", Operand::Expr(*op.init.clone())), + ("condition", Operand::Expr(*op.condition.clone())), + ("update", Operand::Expr(*op.update.clone())), + ("body", Operand::Expr(*op.body.clone())), + ], + ForSsa(op) => vec![ + ("init", Operand::Expr(*op.init.clone())), + ("condition_phi", Operand::Expr(*op.condition_phi.clone())), + ("condition", Operand::Expr(*op.condition.clone())), + ("update", Operand::Expr(*op.update.clone())), + ("body", Operand::Expr(*op.body.clone())), + ], + Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))], + If(op) => vec![ + ("condition", Operand::Expr(*op.condition.clone())), + ("cond_true", Operand::Expr(*op.cond_true.clone())), + ("cond_false", Operand::Expr(*op.cond_false.clone())), + ], + Intrinsic(op) => vec![ + ("intrinsic", Operand::Intrinsic(op.intrinsic)), + ("params", Operand::ExprList(op.params.clone())), + ], + IntrinsicSsa(op) => vec![ + ("intrinsic", Operand::Intrinsic(op.intrinsic)), + ("params", Operand::ExprList(op.params.clone())), + ("dest_memory", Operand::Int(op.dest_memory)), + ("src_memory", Operand::Int(op.src_memory)), + ], + Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))], + MemPhi(op) => vec![ + ("dest", Operand::Int(op.dest)), + ("src", Operand::IntList(op.src.clone())), + ], + Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![], + Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))], + Split(op) => vec![ + ("high", Operand::Expr(*op.high.clone())), + ("low", Operand::Expr(*op.low.clone())), + ], + StructField(op) | DerefField(op) => vec![ + ("src", Operand::Expr(*op.src.clone())), + ("offset", Operand::Int(op.offset)), + ("member_index", Operand::MemberIndex(op.member_index)), + ], + Switch(op) => vec![ + ("condition", Operand::Expr(*op.condition.clone())), + ("default", Operand::Expr(*op.default.clone())), + ("cases", Operand::ExprList(op.cases.clone())), + ], + Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))], + SyscallSsa(op) => vec![ + ("params", Operand::ExprList(op.params.clone())), + ("dest_memory", Operand::Int(op.dest_memory)), + ("src_memory", Operand::Int(op.src_memory)), + ], + Trap(op) => vec![("vector", Operand::Int(op.vector))], + VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))], + VarInit(op) => vec![ + ("dest", Operand::Var(op.dest)), + ("src", Operand::Expr(*op.src.clone())), + ], + VarInitSsa(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())), + ], + VarSsa(op) => vec![("var", Operand::VarSsa(op.var))], + While(op) | DoWhile(op) => vec![ + ("condition", Operand::Expr(*op.condition.clone())), + ("body", Operand::Expr(*op.body.clone())), + ], + WhileSsa(op) | DoWhileSsa(op) => vec![ + ("condition_phi", Operand::Expr(*op.condition_phi.clone())), + ("condition", Operand::Expr(*op.condition.clone())), + ("body", Operand::Expr(*op.body.clone())), + ], } } } |
