stop checking the method classloaders
This commit is contained in:
parent
79664a1cb4
commit
7b6f323756
2 changed files with 27 additions and 75 deletions
|
|
@ -99,20 +99,20 @@ pub(crate) static SCAL_TO_OBJ_FLOAT: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
pub(crate) static SCAL_TO_OBJ_DOUBLE: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static SCAL_TO_OBJ_DOUBLE: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;").unwrap()
|
IdMethod::from_smali("Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;").unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static GET_CLASS_LOADER: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _GET_CLASS_LOADER: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Ljava/lang/Class;->getClassLoader()Ljava/lang/ClassLoader;").unwrap()
|
IdMethod::from_smali("Ljava/lang/Class;->getClassLoader()Ljava/lang/ClassLoader;").unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static GET_PARENT: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _GET_PARENT: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Ljava/lang/ClassLoader;->getParent()Ljava/lang/ClassLoader;").unwrap()
|
IdMethod::from_smali("Ljava/lang/ClassLoader;->getParent()Ljava/lang/ClassLoader;").unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static GET_CLASS: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _GET_CLASS: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Ljava/lang/Object;->getClass()Ljava/lang/Class;").unwrap()
|
IdMethod::from_smali("Ljava/lang/Object;->getClass()Ljava/lang/Class;").unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static TO_STRING: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _TO_STRING: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Ljava/lang/Object;->toString()Ljava/lang/String;").unwrap()
|
IdMethod::from_smali("Ljava/lang/Object;->toString()Ljava/lang/String;").unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
pub(crate) static BOOT_CLASS_LOADER_TY: LazyLock<IdType> =
|
pub(crate) static _BOOT_CLASS_LOADER_TY: LazyLock<IdType> =
|
||||||
LazyLock::new(|| IdType::from_smali("Ljava/lang/BootClassLoader;").unwrap());
|
LazyLock::new(|| IdType::from_smali("Ljava/lang/BootClassLoader;").unwrap());
|
||||||
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());
|
||||||
|
|
@ -122,26 +122,26 @@ pub(crate) static DELEGATE_LAST_CLASS_LOADER: LazyLock<IdType> =
|
||||||
pub(crate) static LOG_INFO: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static LOG_INFO: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali("Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I").unwrap()
|
IdMethod::from_smali("Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I").unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static STRING_REPLACE_ALL: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _STRING_REPLACE_ALL: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali(
|
IdMethod::from_smali(
|
||||||
"Ljava/lang/String;->replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
|
"Ljava/lang/String;->replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
pub(crate) static GET_APP: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _GET_APP: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali(
|
IdMethod::from_smali(
|
||||||
"Landroid/app/ActivityThread;->currentApplication()Landroid/app/Application;",
|
"Landroid/app/ActivityThread;->currentApplication()Landroid/app/Application;",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static GET_APP_INFO: LazyLock<IdMethod> = LazyLock::new(|| {
|
pub(crate) static _GET_APP_INFO: LazyLock<IdMethod> = LazyLock::new(|| {
|
||||||
IdMethod::from_smali(
|
IdMethod::from_smali(
|
||||||
"Landroid/content/Context;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;",
|
"Landroid/content/Context;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
pub(crate) static APP_INFO_SOURCE_DIR: LazyLock<IdField> = LazyLock::new(|| {
|
pub(crate) static _APP_INFO_SOURCE_DIR: LazyLock<IdField> = LazyLock::new(|| {
|
||||||
IdField::from_smali("Landroid/content/pm/ApplicationInfo;->sourceDir:Ljava/lang/String;")
|
IdField::from_smali("Landroid/content/pm/ApplicationInfo;->sourceDir:Ljava/lang/String;")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use androscalpel::SmaliName;
|
use androscalpel::SmaliName;
|
||||||
use androscalpel::{Code, IdMethod, IdMethodType, IdType, Instruction, Method};
|
use androscalpel::{Code, IdMethod, IdMethodType, IdType, Instruction, Method};
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use log::{debug, error, warn};
|
use log::{debug, warn};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
@ -232,16 +232,10 @@ pub fn transform_method(
|
||||||
"Lcom/example/theseus/dynandref/Main;->factoryInterface(Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;)V"
|
"Lcom/example/theseus/dynandref/Main;->factoryInterface(Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;)V"
|
||||||
).unwrap()
|
).unwrap()
|
||||||
{
|
{
|
||||||
error!(
|
|
||||||
"Patching instanciation of {}",
|
|
||||||
ref_data.constructor.class_.__str__()
|
|
||||||
);
|
|
||||||
let mut cl_id = Some(&ref_data.constructor_cl_id);
|
let mut cl_id = Some(&ref_data.constructor_cl_id);
|
||||||
while let Some(id) = cl_id {
|
while let Some(id) = cl_id {
|
||||||
error!(" cl id : {id}");
|
|
||||||
let cl = runtime_data.classloaders.get(id);
|
let cl = runtime_data.classloaders.get(id);
|
||||||
if let Some(cl) = cl {
|
if let Some(cl) = cl {
|
||||||
error!(" cl str: {}", cl.string_representation.as_str());
|
|
||||||
cl_id = cl.parent_id.as_ref();
|
cl_id = cl.parent_id.as_ref();
|
||||||
} else {
|
} else {
|
||||||
cl_id = None
|
cl_id = None
|
||||||
|
|
@ -260,26 +254,6 @@ pub fn transform_method(
|
||||||
)? {
|
)? {
|
||||||
new_insns.push(ins);
|
new_insns.push(ins);
|
||||||
}
|
}
|
||||||
if ref_data.constructor
|
|
||||||
== IdMethod::from_smali(
|
|
||||||
"Lcom/example/theseus/dynandref/AReflectee;-><init>()V",
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
&&
|
|
||||||
meth.descriptor == IdMethod::from_smali(
|
|
||||||
"Lcom/example/theseus/dynandref/Main;->factoryInterface(Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;)V"
|
|
||||||
).unwrap()
|
|
||||||
{
|
|
||||||
let key = (ref_data.constructor.clone(), ref_data.constructor_cl_id.clone());
|
|
||||||
error!(
|
|
||||||
" tester method: {}",
|
|
||||||
tester_methods
|
|
||||||
.get(&key)
|
|
||||||
.unwrap()
|
|
||||||
.descriptor
|
|
||||||
.__str__()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Should not happen!")
|
panic!("Should not happen!")
|
||||||
|
|
@ -379,32 +353,6 @@ pub fn transform_method(
|
||||||
// Add the new code
|
// Add the new code
|
||||||
code.insns.append(&mut new_insns);
|
code.insns.append(&mut new_insns);
|
||||||
code.registers_size += register_info.get_nb_added_reg();
|
code.registers_size += register_info.get_nb_added_reg();
|
||||||
if meth.descriptor
|
|
||||||
== IdMethod::from_smali(
|
|
||||||
"Lcom/example/theseus/dynandref/Main;->\
|
|
||||||
factoryInterface(\
|
|
||||||
Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;\
|
|
||||||
)V",
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
{
|
|
||||||
for ins in &code.insns {
|
|
||||||
let indent = if let Instruction::Label { .. } = &ins {
|
|
||||||
""
|
|
||||||
} else {
|
|
||||||
" "
|
|
||||||
};
|
|
||||||
error!(" {indent}{}", ins.__str__());
|
|
||||||
}
|
|
||||||
use androscalpel::MethodCFG;
|
|
||||||
println!("{}", MethodCFG::new(meth).unwrap().to_dot(true));
|
|
||||||
for (lab, refdatas) in ABORD_LABELS.lock().unwrap().iter() {
|
|
||||||
error!("label {lab}");
|
|
||||||
for refdata in refdatas {
|
|
||||||
error!(" {refdata}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -414,7 +362,7 @@ fn gen_tester_method(
|
||||||
method_to_test: IdMethod,
|
method_to_test: IdMethod,
|
||||||
is_constructor: bool,
|
is_constructor: bool,
|
||||||
classloader: Option<String>,
|
classloader: Option<String>,
|
||||||
runtime_data: &RuntimeData,
|
_runtime_data: &RuntimeData,
|
||||||
) -> Result<Method> {
|
) -> Result<Method> {
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
if let Some(ref id) = classloader {
|
if let Some(ref id) = classloader {
|
||||||
|
|
@ -491,12 +439,13 @@ fn gen_tester_method(
|
||||||
const REG_TST_VAL: u8 = 2;
|
const REG_TST_VAL: u8 = 2;
|
||||||
const REG_DEF_TYPE: u8 = 3;
|
const REG_DEF_TYPE: u8 = 3;
|
||||||
const REG_CMP_VAL: u8 = 4;
|
const REG_CMP_VAL: u8 = 4;
|
||||||
const REG_CLASS_LOADER: u8 = 5;
|
const _REG_CLASS_LOADER: u8 = 5;
|
||||||
const REG_REGEX: u8 = 6;
|
const REG_REGEX: u8 = 6;
|
||||||
const REG_REPLACE: u8 = 7;
|
const REG_REPLACE: u8 = 7;
|
||||||
const REG_IF_RES: u8 = 8;
|
const REG_IF_RES: u8 = 8;
|
||||||
const REG_REF_METHOD: u8 = 9;
|
const REG_REF_METHOD: u8 = 9;
|
||||||
|
|
||||||
|
/*
|
||||||
fn standardize_name(reg: u8, old_app_path: &str) -> Vec<Instruction> {
|
fn standardize_name(reg: u8, old_app_path: &str) -> Vec<Instruction> {
|
||||||
let tmp_reg = REG_IF_RES;
|
let tmp_reg = REG_IF_RES;
|
||||||
vec![
|
vec![
|
||||||
|
|
@ -565,7 +514,7 @@ fn gen_tester_method(
|
||||||
},
|
},
|
||||||
Instruction::MoveResultObject { to: reg },
|
Instruction::MoveResultObject { to: reg },
|
||||||
]
|
]
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Check for arg type
|
// Check for arg type
|
||||||
let mut insns = if !is_constructor {
|
let mut insns = if !is_constructor {
|
||||||
|
|
@ -723,6 +672,9 @@ fn gen_tester_method(
|
||||||
}
|
}
|
||||||
insns.push(Instruction::MoveResultObject { to: REG_DEF_TYPE });
|
insns.push(Instruction::MoveResultObject { to: REG_DEF_TYPE });
|
||||||
|
|
||||||
|
/* Checking classloader is complicated: adding the classes to the appliction change the
|
||||||
|
* behavior of classloader, so this tst wont work. To make this work, all classes reinjected
|
||||||
|
* to the application would need to be renammed.
|
||||||
//Check the classloader
|
//Check the classloader
|
||||||
let mut current_classloader = classloader
|
let mut current_classloader = classloader
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -848,6 +800,7 @@ fn gen_tester_method(
|
||||||
.find(|cl| cl.cname == *BOOT_CLASS_LOADER_TY)
|
.find(|cl| cl.cname == *BOOT_CLASS_LOADER_TY)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Check Declaring Type
|
// Check Declaring Type
|
||||||
insns.append(&mut vec![
|
insns.append(&mut vec![
|
||||||
|
|
@ -1109,12 +1062,12 @@ fn gen_tester_method(
|
||||||
/// - `abort_label`: the label where to jump if the method does not match `id_method`.
|
/// - `abort_label`: the label where to jump if the method does not match `id_method`.
|
||||||
/// - `tester_methods_class`: the class used to define the methods in `tester_methods`
|
/// - `tester_methods_class`: the class used to define the methods in `tester_methods`
|
||||||
/// - `tester_methods`: the methods used to test if a `java.lang.reflect.Method` is a specific method.
|
/// - `tester_methods`: the methods used to test if a `java.lang.reflect.Method` is a specific method.
|
||||||
/// Methods are indexed by the IdMethod they detect, and have a name derived from the method
|
/// Methods are indexed by the IdMethod they detect, and have a name derived from the method
|
||||||
/// they detect.
|
/// they detect.
|
||||||
/// - `classloader`: is the runtime data of the classloader that loaded the class defining the
|
/// - `classloader`: is the runtime data of the classloader that loaded the class defining the
|
||||||
/// reflected method. If None, the classloader is not tested. Platform classes should probably
|
/// reflected method. If None, the classloader is not tested. Platform classes should probably
|
||||||
/// not be tested (the bootclassloader can be represented with a null reference, which may
|
/// not be tested (the bootclassloader can be represented with a null reference, which may
|
||||||
/// lead to a null pointer exception).
|
/// lead to a null pointer exception).
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn test_method(
|
fn test_method(
|
||||||
method_obj_reg: u16,
|
method_obj_reg: u16,
|
||||||
|
|
@ -1449,7 +1402,6 @@ fn get_cnstr_new_inst_block(
|
||||||
if ref_data.caller_method == IdMethod::from_smali("Lcom/example/theseus/dynandref/Main;->factoryInterface(Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;)V").unwrap() {
|
if ref_data.caller_method == IdMethod::from_smali("Lcom/example/theseus/dynandref/Main;->factoryInterface(Landroid/app/Activity;Ljava/lang/Class;ZBSCIJFD[Ljava/lang/String;)V").unwrap() {
|
||||||
ABORD_LABELS.lock().unwrap().entry(abort_label.clone()).or_default().push(ref_data.clone());
|
ABORD_LABELS.lock().unwrap().entry(abort_label.clone()).or_default().push(ref_data.clone());
|
||||||
}
|
}
|
||||||
error!("abort_label: {abort_label}");
|
|
||||||
|
|
||||||
let classloader = if ref_data.constructor.class_.is_platform_class() {
|
let classloader = if ref_data.constructor.class_.is_platform_class() {
|
||||||
None
|
None
|
||||||
|
|
@ -1510,11 +1462,11 @@ fn get_cnstr_new_inst_block(
|
||||||
/// - `abort_label`: the label where to jump if the method does not match `id_method`.
|
/// - `abort_label`: the label where to jump if the method does not match `id_method`.
|
||||||
/// - `tester_methods_class`: the class used to define the methods in `tester_methods`
|
/// - `tester_methods_class`: the class used to define the methods in `tester_methods`
|
||||||
/// - `tester_methods`: the methods used to test if a `java.lang.reflect.Method` is a specific method.
|
/// - `tester_methods`: the methods used to test if a `java.lang.reflect.Method` is a specific method.
|
||||||
/// Methods are indexed by the IdMethod they detect, and have a name derived from the method
|
/// Methods are indexed by the IdMethod they detect, and have a name derived from the method
|
||||||
/// they detect.
|
/// they detect.
|
||||||
/// - `classloader`: is the runtime data of the classloader that loaded the. If None, the classloader
|
/// - `classloader`: is the runtime data of the classloader that loaded the. If None, the classloader
|
||||||
/// is not tested. Platform classes should probably not be tested (the bootclassloader can be
|
/// is not tested. Platform classes should probably not be tested (the bootclassloader can be
|
||||||
/// represented with a null reference, which may lead to a null pointer exception).
|
/// represented with a null reference, which may lead to a null pointer exception).
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn test_cnstr(
|
fn test_cnstr(
|
||||||
cnst_reg: u16,
|
cnst_reg: u16,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue