From 5c91adfe93e53f4174d70d9507a144c26c286dd5 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Wed, 26 Mar 2025 16:23:05 +0100 Subject: [PATCH] remove class now return the class --- patcher/Cargo.lock | 8 ++-- patcher/Cargo.toml | 4 +- patcher/src/code_loading_patcher.rs | 65 ++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/patcher/Cargo.lock b/patcher/Cargo.lock index 26f5029..864999d 100644 --- a/patcher/Cargo.lock +++ b/patcher/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ [[package]] name = "androscalpel" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=5379c29#5379c29eb881bb2fbed9703206f01f4a9ec73ca3" dependencies = [ "adler", "androscalpel_serializer", @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "androscalpel_serializer" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=5379c29#5379c29eb881bb2fbed9703206f01f4a9ec73ca3" dependencies = [ "androscalpel_serializer_derive", "log", @@ -60,7 +60,7 @@ dependencies = [ [[package]] name = "androscalpel_serializer_derive" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=5379c29#5379c29eb881bb2fbed9703206f01f4a9ec73ca3" dependencies = [ "proc-macro2", "quote", @@ -129,7 +129,7 @@ dependencies = [ [[package]] name = "apk_frauder" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=5379c29#5379c29eb881bb2fbed9703206f01f4a9ec73ca3" dependencies = [ "androscalpel_serializer", "flate2", diff --git a/patcher/Cargo.toml b/patcher/Cargo.toml index 04c6d2e..2d767c7 100644 --- a/patcher/Cargo.toml +++ b/patcher/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "4c4940e6b1e1760617d2cb86f83a27a7a8e187da", features = ["code-analysis"] } -apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "4c4940e6b1e1760617d2cb86f83a27a7a8e187da"} +androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "5379c29", features = ["code-analysis"] } +apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "5379c29"} anyhow = { version = "1.0.95", features = ["backtrace"] } clap = { version = "4.5.27", features = ["derive"] } env_logger = "0.11.6" diff --git a/patcher/src/code_loading_patcher.rs b/patcher/src/code_loading_patcher.rs index f29f77d..5877b76 100644 --- a/patcher/src/code_loading_patcher.rs +++ b/patcher/src/code_loading_patcher.rs @@ -1,8 +1,8 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::fs::File; -use androscalpel::{Apk, IdType}; -use anyhow::Result; +use androscalpel::{Apk, DexString, IdType, VisitableMut, VisitorMut}; +use anyhow::{Context, Result}; use clap::ValueEnum; use crate::runtime_data::RuntimeData; @@ -47,7 +47,7 @@ fn insert_code_model_class_loaders(apk: &mut Apk, data: &RuntimeData) -> Result< parent: None, class: IdType::from_smali("Ljava/lang/Boolean;").unwrap(), apk: ApkOrRef::Ref(apk), - renamed_classes: HashSet::new(), + renamed_classes: HashMap::new(), }, ); for dyn_data in &data.dyn_code_load { @@ -66,7 +66,7 @@ fn insert_code_model_class_loaders(apk: &mut Apk, data: &RuntimeData) -> Result< parent: None, class, apk: ApkOrRef::Owned(apk), - renamed_classes: HashSet::new(), + renamed_classes: HashMap::new(), }; let collisions = class_defined.intersection(&classes); for cls in collisions { @@ -90,25 +90,68 @@ struct ClassLoader<'a> { pub parent: Option, pub class: IdType, pub apk: ApkOrRef<'a>, - pub renamed_classes: HashSet, + pub renamed_classes: HashMap, } impl ClassLoader<'_> { - pub fn _apk(&mut self) -> &mut Apk { + pub fn apk(&mut self) -> &mut Apk { match &mut self.apk { ApkOrRef::Owned(ref mut apk) => apk, ApkOrRef::Ref(ref mut apk) => apk, } } - pub fn rename_classdef(&mut self, cls: &IdType) { + pub fn rename_classdef(&mut self, cls: &IdType) -> Result<()> { use androscalpel::SmaliName; + let id = self.id.clone(); + let mut i = 0; + let name = if let Some(name) = cls.get_class_name() { + name + } else { + log::warn!("Tried to rename non class type {}", cls.__str__()); + return Ok(()); + }; + let new_name = loop { + let prefix: DexString = if i == 0 { + format!("theseus-dedup/{}/", self.id).into() + } else { + format!("theseus-dedup/{}-{i}/", self.id).into() + }; + let new_name = IdType::class_from_dex_string(&prefix.concatenate(&name)); + if self.apk().get_class(&new_name).is_none() { + break new_name; + } + i += 1; + }; println!( - "TODO: rename {} -> {}_{}", + "TODO: rename {} -> {}", cls.try_to_smali().unwrap(), - cls.try_to_smali().unwrap(), - self.id + new_name.try_to_smali().unwrap(), ); + + let class = self.apk().remove_class(cls, None).with_context(|| { + format!( + "Try to rename classdef of {} in class loader {}, but classdef not found", + cls.__str__(), + &id + ) + })?; + + self.renamed_classes.insert(cls.clone(), new_name); + Ok(()) + } +} + +struct RenameTypeVisitor { + pub new_names: HashMap, +} + +impl VisitorMut for RenameTypeVisitor { + fn visit_type(&mut self, id: IdType) -> Result { + match self.new_names.get(&id) { + Some(newid) => Ok(newid.clone()), + None => Ok(id.clone()), + } } }