WIP
This commit is contained in:
parent
dfcd6232a4
commit
1d62277f42
5 changed files with 92 additions and 15 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
|
@ -26,6 +26,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"apk_frauder",
|
"apk_frauder",
|
||||||
"log",
|
"log",
|
||||||
|
"pretty_assertions",
|
||||||
"pyo3",
|
"pyo3",
|
||||||
"pyo3-log",
|
"pyo3-log",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
|
@ -180,6 +181,12 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diff"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
|
@ -347,6 +354,16 @@ version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty_assertions"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||||
|
dependencies = [
|
||||||
|
"diff",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.78"
|
version = "1.0.78"
|
||||||
|
|
@ -668,3 +685,9 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ serde = { version = "1.0.195", features = ["derive"] }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
sha1 = "0.10.6"
|
sha1 = "0.10.6"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pretty_assertions = "1.4.1"
|
||||||
|
|
||||||
#[features]
|
#[features]
|
||||||
#extension-module = ["pyo3/extension-module"]
|
#extension-module = ["pyo3/extension-module"]
|
||||||
|
|
|
||||||
|
|
@ -830,32 +830,32 @@ impl Apk {
|
||||||
let ins = match format.clone() {
|
let ins = match format.clone() {
|
||||||
Format10X { op: 0x00 } => Instruction::Nop {},
|
Format10X { op: 0x00 } => Instruction::Nop {},
|
||||||
Format12X { op: 0x01, va, vb } => Instruction::Move {
|
Format12X { op: 0x01, va, vb } => Instruction::Move {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb as u16,
|
from: vb as u16,
|
||||||
},
|
},
|
||||||
Format22X { op: 0x02, va, vb } => Instruction::Move {
|
Format22X { op: 0x02, va, vb } => Instruction::Move {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb,
|
from: vb,
|
||||||
},
|
},
|
||||||
Format32X { op: 0x03, va, vb } => Instruction::Move { from: va, to: vb },
|
Format32X { op: 0x03, va, vb } => Instruction::Move { to: va, from: vb },
|
||||||
Format12X { op: 0x04, va, vb } => Instruction::MoveWide {
|
Format12X { op: 0x04, va, vb } => Instruction::MoveWide {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb as u16,
|
from: vb as u16,
|
||||||
},
|
},
|
||||||
Format22X { op: 0x05, va, vb } => Instruction::MoveWide {
|
Format22X { op: 0x05, va, vb } => Instruction::MoveWide {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb,
|
from: vb,
|
||||||
},
|
},
|
||||||
Format32X { op: 0x06, va, vb } => Instruction::MoveWide { from: va, to: vb },
|
Format32X { op: 0x06, va, vb } => Instruction::MoveWide { to: va, from: vb },
|
||||||
Format12X { op: 0x07, va, vb } => Instruction::MoveObject {
|
Format12X { op: 0x07, va, vb } => Instruction::MoveObject {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb as u16,
|
from: vb as u16,
|
||||||
},
|
},
|
||||||
Format22X { op: 0x08, va, vb } => Instruction::MoveObject {
|
Format22X { op: 0x08, va, vb } => Instruction::MoveObject {
|
||||||
from: va as u16,
|
to: va as u16,
|
||||||
to: vb,
|
from: vb,
|
||||||
},
|
},
|
||||||
Format32X { op: 0x09, va, vb } => Instruction::MoveObject { from: va, to: vb },
|
Format32X { op: 0x09, va, vb } => Instruction::MoveObject { to: va, from: vb },
|
||||||
Format11X { op: 0x0a, va } => Instruction::MoveResult { to: va },
|
Format11X { op: 0x0a, va } => Instruction::MoveResult { to: va },
|
||||||
Format11X { op: 0x0b, va } => Instruction::MoveResultWide { to: va },
|
Format11X { op: 0x0b, va } => Instruction::MoveResultWide { to: va },
|
||||||
Format11X { op: 0x0c, va } => Instruction::MoveResultObject { to: va },
|
Format11X { op: 0x0c, va } => Instruction::MoveResultObject { to: va },
|
||||||
|
|
@ -2948,6 +2948,23 @@ impl Apk {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check for android platform classes?
|
||||||
|
/// Search for the given class. If several classes with the same name are found,
|
||||||
|
/// return the class used by android (classes.dex over classes2.dex over classes3.dex until
|
||||||
|
/// classesN.dex does not exists),
|
||||||
|
/// and if not found in files used by android, look in any other files (classes0.dex,
|
||||||
|
/// classses1.dex, classes02.dex, assets/stuff.dex, ...), and select the first one in
|
||||||
|
/// alphabetical order of dex file name.
|
||||||
|
pub fn get_class(&self, class_id: &IdType) -> Option<&Class> {
|
||||||
|
self.get_file_of_class(class_id, false).and_then(|file| {
|
||||||
|
self.dex_files
|
||||||
|
.get(&file)
|
||||||
|
.expect("`get_file_of_class()` return a string not in `dex_files`")
|
||||||
|
.classes
|
||||||
|
.get(class_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Search for the dex file of a given class. If several classes with the same name exist,
|
/// Search for the dex file of a given class. If several classes with the same name exist,
|
||||||
/// return the file used by android (classes.dex over classes2.dex over classes3.dex until
|
/// return the file used by android (classes.dex over classes2.dex over classes3.dex until
|
||||||
/// classesN.dex does not exists), and if `valid_file_only` is set to false, look in any
|
/// classesN.dex does not exists), and if `valid_file_only` is set to false, look in any
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,16 @@ pub struct Method {
|
||||||
#[pyo3(get)]
|
#[pyo3(get)]
|
||||||
pub code: Option<Code>,
|
pub code: Option<Code>,
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
impl PartialEq for Method {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
let res = self.code.eq(other.code);
|
||||||
|
if !res {
|
||||||
|
panic!("{} code don't match", self.descriptor.__str__());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/// Represent the visibility of a field
|
/// Represent the visibility of a field
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ use std::ops::Deref;
|
||||||
use std::sync::{Mutex, OnceLock};
|
use std::sync::{Mutex, OnceLock};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
//use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
fn write_to_report(data: &str) {
|
fn write_to_report(data: &str) {
|
||||||
static REPORT_FILE: Mutex<Option<File>> = Mutex::new(None);
|
static REPORT_FILE: Mutex<Option<File>> = Mutex::new(None);
|
||||||
let mut report_file = REPORT_FILE.lock().unwrap();
|
let mut report_file = REPORT_FILE.lock().unwrap();
|
||||||
|
|
@ -144,6 +146,29 @@ fn test_generated_apk_equivalence() {
|
||||||
new_apk
|
new_apk
|
||||||
.add_dex_file("classes.dex", &new_dex, false, false)
|
.add_dex_file("classes.dex", &new_dex, false, false)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
/*
|
||||||
|
let method = IdMethod::from_smali(
|
||||||
|
"Lkotlinx/coroutines/flow/internal/SafeCollector_commonKt$unsafeFlow$1$collect$1;->\
|
||||||
|
invokeSuspend(\
|
||||||
|
Ljava/lang/Object;\
|
||||||
|
)\
|
||||||
|
Ljava/lang/Object;",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
get_hello_world_apk()
|
||||||
|
.get_class(&method.class_)
|
||||||
|
.unwrap()
|
||||||
|
.virtual_methods
|
||||||
|
.get(&method)
|
||||||
|
.unwrap(),
|
||||||
|
new_apk
|
||||||
|
.get_class(&method.class_)
|
||||||
|
.unwrap()
|
||||||
|
.virtual_methods
|
||||||
|
.get(&method)
|
||||||
|
.unwrap()
|
||||||
|
);*/
|
||||||
assert_eq!(get_hello_world_apk(), &new_apk);
|
assert_eq!(get_hello_world_apk(), &new_apk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue