From d479fbba6d4e4092d431152d04fff6c8488d2f7e Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Thu, 18 Jul 2024 11:50:53 +0200 Subject: [PATCH] WIP --- androscalpel/src/code.rs | 218 ++++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 105 deletions(-) diff --git a/androscalpel/src/code.rs b/androscalpel/src/code.rs index 42a8972..56741fb 100644 --- a/androscalpel/src/code.rs +++ b/androscalpel/src/code.rs @@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet}; use pyo3::prelude::*; use crate::{ - ins, ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result, + ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result, }; // TODO: make this easy to edit/manipulate, maybe move to Method @@ -163,50 +163,50 @@ impl Code { let mut used_labels = HashSet::new(); for ins in &self.insns { match ins { - Instruction::Goto(ins::Goto { label }) => { + Instruction::Goto { label } => { used_labels.insert(label.clone()); } - Instruction::IfEq(ins::IfEq { label, .. }) => { + Instruction::IfEq { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfNe(ins::IfNe { label, .. }) => { + Instruction::IfNe { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfLt(ins::IfLt { label, .. }) => { + Instruction::IfLt { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfGe(ins::IfGe { label, .. }) => { + Instruction::IfGe { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfGt(ins::IfGt { label, .. }) => { + Instruction::IfGt { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfLe(ins::IfLe { label, .. }) => { + Instruction::IfLe { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfEqZ(ins::IfEqZ { label, .. }) => { + Instruction::IfEqZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfNeZ(ins::IfNeZ { label, .. }) => { + Instruction::IfNeZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfLtZ(ins::IfLtZ { label, .. }) => { + Instruction::IfLtZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfGeZ(ins::IfGeZ { label, .. }) => { + Instruction::IfGeZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfGtZ(ins::IfGtZ { label, .. }) => { + Instruction::IfGtZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::IfLeZ(ins::IfLeZ { label, .. }) => { + Instruction::IfLeZ { label, .. } => { used_labels.insert(label.clone()); } - Instruction::Try(ins::Try { + Instruction::Try { end_label, handlers, default_handler, - }) => { + } => { used_labels.insert(end_label.clone()); for (_, label) in handlers { used_labels.insert(label.clone()); @@ -215,7 +215,7 @@ impl Code { used_labels.insert(label.clone()); } } - Instruction::Switch(ins::Switch { branches, .. }) => { + Instruction::Switch { branches, .. } => { for label in branches.values() { used_labels.insert(label.clone()); } @@ -239,7 +239,7 @@ impl Code { for ins in &self.insns { match ins { - Instruction::Label(ins::Label { name }) => { + Instruction::Label { name } => { if used_labels.get(name).is_none() { continue; } @@ -265,185 +265,193 @@ impl Code { let mut new_insns = vec![]; last_ins_was_a_label = false; - for ins in self.insns.iter().cloned() { + for ins in self.insns.into_iter() { match ins { - Instruction::Goto(mut instr) => { + Instruction::Goto { label } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::Goto(instr)); + new_insns.push(Instruction::Goto { label }); } - Instruction::IfEq(mut instr) => { + Instruction::IfEq { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfEq(instr)); + new_insns.push(Instruction::IfEq { label, a, b }); } - Instruction::IfNe(mut instr) => { + Instruction::IfNe { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfNe(instr)); + new_insns.push(Instruction::IfNe { label, a, b }); } - Instruction::IfLt(mut instr) => { + Instruction::IfLt { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfLt(instr)); + new_insns.push(Instruction::IfLt { label, a, b }); } - Instruction::IfGe(mut instr) => { + Instruction::IfGe { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfGe(instr)); + new_insns.push(Instruction::IfGe { label, a, b }); } - Instruction::IfGt(mut instr) => { + Instruction::IfGt { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfGt(instr)); + new_insns.push(Instruction::IfGt { label, a, b }); } - Instruction::IfLe(mut instr) => { + Instruction::IfLe { label, a, b } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfLe(instr)); + new_insns.push(Instruction::IfLe { label, a, b }); } - Instruction::IfEqZ(mut instr) => { + Instruction::IfEqZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfEqZ(instr)); + new_insns.push(Instruction::IfEqZ { label, a }); } - Instruction::IfNeZ(mut instr) => { + Instruction::IfNeZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfNeZ(instr)); + new_insns.push(Instruction::IfNeZ { label, a }); } - Instruction::IfLtZ(mut instr) => { + Instruction::IfLtZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfLtZ(instr)); + new_insns.push(Instruction::IfLtZ { label, a }); } - Instruction::IfGeZ(mut instr) => { + Instruction::IfGeZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfGeZ(instr)); + new_insns.push(Instruction::IfGeZ { label, a }); } - Instruction::IfGtZ(mut instr) => { + Instruction::IfGtZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfGtZ(instr)); + new_insns.push(Instruction::IfGtZ { label, a }); } - Instruction::IfLeZ(mut instr) => { + Instruction::IfLeZ { label, a } => { last_ins_was_a_label = false; - instr.label = new_labels - .get(&instr.label) + let label = new_labels + .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.label + label ))? .clone(); - new_insns.push(Instruction::IfLeZ(instr)); + new_insns.push(Instruction::IfLeZ { label, a }); } - Instruction::Try(mut instr) => { + Instruction::Try { + end_label, + mut handlers, + default_handler, + } => { last_ins_was_a_label = false; - instr.end_label = new_labels - .get(&instr.end_label) + let end_label = new_labels + .get(&end_label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.end_label + end_label ))? .clone(); - for i in 0..instr.handlers.len() { - instr.handlers[i].1 = new_labels - .get(&instr.handlers[i].1) + for i in 0..handlers.len() { + handlers[i].1 = new_labels + .get(&handlers[i].1) .ok_or(anyhow!( "Internal error: {} not found in renamed label", - instr.handlers[i].1 + handlers[i].1 ))? .clone(); } - if let Some(label) = instr.default_handler { - instr.default_handler = Some( + let default_handler = default_handler + .map(|label| { new_labels .get(&label) .ok_or(anyhow!( "Internal error: {} not found in renamed label", label - ))? - .clone(), - ); - } - new_insns.push(Instruction::Try(instr)); + )) + .cloned() + }) + .transpose()?; + new_insns.push(Instruction::Try { + end_label, + handlers, + default_handler, + }); } - Instruction::Switch(mut instr) => { + Instruction::Switch { mut branches, reg } => { last_ins_was_a_label = false; - for label in instr.branches.values_mut() { + for label in branches.values_mut() { *label = new_labels .get(label) .ok_or(anyhow!( @@ -452,15 +460,15 @@ impl Code { ))? .clone(); } - new_insns.push(Instruction::Switch(instr)); + new_insns.push(Instruction::Switch { branches, reg }); } - Instruction::Label(ins::Label { name }) => { + Instruction::Label { name } => { if used_labels.get(&name).is_none() { //println!("{name} not used"); continue; } if !last_ins_was_a_label { - new_insns.push(Instruction::Label(ins::Label { + new_insns.push(Instruction::Label { name: new_labels .get(&name) .ok_or(anyhow!( @@ -468,7 +476,7 @@ impl Code { name ))? .clone(), - })); + }); } last_ins_was_a_label = true; }