This commit is contained in:
Jean-Marie Mineau 2025-04-18 15:43:31 +02:00
parent 7f46d6c12f
commit a999338cd0
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
7 changed files with 139 additions and 1115 deletions

View file

@ -357,14 +357,14 @@ Java.perform(() => {
// openInMemoryDexFilesNative() checks bufs.length == arrays.length == starts.length === ends.length
for (let i = 0; i < bufs.length; i++) {
let s = starts[i];
let e = starts[i];
let e = ends[i];
// openInMemoryDexFilesNative() checks s < e
let array = arrays[i];
let buf = bufs[i];
let raw = [];
// match code from art/runtime/native/dalvik_system_DexFile.cc commit 3d19fbcc09b1b44928639b06cd0b88f735cd988d
raw = Arrays.copyOf([], e-s);
if (array === null) {
raw = Arrays.copyOf([], e-s);
raw = buf.get(s, raw, 0, e-s);
} else {
raw = Arrays.copyOfRange(array, s, e);

1182
patcher/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,14 +6,13 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
androscalpel = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "615f7a8", features = ["code-analysis"] }
apk_frauder = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "615f7a8"}
androscalpel = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "3cc02a3", features = ["code-analysis"] }
apk_frauder = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "3cc02a3"}
#androscalpel = { path = "../../androscalpel/androscalpel", features = ["code-analysis"] }
#apk_frauder = { path = "../../androscalpel/apk_frauder"}
anyhow = { version = "1.0.95", features = ["backtrace"] }
clap = { version = "4.5.27", features = ["derive"] }
env_logger = "0.11.6"
reqwest = { version = "0.12.12", default-features = false, features = ["blocking", "rustls-tls"] }
serde = "1.0.217"
serde_json = "1.0.138"
log = "0.4.25"

View file

@ -1,3 +1,4 @@
use anyhow::Context;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Cursor, Read};
@ -5,6 +6,7 @@ use std::path::PathBuf;
use androscalpel::{Apk, Class, IdType};
use androscalpel::SmaliName;
use patcher::{
code_loading_patcher::{insert_code, CodePatchingStrategy},
labeling,
@ -58,7 +60,21 @@ fn main() {
if let Some(class) = apk.get_class_mut(&method.class_) {
//println!("{:#?}", class.direct_methods.keys());
//println!("{:#?}", class.virtual_methods.keys());
let method = class.virtual_methods.get_mut(method).unwrap();
let method = if let Some(method) = class.virtual_methods.get_mut(method) {
method
} else {
class
.direct_methods
.get_mut(method)
.with_context(|| {
format!(
"method {} not found in {}",
method.try_to_smali().unwrap(),
class.descriptor.try_to_smali().unwrap()
)
})
.unwrap()
};
transform_method(method, &rt_data, test_class.clone(), &mut test_methods).unwrap();
}
}
@ -95,5 +111,6 @@ fn main() {
cli.apksigner,
cli.keypassword.as_deref(),
None::<HashMap<_, Option<Cursor<&[u8]>>>>,
);
)
.unwrap();
}

View file

@ -30,9 +30,15 @@ pub fn insert_code(
/// For now, we ignore class collision.
fn insert_code_naive(apk: &mut Apk, data: &RuntimeData) -> Result<()> {
for dyn_data in &data.dyn_code_load {
for file in &dyn_data.files {
let file = File::open(file)?;
apk.add_code(file, crate::labeling, false)?;
for file_name in &dyn_data.files {
let file = File::open(file_name)?;
apk.add_code(file, crate::labeling, false)
.with_context(|| {
format!(
"Could not add code from {}",
file_name.to_str().unwrap_or("<failed to parse file name>")
)
})?;
}
}
Ok(())
@ -60,9 +66,15 @@ fn insert_code_model_class_loaders(apk: &mut Apk, runtime_data: &mut RuntimeData
for dyn_data in &runtime_data.dyn_code_load {
let mut apk = Apk::new();
let class = dyn_data.classloader_class.clone();
for file in &dyn_data.files {
let file = File::open(file)?;
apk.add_code(file, crate::labeling, false)?;
for file_name in &dyn_data.files {
let file = File::open(file_name)?;
apk.add_code(file, crate::labeling, false)
.with_context(|| {
format!(
"Could not add code from {}",
file_name.to_str().unwrap_or("<failed to parse file name>")
)
})?;
}
assert!(

View file

@ -1,4 +1,5 @@
import os
import time
import argparse
import subprocess
import tempfile
@ -127,11 +128,20 @@ def main():
else:
keytool = args.keytool
runner_f = None
if args.runner_script is not None and args.runner_script.name.endswith(".py"):
runner_f = lambda: subprocess.run(["python3", str(args.runner_script)])
def runner_f():
time.sleep(1)
subprocess.run(["python3", str(args.runner_script)])
elif args.runner_script is not None and args.runner_script.name.endswith(".sh"):
runner_f = lambda: subprocess.run(["bash", str(args.runner_script)])
def runner_f():
time.sleep(1)
subprocess.run(["bash", str(args.runner_script)])
else:
runner_f = None
if zipalign is None:
print(

View file

@ -21,6 +21,6 @@ pip install "${FOLDER}/dist/theseus_autopatcher-0.1.0-py3-none-any.whl[grodd]"
adb wait-for-device
#theseus-autopatch -a "${FOLDER}/../test_apks/dynloading/build/test_dynloading.apk" -o /tmp/patched_dynloading.apk -k "${FOLDER}/../test_apks/dynloading/ToyKey.keystore"
theseus-autopatch -a "${FOLDER}/../test_apks/dyn_and_ref/build/test_dyn_and_ref.apk" -o /tmp/patched_dynloading.apk -k /tmp/kstore.keystore -kp 'P@ssw0rd!' --runner-script "${FOLDER}/../test_apks/dyn_and_ref/tests/test_apk.py"
theseus-autopatch -a "${FOLDER}/../test_apks/dyn_and_ref/build/test_dyn_and_ref.apk" -o /tmp/patched_dynloading.apk -k /tmp/kstore.keystore -kp 'P@ssw0rd!' --runner-script "${FOLDER}/../test_apks/dyn_and_ref/tests/test_apk.py" --patch "${FOLDER}/../patcher/target/release/patcher"
rm -rf "${TMP}"