model delegate last behavior

This commit is contained in:
Jean-Marie Mineau 2025-04-02 16:45:26 +02:00
parent 555c1e72fb
commit b86bf08229
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 18 additions and 8 deletions

View file

@ -5,14 +5,9 @@ use androscalpel::{Apk, DexString, IdType, VisitorMut};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use clap::ValueEnum; use clap::ValueEnum;
use crate::dex_types::DELEGATE_LAST_CLASS_LOADER;
use crate::runtime_data::RuntimeData; use crate::runtime_data::RuntimeData;
// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
//
// INSERT EMPTY CLASS LOADERS WHEN ID REFERS TO UNKNOWN CLASS LOADER
//
// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
#[derive(ValueEnum, Debug, PartialEq, Clone, Copy, Default)] #[derive(ValueEnum, Debug, PartialEq, Clone, Copy, Default)]
pub enum CodePatchingStrategy { pub enum CodePatchingStrategy {
#[default] #[default]
@ -70,7 +65,10 @@ fn insert_code_model_class_loaders(apk: &mut Apk, runtime_data: &mut RuntimeData
apk.add_code(file, crate::labeling, false)?; apk.add_code(file, crate::labeling, false)?;
} }
assert!(!class_loaders.contains_key(&dyn_data.classloader)); assert!(
!class_loaders.contains_key(&dyn_data.classloader),
"The same class loader should not appear twice in runtime_data.dyn_code_load"
);
let classes = apk.list_classes(); let classes = apk.list_classes();
let mut class_loader = ClassLoader { let mut class_loader = ClassLoader {
@ -305,7 +303,14 @@ impl ClassLoader<'_> {
ty: &IdType, ty: &IdType,
class_loaders: &HashMap<String, Self>, class_loaders: &HashMap<String, Self>,
) -> Option<IdType> { ) -> Option<IdType> {
// TODO: Implemente different class loader behaviors // TODO: Check Platform Classes
if self.class == *DELEGATE_LAST_CLASS_LOADER {
if let Some(new_ty) = self.renamed_classes.get(ty) {
return Some(new_ty.clone());
} else if self.apk().get_class(ty).is_some() {
return Some(ty.clone());
}
}
if let Some(ref parent_id) = self.parent { if let Some(ref parent_id) = self.parent {
if let Some(parent) = class_loaders.get(parent_id) { if let Some(parent) = class_loaders.get(parent_id) {
if let Some(new_ty) = parent.get_ref_new_name(ty, class_loaders) { if let Some(new_ty) = parent.get_ref_new_name(ty, class_loaders) {
@ -315,6 +320,9 @@ impl ClassLoader<'_> {
log::warn!("Class Loader {}({}) has parent {}, but parent was not found in class loader list", self.id, self.class.__str__(), parent_id); log::warn!("Class Loader {}({}) has parent {}, but parent was not found in class loader list", self.id, self.class.__str__(), parent_id);
} }
} }
if self.class == *DELEGATE_LAST_CLASS_LOADER {
return None;
}
if let Some(new_ty) = self.renamed_classes.get(ty) { if let Some(new_ty) = self.renamed_classes.get(ty) {
Some(new_ty.clone()) Some(new_ty.clone())
} else if self.apk().get_class(ty).is_some() { } else if self.apk().get_class(ty).is_some() {

View file

@ -102,6 +102,8 @@ pub(crate) static SCAL_TO_OBJ_DOUBLE: LazyLock<IdMethod> = LazyLock::new(|| {
pub(crate) static OBJECT_TY: LazyLock<IdType> = pub(crate) static OBJECT_TY: LazyLock<IdType> =
LazyLock::new(|| IdType::from_smali("Ljava/lang/Object;").unwrap()); LazyLock::new(|| IdType::from_smali("Ljava/lang/Object;").unwrap());
pub(crate) static DELEGATE_LAST_CLASS_LOADER: LazyLock<IdType> =
LazyLock::new(|| IdType::from_smali("Ldalvik/system/DelegateLastClassLoader;").unwrap());
/// Get the method that convert a object to its scalar conterpart (eg `java.lang.Integer` to `int` with /// Get the method that convert a object to its scalar conterpart (eg `java.lang.Integer` to `int` with
/// `Ljava/lang/Integer;->intValue()I`) /// `Ljava/lang/Integer;->intValue()I`)