diff --git a/TODO.md b/TODO.md index 6fce29f..0571f78 100644 --- a/TODO.md +++ b/TODO.md @@ -1,92 +1,8 @@ -- generate .dex -- edditable code format -- json serialize with serde - sanity checks - tests - https://source.android.com/docs/core/runtime/dex-format#system-annotation +- +- Caused by: java.lang.VerifyError: Verifier rejected class androidx.appcompat.app.AppCompatViewInflater: android.view.View androidx.appcompat.app.AppCompatViewInflater.createView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean, boolean, boolean, boolean): [0xFFFFFFFF] unaligned switch table: at 32, switch offset 319 (declaration of 'androidx.appcompat.app.AppCompatViewInflater' appears in /data/app/~~P3In-lzdBi-g5oUouTDKsA==/com.example.testapplication-rXxXwHN5Yo2wxHAcnkq7iw==/base.apk -``` -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::hash::Hash; - -pub mod vectorize { - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use std::iter::FromIterator; - pub fn serialize<'a, T, K, V, S>(target: T, ser: S) -> Result - where - S: Serializer, - T: IntoIterator, - K: Serialize + 'a, - V: Serialize + 'a, - { - let container: Vec<_> = target.into_iter().collect(); - serde::Serialize::serialize(&container, ser) - } - - pub fn deserialize<'de, T, K, V, D>(des: D) -> Result - where - D: Deserializer<'de>, - T: FromIterator<(K, V)>, - K: Deserialize<'de>, - V: Deserialize<'de>, - { - let container: Vec<_> = serde::Deserialize::deserialize(des)?; - Ok(T::from_iter(container.into_iter())) - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] -struct KeyItem { - name: String, - len: u32, -} - -impl KeyItem { - fn new(s: &str) -> Self { - Self { - name: s.into(), - len: s.len() as u32, - } - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] -enum ValueItem { - String1(String), - String2(String), - Int(u32), -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] -struct ToSerialize { - #[serde(with = "vectorize")] - map1: HashMap, - #[serde(with = "vectorize")] - map2: HashMap, -} - -fn main() { - let value = ToSerialize { - map1: HashMap::from([ - (KeyItem::new("plop"), ValueItem::String1("Plop".into())), - (KeyItem::new("plip"), ValueItem::String2("Plip".into())), - (KeyItem::new("lop"), ValueItem::Int(109)), - ]), - map2: HashMap::from([( - KeyItem::new("run"), - ValueItem::String1("Demons run when a good man goes to war".into()), - )]), - }; - let serialized = serde_json::to_string(&value).unwrap(); - println!("{serialized}"); - assert_eq!( - serde_json::from_str::(&serialized).unwrap(), - value - ); -} -``` - -`cargo add serde -F derive && cargo add serde_json` diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index c609003..98c7783 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -721,6 +721,22 @@ impl Apk { let code = if code_off == 0 { None } else { + if descriptor + == IdMethod::from_smali( + "Landroidx/appcompat/app/AppCompatViewInflater;\ + ->createView(Landroid/view/View;Ljava/lang/String;\ + Landroid/content/Context;Landroid/util/AttributeSet;\ + ZZZZ)Landroid/view/View;", + ) + .unwrap() + { + let code_item = dex.get_struct_at_offset::(code_off)?; + let mut off = 0; + for ins in &code_item.insns { + println!("INS 0x{off:x}: {ins:x?}"); + off += ins.size(); + } + } Some(Self::get_code_from_off(code_off, dex).with_context(|| { format!("Failed to parse code of method {}", descriptor.__str__()) })?) diff --git a/test.py b/test.py index b635456..89ff9ca 100644 --- a/test.py +++ b/test.py @@ -59,42 +59,43 @@ print(f"[+] New code of {method_id} ") for i in code.insns: print(f" {i}") -# # Strip class for debugging -# classes = list( -# filter( -# lambda x: x -# not in [ -# IdType("Lcom/example/testapplication/ui/home/HomeViewModel;"), -# IdType("Landroidx/navigation/NavDeepLink$Builder;"), -# IdType("Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;"), -# IdType("Landroidx/appcompat/app/ActionBar;"), -# IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"), -# ], -# apk.classes.keys(), -# ) -# ) -# # for cls in classes: -# # apk.remove_class(cls) +# Strip class for debugging +classes = list( + filter( + lambda x: x + not in [ + # IdType("Lcom/example/testapplication/ui/home/HomeViewModel;"), + # IdType("Landroidx/navigation/NavDeepLink$Builder;"), + # IdType("Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;"), + # IdType("Landroidx/appcompat/app/ActionBar;"), + # IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"), + IdType("Landroidx/appcompat/app/AppCompatViewInflater;"), + ], + apk.classes.keys(), + ) +) +for cls in classes: + apk.remove_class(cls) print("[+] Recompile") dex_raw = apk.gen_raw_dex() -# new_apk = Apk() -# for dex in dex_raw: -# new_apk.add_dex_file(dex) +new_apk = Apk() +for dex in dex_raw: + new_apk.add_dex_file(dex) -print("[+] Repackage") - -utils.replace_dex( - APK_NAME, - APK_NAME.parent / (APK_NAME.name.removesuffix(".apk") + "-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", -) +# print("[+] Repackage") +# +# utils.replace_dex( +# APK_NAME, +# APK_NAME.parent / (APK_NAME.name.removesuffix(".apk") + "-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", +# ) last_id = None