add repackaging to utils

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-02-01 23:37:26 +01:00
parent cb34f76063
commit 2cf3963532
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
5 changed files with 52 additions and 8 deletions

4
.gitignore vendored
View file

@ -3,3 +3,7 @@
/venv_test /venv_test
/test.apk /test.apk
/androguard_test.py /androguard_test.py
*.apk
*.dex
*.idsig
*.jks

1
Cargo.lock generated
View file

@ -24,6 +24,7 @@ dependencies = [
"adler", "adler",
"androscalpel_serializer", "androscalpel_serializer",
"anyhow", "anyhow",
"apk_frauder",
"log", "log",
"pyo3 0.20.0", "pyo3 0.20.0",
"pyo3-log", "pyo3-log",

View file

@ -12,6 +12,7 @@ crate-type = ["cdylib"]
adler = "1.0.2" adler = "1.0.2"
androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" } androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" }
anyhow = { version = "1.0.75", features = ["backtrace"] } anyhow = { version = "1.0.75", features = ["backtrace"] }
apk_frauder = { version = "0.1.0", path = "../apk_frauder" }
log = "0.4.20" log = "0.4.20"
pyo3 = { version = "0.20.0", features = ["anyhow"] } pyo3 = { version = "0.20.0", features = ["anyhow"] }
pyo3-log = "0.8.3" pyo3-log = "0.8.3"

View file

@ -3,6 +3,9 @@
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyBytes; use pyo3::types::PyBytes;
use std::io::Cursor;
use std::path::PathBuf;
use crate::Result; use crate::Result;
use androscalpel_serializer::{Serializable, Sleb128, Uleb128, Uleb128p1}; use androscalpel_serializer::{Serializable, Sleb128, Uleb128, Uleb128p1};
@ -41,6 +44,27 @@ pub fn sleb128_to_int(b: &[u8]) -> Result<i32> {
Ok(Sleb128::deserialize_from_slice(b)?.0) Ok(Sleb128::deserialize_from_slice(b)?.0)
} }
/// Replace the dex files a an apk an resigned the apk.
///
/// # Warning
///
/// For now, only jks keystore are allowed.
///
/// The `zipalign` and `apksigner` args allow to use a specific version of the
/// tools instead of the one in the PATH (if it even exist)
#[pyfunction]
pub fn replace_dex(
apk: PathBuf,
dst: PathBuf,
dexfiles: Vec<&[u8]>,
keystore: PathBuf,
zipalign: Option<PathBuf>,
apksigner: Option<PathBuf>,
) {
let mut dexfiles: Vec<_> = dexfiles.iter().map(Cursor::new).collect();
apk_frauder::replace_dex(apk, dst, &mut dexfiles, keystore, zipalign, apksigner)
}
/// export the function in a python module /// export the function in a python module
pub(crate) fn export_module(_py: Python, m: &PyModule) -> PyResult<()> { pub(crate) fn export_module(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(int_to_uleb128, m)?)?; m.add_function(wrap_pyfunction!(int_to_uleb128, m)?)?;
@ -49,5 +73,6 @@ pub(crate) fn export_module(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(uleb128_to_int, m)?)?; m.add_function(wrap_pyfunction!(uleb128_to_int, m)?)?;
m.add_function(wrap_pyfunction!(uleb128p1_to_int, m)?)?; m.add_function(wrap_pyfunction!(uleb128p1_to_int, m)?)?;
m.add_function(wrap_pyfunction!(sleb128_to_int, m)?)?; m.add_function(wrap_pyfunction!(sleb128_to_int, m)?)?;
m.add_function(wrap_pyfunction!(replace_dex, m)?)?;
Ok(()) Ok(())
} }

27
test.py
View file

@ -8,9 +8,10 @@ import json
import androscalpel as asc import androscalpel as asc
import zipfile as z import zipfile as z
from androscalpel import * from androscalpel import *
from pathlib import Path
# APK_NAME = "test.apk" # APK_NAME = Path(__file__).parent / "test.apk"
APK_NAME = __file__.removesuffix("test.py") + "/apk_frauder/app-release.apk" APK_NAME = Path(__file__).parent / "app-release.apk"
DEX_NAME = "classes.dex" DEX_NAME = "classes.dex"
with z.ZipFile(APK_NAME) as zipf: with z.ZipFile(APK_NAME) as zipf:
@ -74,14 +75,26 @@ for i in code.insns:
print("[+] Recompile") print("[+] Recompile")
dex_raw = apk.gen_raw_dex() dex_raw = apk.gen_raw_dex()
assert len(dex_raw) == 1
with open(DEX_NAME, "wb") as file: utils.replace_dex(
file.write(dex_raw[0]) APK_NAME,
APK_NAME.parent / "app-instrumented.apk",
dex_raw,
Path().parent / "my-release-key.jks",
zipalign=Path.home() / "Android" / "Sdk" / "build-tools" / "34.0.0" / "zipalign",
apksigner=Path.home() / "Android" / "Sdk" / "build-tools" / "34.0.0" / "apksigner",
)
# assert len(dex_raw) == 1
# with open(DEX_NAME, "wb") as file:
# file.write(dex_raw[0])
#
# with open(DEX_NAME, "rb") as file:
# dex = file.read()
print("[+] Load new dex") print("[+] Load new dex")
with open(DEX_NAME, "rb") as file:
dex = file.read()
new_apk = asc.Apk() new_apk = asc.Apk()
for dex in dex_raw:
new_apk.add_dex_file(dex) new_apk.add_dex_file(dex)
clazz = new_apk.classes[clazz_id] clazz = new_apk.classes[clazz_id]