From 1b666caca80378e9460eec9f55017fe4443ce302 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Sun, 11 May 2025 07:04:35 -0700 Subject: [PATCH] [Rust] Don't panic when a Rust plug-in encounters an unhandled MLIL instruction `MediumLevelILInstruction` does not yet handle `MLIL_CALL_OUTPUT`, `MLIL_CALL_PARAM`, `MLIL_CALL_PARAM_SSA`, `MLIL_CALL_OUTPUT_SSA`, `MLIL_MEMORY_INTRINSIC_OUTPUT_SSA`, or `MLIL_MEMORY_INTRINSIC_SSA`. Map these to a `NotYetImplemented` kind rather than panicking since a panic takes down the entire app. --- rust/src/medium_level_il/instruction.rs | 8 +++++--- rust/src/medium_level_il/lift.rs | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs index 5e20147818..ae550d91e0 100644 --- a/rust/src/medium_level_il/instruction.rs +++ b/rust/src/medium_level_il/instruction.rs @@ -609,9 +609,7 @@ impl MediumLevelILInstruction { | MLIL_CALL_PARAM_SSA | MLIL_CALL_OUTPUT_SSA | MLIL_MEMORY_INTRINSIC_OUTPUT_SSA - | MLIL_MEMORY_INTRINSIC_SSA => { - unimplemented!() - } + | MLIL_MEMORY_INTRINSIC_SSA => Op::NotYetImplemented, }; Self { @@ -633,6 +631,7 @@ impl MediumLevelILInstruction { Bp => Lifted::Bp, Undef => Lifted::Undef, Unimpl => Lifted::Unimpl, + NotYetImplemented => Lifted::NotYetImplemented, If(op) => Lifted::If(LiftedIf { condition: self.lift_operand(op.condition), dest_true: op.dest_true, @@ -1629,6 +1628,9 @@ pub enum MediumLevelILInstructionKind { VarSsaField(VarSsaField), VarAliasedField(VarSsaField), Trap(Trap), + // A placeholder for instructions that the Rust bindings do not yet support. + // Distinct from `Unimpl` as that is a valid instruction. + NotYetImplemented, } fn get_float(value: u64, size: usize) -> f64 { diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs index 3f16148477..f5ee45b345 100644 --- a/rust/src/medium_level_il/lift.rs +++ b/rust/src/medium_level_il/lift.rs @@ -175,6 +175,9 @@ pub enum MediumLevelILLiftedInstructionKind { VarSsaField(VarSsaField), VarAliasedField(VarSsaField), Trap(Trap), + // A placeholder for instructions that the Rust bindings do not yet support. + // Distinct from `Unimpl` as that is a valid instruction. + NotYetImplemented, } impl MediumLevelILLiftedInstruction { @@ -186,6 +189,7 @@ impl MediumLevelILLiftedInstruction { Bp => "Bp", Undef => "Undef", Unimpl => "Unimpl", + NotYetImplemented => "NotYetImplemented", If(_) => "If", FloatConst(_) => "FloatConst", Const(_) => "Const", @@ -318,7 +322,7 @@ impl MediumLevelILLiftedInstruction { use MediumLevelILLiftedInstructionKind::*; use MediumLevelILLiftedOperand as Operand; match &self.kind { - Nop | Noret | Bp | Undef | Unimpl => vec![], + Nop | Noret | Bp | Undef | Unimpl | NotYetImplemented => vec![], If(op) => vec![ ("condition", Operand::Expr(*op.condition.clone())), ("dest_true", Operand::InstructionIndex(op.dest_true)),