diff --git a/TODO.md b/TODO.md index f081fdf..bf07a08 100644 --- a/TODO.md +++ b/TODO.md @@ -5,7 +5,7 @@ - json serialize with serde - sanity checks - tests -- PyRef +- PyRef https://pyo3.rs/v0.20.0/faq.html#pyo3get-clones-my-field - https://source.android.com/docs/core/runtime/dex-format#system-annotation diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index fa85244..f3327a9 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -7,6 +7,7 @@ use log::info; use pyo3::prelude::*; use pyo3::types::PyBytes; +use crate::ins::CallSite; use crate::instructions; use crate::*; use androscalpel_serializer::Instruction as InsFormat; diff --git a/androscalpel/src/code.rs b/androscalpel/src/code.rs index 2a462d5..05cd306 100644 --- a/androscalpel/src/code.rs +++ b/androscalpel/src/code.rs @@ -4,7 +4,7 @@ use std::collections::HashSet; use pyo3::prelude::*; -use crate::{DexString, IdField, IdMethod, IdMethodType, IdType, Instruction, MethodHandle}; +use crate::{ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle}; // TODO: make this easy to edit/manipulate, maybe move to Method diff --git a/androscalpel/src/dex_writer.rs b/androscalpel/src/dex_writer.rs index bbacb73..97757af 100644 --- a/androscalpel/src/dex_writer.rs +++ b/androscalpel/src/dex_writer.rs @@ -13,8 +13,8 @@ use crate::Result; use crate::*; use androscalpel_serializer::*; +use crate::ins::{CallSite, Instruction}; use crate::instructions::*; -use crate::Instruction; use androscalpel_serializer::Instruction as InsFormat; #[derive(Debug, Clone)] @@ -112,7 +112,8 @@ impl Default for DexWriter { Self { header: HeaderItem { magic: DexFileMagic { - version: [0x30, 0x33, 0x39], + //version: [0x30, 0x33, 0x39], + version: [0x30, 0x33, 0x37], }, // TODO: find a better default version checksum: 0, signature: [0u8; 20], diff --git a/androscalpel/src/instructions.rs b/androscalpel/src/instructions.rs index 0e5b249..5d57141 100644 --- a/androscalpel/src/instructions.rs +++ b/androscalpel/src/instructions.rs @@ -3463,9 +3463,13 @@ impl IntoPy for Instruction { #[pyclass] #[derive(Debug, Clone)] pub struct CallSite { + #[pyo3(get, set)] pub method_handle: MethodHandle, + #[pyo3(get, set)] pub name: DexString, + #[pyo3(get, set)] pub type_: IdMethodType, + #[pyo3(get, set)] pub args: Vec, } @@ -3692,7 +3696,9 @@ impl Nop { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Move { + #[pyo3(get, set)] pub from: u16, + #[pyo3(get, set)] pub to: u16, } @@ -3809,7 +3815,9 @@ impl Move { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveWide { + #[pyo3(get, set)] pub from: u16, + #[pyo3(get, set)] pub to: u16, } @@ -3925,7 +3933,9 @@ impl MoveWide { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveObject { + #[pyo3(get, set)] pub from: u16, + #[pyo3(get, set)] pub to: u16, } @@ -4034,6 +4044,7 @@ impl MoveObject { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveResult { + #[pyo3(get, set)] pub to: u8, } @@ -4129,6 +4140,7 @@ impl MoveResult { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveResultWide { + #[pyo3(get, set)] pub to: u8, } @@ -4224,6 +4236,7 @@ impl MoveResultWide { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveResultObject { + #[pyo3(get, set)] pub to: u8, } @@ -4319,6 +4332,7 @@ impl MoveResultObject { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MoveException { + #[pyo3(get, set)] pub to: u8, } @@ -4510,6 +4524,7 @@ impl ReturnVoid { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Return { + #[pyo3(get, set)] pub reg: u8, } @@ -4605,6 +4620,7 @@ impl Return { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReturnWide { + #[pyo3(get, set)] pub reg: u8, } @@ -4700,6 +4716,7 @@ impl ReturnWide { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReturnObject { + #[pyo3(get, set)] pub reg: u8, } @@ -4803,7 +4820,9 @@ impl ReturnObject { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Const { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: i32, } @@ -4925,7 +4944,9 @@ impl Const { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ConstWide { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: i64, } @@ -5045,7 +5066,9 @@ impl ConstWide { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstString { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: DexString, } @@ -5144,7 +5167,9 @@ impl ConstString { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstClass { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: IdType, } @@ -5247,6 +5272,7 @@ impl ConstClass { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MonitorEnter { + #[pyo3(get, set)] pub reg: u8, } @@ -5342,6 +5368,7 @@ impl MonitorEnter { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MonitorExit { + #[pyo3(get, set)] pub reg: u8, } @@ -5438,7 +5465,9 @@ impl MonitorExit { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct CheckCast { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: IdType, } @@ -5542,8 +5571,11 @@ impl CheckCast { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InstanceOf { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub lit: IdType, } @@ -5672,7 +5704,9 @@ impl InstanceOf { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ArrayLength { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, } @@ -5787,7 +5821,9 @@ impl ArrayLength { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct NewInstance { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub lit: IdType, } @@ -5890,8 +5926,11 @@ impl NewInstance { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct NewArray { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub size_reg: u8, + #[pyo3(get, set)] pub lit: IdType, } @@ -6028,7 +6067,9 @@ impl NewArray { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct FilledNewArray { + #[pyo3(get, set)] pub type_: IdType, + #[pyo3(get, set)] pub reg_values: Vec, } @@ -6238,8 +6279,11 @@ impl FilledNewArray { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct FillArrayData { + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub elt_width: u16, + #[pyo3(get, set)] pub data: Vec, } @@ -6393,6 +6437,7 @@ impl FillArrayData { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Throw { + #[pyo3(get, set)] pub reg: u8, } @@ -6488,6 +6533,7 @@ impl Throw { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Goto { + #[pyo3(get, set)] pub label: String, } @@ -6627,7 +6673,9 @@ impl Goto { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Switch { + #[pyo3(get, set)] pub reg: u8, + #[pyo3(get, set)] pub branches: HashMap, } @@ -6752,8 +6800,11 @@ impl Switch { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CmpLFloat { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub c: u8, } @@ -6859,8 +6910,11 @@ impl CmpLFloat { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CmpGFloat { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub c: u8, } @@ -6966,8 +7020,11 @@ impl CmpGFloat { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CmpLDouble { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub c: u8, } @@ -7073,8 +7130,11 @@ impl CmpLDouble { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CmpGDouble { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub c: u8, } @@ -7179,8 +7239,11 @@ impl CmpGDouble { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CmpLong { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub c: u8, } @@ -7281,8 +7344,11 @@ impl CmpLong { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfEq { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -7400,8 +7466,11 @@ impl IfEq { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfNe { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -7520,8 +7589,11 @@ impl IfNe { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfLt { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -7640,8 +7712,11 @@ impl IfLt { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfGe { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -7760,8 +7835,11 @@ impl IfGe { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfGt { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -7880,8 +7958,11 @@ impl IfGt { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfLe { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub b: u8, + #[pyo3(get, set)] pub label: String, } @@ -8000,7 +8081,9 @@ impl IfLe { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfEqZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8101,7 +8184,9 @@ impl IfEqZ { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfNeZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8202,7 +8287,9 @@ impl IfNeZ { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfLtZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8303,7 +8390,9 @@ impl IfLtZ { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfGeZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8404,7 +8493,9 @@ impl IfGeZ { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfGtZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8505,7 +8596,9 @@ impl IfGtZ { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IfLeZ { + #[pyo3(get, set)] pub a: u8, + #[pyo3(get, set)] pub label: String, } @@ -8606,8 +8699,11 @@ impl IfLeZ { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGet { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -8708,8 +8804,11 @@ impl AGet { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetWide { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -8810,8 +8909,11 @@ impl AGetWide { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetObject { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -8912,8 +9014,11 @@ impl AGetObject { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetBoolean { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9014,8 +9119,11 @@ impl AGetBoolean { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetByte { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9116,8 +9224,11 @@ impl AGetByte { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetChar { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9218,8 +9329,11 @@ impl AGetChar { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AGetShort { + #[pyo3(get, set)] pub dest: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9320,8 +9434,11 @@ impl AGetShort { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APut { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9422,8 +9539,11 @@ impl APut { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutWide { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9524,8 +9644,11 @@ impl APutWide { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutObject { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9626,8 +9749,11 @@ impl APutObject { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutBoolean { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9728,8 +9854,11 @@ impl APutBoolean { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutByte { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9830,8 +9959,11 @@ impl APutByte { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutChar { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -9932,8 +10064,11 @@ impl APutChar { #[pyclass] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct APutShort { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub arr: u8, + #[pyo3(get, set)] pub idx: u8, } @@ -10036,8 +10171,11 @@ impl APutShort { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGet { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10165,8 +10303,11 @@ impl IGet { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetWide { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10298,8 +10439,11 @@ impl IGetWide { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetObject { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10431,8 +10575,11 @@ impl IGetObject { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetBoolean { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10565,8 +10712,11 @@ impl IGetBoolean { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetByte { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10698,8 +10848,11 @@ impl IGetByte { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetChar { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10831,8 +10984,11 @@ impl IGetChar { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IGetShort { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -10964,8 +11120,11 @@ impl IGetShort { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPut { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11093,8 +11252,11 @@ impl IPut { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutWide { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11226,8 +11388,11 @@ impl IPutWide { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutObject { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11359,8 +11524,11 @@ impl IPutObject { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutBoolean { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11492,8 +11660,11 @@ impl IPutBoolean { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutByte { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11625,8 +11796,11 @@ impl IPutByte { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutChar { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11758,8 +11932,11 @@ impl IPutChar { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct IPutShort { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub obj: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11889,7 +12066,9 @@ impl IPutShort { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGet { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -11990,7 +12169,9 @@ impl SGet { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetWide { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12095,7 +12276,9 @@ impl SGetWide { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetObject { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12200,7 +12383,9 @@ impl SGetObject { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetBoolean { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12305,7 +12490,9 @@ impl SGetBoolean { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetByte { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12410,7 +12597,9 @@ impl SGetByte { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetChar { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12515,7 +12704,9 @@ impl SGetChar { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SGetShort { + #[pyo3(get, set)] pub to: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12620,7 +12811,9 @@ impl SGetShort { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPut { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12726,7 +12919,9 @@ impl SPut { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutWide { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12831,7 +13026,9 @@ impl SPutWide { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutObject { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -12936,7 +13133,9 @@ impl SPutObject { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutBoolean { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -13041,7 +13240,9 @@ impl SPutBoolean { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutByte { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -13146,7 +13347,9 @@ impl SPutByte { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutChar { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -13251,7 +13454,9 @@ impl SPutChar { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct SPutShort { + #[pyo3(get, set)] pub from: u8, + #[pyo3(get, set)] pub field: IdField, } @@ -13356,7 +13561,9 @@ impl SPutShort { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeVirtual { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub args: Vec, } @@ -13561,7 +13768,9 @@ impl InvokeVirtual { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeSuper { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub args: Vec, } @@ -13766,7 +13975,9 @@ impl InvokeSuper { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeDirect { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub args: Vec, } @@ -13971,7 +14182,9 @@ impl InvokeDirect { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeStatic { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub args: Vec, } @@ -14176,7 +14389,9 @@ impl InvokeStatic { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeInterface { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub args: Vec, } @@ -25507,8 +25722,11 @@ impl UshrIntLit { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokePolymorphic { + #[pyo3(get, set)] pub method: IdMethod, + #[pyo3(get, set)] pub proto: IdMethodType, + #[pyo3(get, set)] pub args: Vec, } @@ -25732,7 +25950,9 @@ impl InvokePolymorphic { #[pyclass] #[derive(Debug, Clone)] pub struct InvokeCustom { + #[pyo3(get, set)] pub call_site: CallSite, + #[pyo3(get, set)] pub args: Vec, } @@ -25935,7 +26155,9 @@ impl InvokeCustom { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstMethodHandle { + #[pyo3(get, set)] pub handle: MethodHandle, + #[pyo3(get, set)] pub to: u8, } @@ -26038,7 +26260,9 @@ impl ConstMethodHandle { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstMethodType { + #[pyo3(get, set)] pub proto: IdMethodType, + #[pyo3(get, set)] pub to: u8, } @@ -26143,6 +26367,7 @@ impl ConstMethodType { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Try { + #[pyo3(get, set)] pub end_label: String, /// The list of exceptions and their associated handler label. /// @@ -26150,7 +26375,9 @@ pub struct Try { /// /// The handler are sorted: if severat Exception Type match an exceptions, the /// the handler used is the first in the list. + #[pyo3(get, set)] pub handlers: Vec<(IdType, String)>, + #[pyo3(get, set)] pub default_handler: Option, } @@ -26277,6 +26504,7 @@ impl Try { #[pyclass] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Label { + #[pyo3(get, set)] pub name: String, } diff --git a/androscalpel/src/lib.rs b/androscalpel/src/lib.rs index a67b995..7375fe9 100644 --- a/androscalpel/src/lib.rs +++ b/androscalpel/src/lib.rs @@ -24,7 +24,7 @@ pub use dex_id::*; pub use dex_string::*; pub use dex_writer::*; pub use field::*; -pub use instructions::{CallSite, Instruction}; +pub use instructions as ins; pub use method::*; pub use method_handle::*; pub use scalar::*; @@ -32,7 +32,7 @@ pub use value::*; /// Androscalpel. #[pymodule] -fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> { +fn androscalpel(py: Python, m: &PyModule) -> PyResult<()> { pyo3_log::init(); m.add_class::()?; m.add_class::()?; @@ -71,5 +71,210 @@ fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; + + let ins_module = PyModule::new(py, "ins")?; + androscalpel_ins(py, ins_module)?; + m.add_submodule(ins_module)?; + + Ok(()) +} + +/// Dalvik opcode for Androscalpel. +fn androscalpel_ins(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; Ok(()) } diff --git a/androscalpel/src/method.rs b/androscalpel/src/method.rs index ac0f45d..9820749 100644 --- a/androscalpel/src/method.rs +++ b/androscalpel/src/method.rs @@ -62,6 +62,7 @@ pub struct Method { pub parameters_annotations: Vec>, /// The code of the method + #[pyo3(get, set)] pub code: Option, } diff --git a/androscalpel_serializer/src/value.rs b/androscalpel_serializer/src/value.rs index 759cf04..84a1e1a 100644 --- a/androscalpel_serializer/src/value.rs +++ b/androscalpel_serializer/src/value.rs @@ -599,7 +599,7 @@ impl Serializable for EncodedValue { .rev() .take_while(|b| **b == 0) .count(); - 1 + 4 - trailing_zeros + std::cmp::max(1 + 4 - trailing_zeros, 2) } Self::Double(val) => { let trailing_zeros = val @@ -608,7 +608,7 @@ impl Serializable for EncodedValue { .rev() .take_while(|b| **b == 0) .count(); - 1 + 8 - trailing_zeros + std::cmp::max(1 + 8 - trailing_zeros, 2) } Self::MethodType(idx) => Idx(*idx, VALUE_TYPE).size(), Self::MethodHandle(idx) => Idx(*idx, VALUE_METHOD_HANDLE).size(), diff --git a/test.py b/test.py index 084143e..0a18628 100644 --- a/test.py +++ b/test.py @@ -8,7 +8,8 @@ import androscalpel as asc import zipfile as z from androscalpel import * -APK_NAME = "test.apk" +# APK_NAME = "test.apk" +APK_NAME = "/home/histausse/workspace/androscalpel/apk_frauder/app-release.apk" DEX_NAME = "classes.dex" with z.ZipFile(APK_NAME) as zipf: @@ -18,4 +19,32 @@ with z.ZipFile(APK_NAME) as zipf: apk = asc.Apk() apk.add_dex_file(dex) +clazz_id = IdType("Lcom/example/testapplication/ui/home/HomeViewModel;") +proto_id = IdMethodType(IdType("Ljava/lang/String;"), []) +method_id = IdMethod("text_gen", proto_id, clazz_id) + +clazz = apk.classes[clazz_id] +method = clazz.virtual_methods[method_id] + +print("Code of {method_id}") +for i in method.code.insns: + print(i) + +new_insns = [] +for i in method.code.insns: + if isinstance(i, asc.ins.ConstString): + if i.lit == "Hello": + i.lit = DexString("Degemer Mat") + elif i.lit == "Bye": + i.lit = DexString("Kenavo") + new_insns.append(i) + +# This need improving! +new_code = method.code +new_code.insns = new_insns +method.code = new_code +clazz.virtual_methods[method_id] = method +apk.classes[clazz_id] = clazz + + dex_raw = apk.gen_raw_dex()