patch code received from dyn loading
This commit is contained in:
parent
b476d04b78
commit
1c7b84261d
7 changed files with 40 additions and 16 deletions
|
|
@ -19,7 +19,7 @@ requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
collect-reflection-data = 'theseus_frida.__init__:main'
|
collect-runtime-data = 'theseus_frida.__init__:main'
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
include = [
|
include = [
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,10 @@ def handle_cnstr_new_inst_data(data, data_storage: dict):
|
||||||
def handle_load_dex(data, data_storage: dict, file_storage: Path):
|
def handle_load_dex(data, data_storage: dict, file_storage: Path):
|
||||||
dex = data["dex"]
|
dex = data["dex"]
|
||||||
classloader_class = data["classloader_class"]
|
classloader_class = data["classloader_class"]
|
||||||
classloader = data["classloader"].hex()
|
classloader = data["classloader"]
|
||||||
|
if classloader < 0:
|
||||||
|
classloader += 2 << (HASH_NB_BYTES * 8 - 1)
|
||||||
|
classloader = classloader.to_bytes(HASH_NB_BYTES).hex()
|
||||||
short_class = classloader_class.split("/")[-1].removesuffix(";")
|
short_class = classloader_class.split("/")[-1].removesuffix(";")
|
||||||
files = []
|
files = []
|
||||||
print("DEX file loaded:")
|
print("DEX file loaded:")
|
||||||
|
|
|
||||||
8
patcher/Cargo.lock
generated
8
patcher/Cargo.lock
generated
|
|
@ -35,7 +35,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "androscalpel"
|
name = "androscalpel"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b"
|
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"androscalpel_serializer",
|
"androscalpel_serializer",
|
||||||
|
|
@ -51,7 +51,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "androscalpel_serializer"
|
name = "androscalpel_serializer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b"
|
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"androscalpel_serializer_derive",
|
"androscalpel_serializer_derive",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -60,7 +60,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "androscalpel_serializer_derive"
|
name = "androscalpel_serializer_derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b"
|
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -129,7 +129,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "apk_frauder"
|
name = "apk_frauder"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b"
|
source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"androscalpel_serializer",
|
"androscalpel_serializer",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "610347554d7e46a9213f45b09b76ba7e2bce201b", features = ["code-analysis"] }
|
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 = "610347554d7e46a9213f45b09b76ba7e2bce201b"}
|
apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "4c4940e6b1e1760617d2cb86f83a27a7a8e187da"}
|
||||||
anyhow = { version = "1.0.95", features = ["backtrace"] }
|
anyhow = { version = "1.0.95", features = ["backtrace"] }
|
||||||
clap = { version = "4.5.27", features = ["derive"] }
|
clap = { version = "4.5.27", features = ["derive"] }
|
||||||
env_logger = "0.11.6"
|
env_logger = "0.11.6"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use std::path::PathBuf;
|
||||||
use androscalpel::Apk;
|
use androscalpel::Apk;
|
||||||
|
|
||||||
use patcher::{
|
use patcher::{
|
||||||
|
code_loading_patcher::insert_code,
|
||||||
labeling,
|
labeling,
|
||||||
reflection_patcher::transform_method,
|
reflection_patcher::transform_method,
|
||||||
runtime_data::RuntimeData, // ReflectionInvokeData, ReflectionClassNewInstData, ReflectionCnstrNewInstData,
|
runtime_data::RuntimeData, // ReflectionInvokeData, ReflectionClassNewInstData, ReflectionCnstrNewInstData,
|
||||||
|
|
@ -27,7 +28,7 @@ struct Cli {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
reflection_data: PathBuf,
|
runtime_data: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -36,13 +37,13 @@ fn main() {
|
||||||
let mut apk = Apk::load_apk(File::open(&cli.path).unwrap(), labeling, false).unwrap();
|
let mut apk = Apk::load_apk(File::open(&cli.path).unwrap(), labeling, false).unwrap();
|
||||||
//println!("{:#?}", apk.list_classes());
|
//println!("{:#?}", apk.list_classes());
|
||||||
let mut json = String::new();
|
let mut json = String::new();
|
||||||
File::open(&cli.reflection_data)
|
File::open(&cli.runtime_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read_to_string(&mut json)
|
.read_to_string(&mut json)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let reflection_data: RuntimeData = serde_json::from_str(&json).unwrap();
|
let rt_data: RuntimeData = serde_json::from_str(&json).unwrap();
|
||||||
/*
|
/*
|
||||||
let reflection_data = RuntimeData {
|
let rt_data = RuntimeData {
|
||||||
invoke_data: vec![
|
invoke_data: vec![
|
||||||
ReflectionInvokeData {
|
ReflectionInvokeData {
|
||||||
method: IdMethod::from_smali(
|
method: IdMethod::from_smali(
|
||||||
|
|
@ -112,14 +113,15 @@ fn main() {
|
||||||
addr: 0x22,
|
addr: 0x22,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
println!("{}", serde_json::to_string(&reflection_data).unwrap());
|
println!("{}", serde_json::to_string(&rt_data).unwrap());
|
||||||
*/
|
*/
|
||||||
for method in reflection_data.get_method_referenced().iter() {
|
insert_code(&mut apk, &rt_data).unwrap();
|
||||||
|
for method in rt_data.get_method_referenced().iter() {
|
||||||
if let Some(class) = apk.get_class_mut(&method.class_) {
|
if let Some(class) = apk.get_class_mut(&method.class_) {
|
||||||
//println!("{:#?}", class.direct_methods.keys());
|
//println!("{:#?}", class.direct_methods.keys());
|
||||||
//println!("{:#?}", class.virtual_methods.keys());
|
//println!("{:#?}", class.virtual_methods.keys());
|
||||||
let method = class.virtual_methods.get_mut(method).unwrap();
|
let method = class.virtual_methods.get_mut(method).unwrap();
|
||||||
transform_method(method, &reflection_data).unwrap();
|
transform_method(method, &rt_data).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut dex_files = vec![];
|
let mut dex_files = vec![];
|
||||||
|
|
@ -138,7 +140,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
// TODO: aapt would be a lot more stable
|
// TODO: aapt would be a lot more stable?
|
||||||
apk_frauder::replace_dex(
|
apk_frauder::replace_dex(
|
||||||
cli.path,
|
cli.path,
|
||||||
cli.out,
|
cli.out,
|
||||||
|
|
|
||||||
18
patcher/src/code_loading_patcher.rs
Normal file
18
patcher/src/code_loading_patcher.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
use androscalpel::Apk;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use crate::runtime_data::RuntimeData;
|
||||||
|
|
||||||
|
/// Insert statically bytecode that was loaded from other source at runtime.
|
||||||
|
/// For now, we ignore class collision.
|
||||||
|
pub fn insert_code(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)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use androscalpel::{IdMethod, Instruction};
|
use androscalpel::{IdMethod, Instruction};
|
||||||
|
|
||||||
|
pub mod code_loading_patcher;
|
||||||
pub mod dex_types;
|
pub mod dex_types;
|
||||||
pub mod reflection_patcher;
|
pub mod reflection_patcher;
|
||||||
pub mod register_manipulation;
|
pub mod register_manipulation;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue