serialize to json

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-01-24 11:32:49 +01:00
parent ebaeaef877
commit eece6178f9
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
18 changed files with 2515 additions and 293 deletions

57
Cargo.lock generated
View file

@ -27,6 +27,8 @@ dependencies = [
"log", "log",
"pyo3 0.20.0", "pyo3 0.20.0",
"pyo3-log", "pyo3-log",
"serde",
"serde_json",
"sha1", "sha1",
] ]
@ -207,6 +209,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.151" version = "0.2.151"
@ -318,9 +326,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -421,9 +429,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.33" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -452,12 +460,49 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.6"
@ -477,9 +522,9 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.29" version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -15,4 +15,6 @@ anyhow = { version = "1.0.75", features = ["backtrace"] }
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"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"
sha1 = "0.10.6" sha1 = "0.10.6"

View file

@ -1,15 +1,18 @@
//! Annotations (for class, fields, methods and parameters alike). //! Annotations (for class, fields, methods and parameters alike).
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::hashmap_vectorize;
use crate::{ use crate::{
dex_id::IdType, value::DexValue, DexString, IdField, IdMethod, IdMethodType, MethodHandle, dex_id::IdType, value::DexValue, DexString, IdField, IdMethod, IdMethodType, MethodHandle,
Result,
}; };
/// Annotation with a visibility /// Annotation with a visibility
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct DexAnnotationItem { pub struct DexAnnotationItem {
// TODO: the get/set will probably be wonky on the python side when edditing // TODO: the get/set will probably be wonky on the python side when edditing
/// The actual annotation /// The actual annotation
@ -93,11 +96,20 @@ impl DexAnnotationItem {
pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> { pub fn get_all_method_handles(&self) -> HashSet<MethodHandle> {
self.annotation.get_all_method_handles() self.annotation.get_all_method_handles()
} }
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
} }
/// An annotation. /// An annotation.
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct DexAnnotation { pub struct DexAnnotation {
// TODO: check the relation between type and encoded_value. // TODO: check the relation between type and encoded_value.
/// The type of the annotation. /// The type of the annotation.
@ -106,6 +118,7 @@ pub struct DexAnnotation {
// TODO: the get/set will probably be wonky on the python side when edditing // TODO: the get/set will probably be wonky on the python side when edditing
/// The annotation elements. /// The annotation elements.
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub elements: HashMap<DexString, DexValue>, // TODO: check MemberName syntax? pub elements: HashMap<DexString, DexValue>, // TODO: check MemberName syntax?
} }
@ -186,4 +199,13 @@ impl DexAnnotation {
} }
methods methods
} }
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
} }

View file

@ -1,23 +1,27 @@
//! Representation of an apk. //! Representation of an apk.
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context};
use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use log::info; use log::info;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyBytes; use pyo3::types::PyBytes;
use crate::hashmap_vectorize;
use crate::ins::CallSite; use crate::ins::CallSite;
use crate::instructions; use crate::instructions;
use crate::Result;
use crate::*; use crate::*;
use androscalpel_serializer::Instruction as InsFormat; use androscalpel_serializer::Instruction as InsFormat;
use androscalpel_serializer::*; use androscalpel_serializer::*;
/// Represent an apk. /// Represent an apk.
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Apk { pub struct Apk {
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub classes: HashMap<IdType, Class>, pub classes: HashMap<IdType, Class>,
} }
@ -2368,4 +2372,13 @@ impl Apk {
.map(|bytes| PyBytes::new(py, &bytes).into()) .map(|bytes| PyBytes::new(py, &bytes).into())
.collect()) .collect())
} }
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
} }

View file

@ -1,9 +1,11 @@
//! Representation of a class. //! Representation of a class.
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::hashmap_vectorize;
use crate::{ use crate::{
DexAnnotationItem, DexString, Field, IdField, IdMethod, IdMethodType, IdType, Method, DexAnnotationItem, DexString, Field, IdField, IdMethod, IdMethodType, IdType, Method,
MethodHandle, Result, MethodHandle, Result,
@ -12,7 +14,7 @@ use androscalpel_serializer::consts::*;
/// Represent an apk /// Represent an apk
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Class { pub struct Class {
/// Type, format described at /// Type, format described at
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor> /// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
@ -54,15 +56,19 @@ pub struct Class {
/// The static fields /// The static fields
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub static_fields: HashMap<IdField, Field>, pub static_fields: HashMap<IdField, Field>,
/// The instance fields /// The instance fields
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub instance_fields: HashMap<IdField, Field>, pub instance_fields: HashMap<IdField, Field>,
/// The direct (static, private or constructor) methods of the class /// The direct (static, private or constructor) methods of the class
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub direct_methods: HashMap<IdMethod, Method>, pub direct_methods: HashMap<IdMethod, Method>,
/// The virtual (ie non direct) methods of the class /// The virtual (ie non direct) methods of the class
#[pyo3(get)] #[pyo3(get)]
#[serde(with = "hashmap_vectorize")]
pub virtual_methods: HashMap<IdMethod, Method>, pub virtual_methods: HashMap<IdMethod, Method>,
// Do we need to distinguish direct and virtual (all the other) methods? // Do we need to distinguish direct and virtual (all the other) methods?
// Maybe overlapping descriptor (same name, class and proto?) // Maybe overlapping descriptor (same name, class and proto?)
@ -75,6 +81,15 @@ pub struct Class {
#[pymethods] #[pymethods]
impl Class { impl Class {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(name: DexString) -> Result<Self> { pub fn new(name: DexString) -> Result<Self> {
Ok(Self { Ok(Self {

View file

@ -1,10 +1,13 @@
//! Representation of a method. //! Representation of a method.
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle}; use crate::{
ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result,
};
// TODO: make this easy to edit/manipulate, maybe move to Method // TODO: make this easy to edit/manipulate, maybe move to Method
@ -12,7 +15,7 @@ use crate::{ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType
/// The code run by a method. /// The code run by a method.
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Code { pub struct Code {
// TODO: remove and compute this value from code? // TODO: remove and compute this value from code?
/// The number of registers used by the code /// The number of registers used by the code
@ -37,6 +40,15 @@ pub struct Code {
#[pymethods] #[pymethods]
impl Code { impl Code {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new( pub fn new(
registers_size: u16, registers_size: u16,

View file

@ -1,5 +1,6 @@
//! The class identifying dex structure. //! The class identifying dex structure.
use serde::{Deserialize, Serialize};
use std::cmp::{Ord, Ordering, PartialOrd}; use std::cmp::{Ord, Ordering, PartialOrd};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet; use std::collections::HashSet;
@ -11,8 +12,10 @@ use pyo3::prelude::*;
use crate::{scalar::*, DexString, DexValue, Result}; use crate::{scalar::*, DexString, DexValue, Result};
use androscalpel_serializer::{StringDataItem, Uleb128}; use androscalpel_serializer::{StringDataItem, Uleb128};
/// The type of a method. The shorty is formated as described in
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct IdMethodType { pub struct IdMethodType {
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor> /// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
pub(crate) shorty: DexString, // Redondant, but same as in the encoding, keep it in case we ever pub(crate) shorty: DexString, // Redondant, but same as in the encoding, keep it in case we ever
@ -37,9 +40,16 @@ impl PartialOrd for IdMethodType {
} }
#[pymethods] #[pymethods]
/// The type of a method. The shorty is formated as described in
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
impl IdMethodType { impl IdMethodType {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(return_type: IdType, parameters: Vec<IdType>) -> Self { pub fn new(return_type: IdType, parameters: Vec<IdType>) -> Self {
Self { Self {
@ -62,7 +72,15 @@ impl IdMethodType {
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
format!("DexMethodType({})", self.__str__()) format!(
"IdMethodType({}, [{}])",
self.return_type.__repr__(),
self.parameters
.iter()
.map(|param| param.__repr__())
.collect::<Vec<_>>()
.join(", ")
)
} }
pub fn get_shorty(&self) -> DexString { pub fn get_shorty(&self) -> DexString {
@ -133,10 +151,19 @@ impl IdMethodType {
// Not a clean rust enum because we want to be compatible with python, and maybe support strange // Not a clean rust enum because we want to be compatible with python, and maybe support strange
// malware edge case? // malware edge case?
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize)]
pub struct IdType(pub(crate) DexString); pub struct IdType(pub(crate) DexString);
#[pymethods] #[pymethods]
impl IdType { impl IdType {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new( pub fn new(
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] ty: DexString, #[pyo3(from_py_with = "crate::dex_string::as_dex_string")] ty: DexString,
@ -231,7 +258,7 @@ impl IdType {
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let name: String = (&self.0).into(); let name: String = (&self.0).into();
format!("IdType({name})") format!("IdType(\"{name}\")")
} }
/// Check if the type is void (return type) /// Check if the type is void (return type)
@ -426,7 +453,7 @@ impl IdType {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct IdField { pub struct IdField {
/// The name of the field, format described at /// The name of the field, format described at
/// <https://source.android.com/docs/core/runtime/dex-format#membername> /// <https://source.android.com/docs/core/runtime/dex-format#membername>
@ -442,6 +469,15 @@ pub struct IdField {
#[pymethods] #[pymethods]
impl IdField { impl IdField {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new( pub fn new(
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString, #[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString,
@ -467,7 +503,7 @@ impl IdField {
let class: String = self.class_.__repr__(); let class: String = self.class_.__repr__();
let name: String = (&self.name).into(); let name: String = (&self.name).into();
let ty: String = self.type_.__repr__(); let ty: String = self.type_.__repr__();
format!("IdField(({ty}){class}.{name})") format!("IdField(\"{name}\", {ty}, {class})")
} }
pub fn __eq__(&self, other: &Self) -> bool { pub fn __eq__(&self, other: &Self) -> bool {
@ -522,7 +558,7 @@ impl PartialOrd for IdField {
/// The Id of a method. /// The Id of a method.
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct IdMethod { pub struct IdMethod {
/// The class containing the method. /// The class containing the method.
#[pyo3(get)] #[pyo3(get)]
@ -537,6 +573,15 @@ pub struct IdMethod {
#[pymethods] #[pymethods]
impl IdMethod { impl IdMethod {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new( pub fn new(
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString, #[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString,
@ -566,7 +611,12 @@ impl IdMethod {
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
format!("DexMethod({})", self.__str__()) format!(
"IdMethod(\"{}\", {}, {})",
self.name.__str__(),
self.proto.__repr__(),
self.class_.__repr__()
)
} }
pub fn __eq__(&self, other: &Self) -> bool { pub fn __eq__(&self, other: &Self) -> bool {
@ -627,10 +677,19 @@ impl PartialOrd for IdMethod {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct IdEnum(pub IdField); pub struct IdEnum(pub IdField);
#[pymethods] #[pymethods]
impl IdEnum { impl IdEnum {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdField) -> Self { pub fn new(val: IdField) -> Self {
Self(val) Self(val)
@ -645,7 +704,7 @@ impl IdEnum {
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
format!("DexEnum({})", self.__str__()) format!("DexEnum({})", self.0.__repr__())
} }
/// Return all strings referenced in the Id. /// Return all strings referenced in the Id.

View file

@ -1,3 +1,5 @@
use crate::Result;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cmp::{Ord, PartialOrd}; use std::cmp::{Ord, PartialOrd};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet; use std::collections::HashSet;
@ -11,6 +13,59 @@ use pyo3::prelude::*;
#[derive(Clone, PartialEq, Eq, Debug, Ord, PartialOrd)] #[derive(Clone, PartialEq, Eq, Debug, Ord, PartialOrd)]
pub struct DexString(pub androscalpel_serializer::StringDataItem); pub struct DexString(pub androscalpel_serializer::StringDataItem);
impl Serialize for DexString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Serialize::serialize(&SerdeDexString::from(self), serializer)
}
}
impl<'de> Deserialize<'de> for DexString {
fn deserialize<D>(deserializer: D) -> Result<DexString, D::Error>
where
D: Deserializer<'de>,
{
<SerdeDexString as Deserialize>::deserialize(deserializer).map(|string| (&string).into())
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename = "DexString")]
enum SerdeDexString {
String(String),
BinString(Vec<u8>, u32),
}
impl From<&DexString> for SerdeDexString {
fn from(DexString(string): &DexString) -> Self {
if let Ok(string) = string.try_into() {
SerdeDexString::String(string)
} else {
let androscalpel_serializer::StringDataItem {
data,
utf16_size: androscalpel_serializer::Uleb128(len),
} = string;
SerdeDexString::BinString(data.to_vec(), *len)
}
}
}
impl From<&SerdeDexString> for DexString {
fn from(string: &SerdeDexString) -> Self {
match string {
SerdeDexString::String(string) => string.as_str().into(),
SerdeDexString::BinString(data, len) => {
DexString(androscalpel_serializer::StringDataItem {
data: data.clone(),
utf16_size: androscalpel_serializer::Uleb128(*len),
})
}
}
}
}
impl From<DexString> for androscalpel_serializer::StringDataItem { impl From<DexString> for androscalpel_serializer::StringDataItem {
fn from(DexString(string): DexString) -> Self { fn from(DexString(string): DexString) -> Self {
string string
@ -71,6 +126,15 @@ pub fn as_dex_string(obj: &PyAny) -> PyResult<DexString> {
#[pymethods] #[pymethods]
impl DexString { impl DexString {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(s: &str) -> Self { pub fn new(s: &str) -> Self {
s.into() s.into()

View file

@ -2625,7 +2625,7 @@ impl DexWriter {
/// given section. /// given section.
fn fix_section_alignement(buffer: &mut Cursor<Vec<u8>>, section: Section) -> Result<()> { fn fix_section_alignement(buffer: &mut Cursor<Vec<u8>>, section: Section) -> Result<()> {
while buffer.position() % section.get_item_alignment() as u64 != 0 { while buffer.position() % section.get_item_alignment() as u64 != 0 {
0u8.serialize(buffer)?; Serializable::serialize(&0u8, buffer)?;
} }
Ok(()) Ok(())
} }

View file

@ -1,17 +1,19 @@
//! Representation of the fields of a class. //! Representation of the fields of a class.
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{ use crate::{
DexAnnotationItem, DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle, DexAnnotationItem, DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle,
Result,
}; };
use androscalpel_serializer::consts::*; use androscalpel_serializer::consts::*;
/// Represent a field. /// Represent a field.
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Field { pub struct Field {
/// The structure used to reference this field. /// The structure used to reference this field.
#[pyo3(get)] #[pyo3(get)]
@ -46,7 +48,7 @@ pub struct Field {
/// Represent the visibility of a field /// Represent the visibility of a field
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum FieldVisibility { pub enum FieldVisibility {
Public, Public,
Private, Private,
@ -56,6 +58,15 @@ pub enum FieldVisibility {
#[pymethods] #[pymethods]
impl Field { impl Field {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(descriptor: IdField) -> Self { pub fn new(descriptor: IdField) -> Self {
Self { Self {

View file

@ -0,0 +1,23 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::iter::FromIterator;
pub fn serialize<'a, T, K, V, S>(target: T, ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: IntoIterator<Item = (&'a K, &'a V)>,
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<T, D::Error>
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()))
}

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,7 @@ pub mod dex_id;
pub mod dex_string; pub mod dex_string;
pub mod dex_writer; pub mod dex_writer;
pub mod field; pub mod field;
mod hashmap_vectorize;
pub mod instructions; pub mod instructions;
pub mod method; pub mod method;
pub mod method_handle; pub mod method_handle;

View file

@ -1,17 +1,19 @@
//! Representation of a method. //! Representation of a method.
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{ use crate::{
Code, DexAnnotationItem, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Code, DexAnnotationItem, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle,
Result,
}; };
use androscalpel_serializer::consts::*; use androscalpel_serializer::consts::*;
/// Represent a method. /// Represent a method.
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Method { pub struct Method {
/// The structure used to reference this method. /// The structure used to reference this method.
#[pyo3(get)] #[pyo3(get)]
@ -68,7 +70,7 @@ pub struct Method {
/// Represent the visibility of a field /// Represent the visibility of a field
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum MethodVisibility { pub enum MethodVisibility {
Public, Public,
Private, Private,
@ -78,6 +80,15 @@ pub enum MethodVisibility {
#[pymethods] #[pymethods]
impl Method { impl Method {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(descriptor: IdMethod) -> Self { pub fn new(descriptor: IdMethod) -> Self {
// TODO: take code option as arg and set the default flags accordingly // TODO: take code option as arg and set the default flags accordingly

View file

@ -1,5 +1,6 @@
//! The structure use to reference a method invocation. //! The structure use to reference a method invocation.
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::Hash; use std::hash::Hash;
@ -8,9 +9,10 @@ use pyo3::prelude::*;
use crate::dex_id::*; use crate::dex_id::*;
use crate::DexString; use crate::DexString;
use crate::Result;
/// The structure use to reference a method invocation. /// The structure use to reference a method invocation.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub enum MethodHandle { pub enum MethodHandle {
StaticPut(StaticPut), StaticPut(StaticPut),
StaticGet(StaticGet), StaticGet(StaticGet),
@ -24,11 +26,20 @@ pub enum MethodHandle {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct StaticPut(pub IdField); pub struct StaticPut(pub IdField);
#[pymethods] #[pymethods]
impl StaticPut { impl StaticPut {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdField) -> Self { pub fn new(val: IdField) -> Self {
Self(val) Self(val)
@ -81,11 +92,20 @@ impl StaticPut {
} }
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct StaticGet(pub IdField); pub struct StaticGet(pub IdField);
#[pymethods] #[pymethods]
impl StaticGet { impl StaticGet {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdField) -> Self { pub fn new(val: IdField) -> Self {
Self(val) Self(val)
@ -138,11 +158,20 @@ impl StaticGet {
} }
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InstancePut(pub IdField); pub struct InstancePut(pub IdField);
#[pymethods] #[pymethods]
impl InstancePut { impl InstancePut {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdField) -> Self { pub fn new(val: IdField) -> Self {
Self(val) Self(val)
@ -195,11 +224,20 @@ impl InstancePut {
} }
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InstanceGet(pub IdField); pub struct InstanceGet(pub IdField);
#[pymethods] #[pymethods]
impl InstanceGet { impl InstanceGet {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdField) -> Self { pub fn new(val: IdField) -> Self {
Self(val) Self(val)
@ -253,11 +291,20 @@ impl InstanceGet {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvokeStatic(pub IdMethod); pub struct InvokeStatic(pub IdMethod);
#[pymethods] #[pymethods]
impl InvokeStatic { impl InvokeStatic {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdMethod) -> Self { pub fn new(val: IdMethod) -> Self {
Self(val) Self(val)
@ -311,11 +358,20 @@ impl InvokeStatic {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvokeInstance(pub IdMethod); pub struct InvokeInstance(pub IdMethod);
#[pymethods] #[pymethods]
impl InvokeInstance { impl InvokeInstance {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdMethod) -> Self { pub fn new(val: IdMethod) -> Self {
Self(val) Self(val)
@ -369,11 +425,20 @@ impl InvokeInstance {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvokeConstructor(pub IdMethod); pub struct InvokeConstructor(pub IdMethod);
#[pymethods] #[pymethods]
impl InvokeConstructor { impl InvokeConstructor {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdMethod) -> Self { pub fn new(val: IdMethod) -> Self {
Self(val) Self(val)
@ -427,11 +492,20 @@ impl InvokeConstructor {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvokeDirect(pub IdMethod); pub struct InvokeDirect(pub IdMethod);
#[pymethods] #[pymethods]
impl InvokeDirect { impl InvokeDirect {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdMethod) -> Self { pub fn new(val: IdMethod) -> Self {
Self(val) Self(val)
@ -485,11 +559,20 @@ impl InvokeDirect {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct InvokeInterface(pub IdMethod); pub struct InvokeInterface(pub IdMethod);
#[pymethods] #[pymethods]
impl InvokeInterface { impl InvokeInterface {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: IdMethod) -> Self { pub fn new(val: IdMethod) -> Self {
Self(val) Self(val)

View file

@ -1,15 +1,26 @@
//! The class identifying dex structure. //! The class identifying dex structure.
use crate::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use crate::{DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle}; use crate::{DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle};
use pyo3::prelude::*; use pyo3::prelude::*;
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexByte(pub i8); pub struct DexByte(pub i8);
#[pymethods] #[pymethods]
impl DexByte { impl DexByte {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: i8) -> Self { pub fn new(val: i8) -> Self {
Self(val) Self(val)
@ -29,10 +40,19 @@ impl DexByte {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexShort(pub i16); pub struct DexShort(pub i16);
#[pymethods] #[pymethods]
impl DexShort { impl DexShort {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: i16) -> Self { pub fn new(val: i16) -> Self {
Self(val) Self(val)
@ -52,10 +72,19 @@ impl DexShort {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexChar(pub u16); pub struct DexChar(pub u16);
#[pymethods] #[pymethods]
impl DexChar { impl DexChar {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: u16) -> Self { pub fn new(val: u16) -> Self {
Self(val) Self(val)
@ -75,10 +104,19 @@ impl DexChar {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexInt(pub i32); pub struct DexInt(pub i32);
#[pymethods] #[pymethods]
impl DexInt { impl DexInt {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: i32) -> Self { pub fn new(val: i32) -> Self {
Self(val) Self(val)
@ -98,10 +136,19 @@ impl DexInt {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexLong(pub i64); pub struct DexLong(pub i64);
#[pymethods] #[pymethods]
impl DexLong { impl DexLong {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: i64) -> Self { pub fn new(val: i64) -> Self {
Self(val) Self(val)
@ -121,10 +168,19 @@ impl DexLong {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
pub struct DexFloat(pub f32); pub struct DexFloat(pub f32);
#[pymethods] #[pymethods]
impl DexFloat { impl DexFloat {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: f32) -> Self { pub fn new(val: f32) -> Self {
Self(val) Self(val)
@ -144,10 +200,19 @@ impl DexFloat {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
pub struct DexDouble(pub f64); pub struct DexDouble(pub f64);
#[pymethods] #[pymethods]
impl DexDouble { impl DexDouble {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: f64) -> Self { pub fn new(val: f64) -> Self {
Self(val) Self(val)
@ -172,6 +237,15 @@ impl DexDouble {
pub struct DexString(pub u32); pub struct DexString(pub u32);
#[pymethods] #[pymethods]
impl DexString { impl DexString {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: u32) -> Self { pub fn new(val: u32) -> Self {
Self(val) Self(val)
@ -192,10 +266,19 @@ impl DexString {
*/ */
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexNull; pub struct DexNull;
#[pymethods] #[pymethods]
impl DexNull { impl DexNull {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn _new() -> Self { pub fn _new() -> Self {
Self Self
@ -211,10 +294,19 @@ impl DexNull {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct DexBoolean(pub bool); pub struct DexBoolean(pub bool);
#[pymethods] #[pymethods]
impl DexBoolean { impl DexBoolean {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn new(val: bool) -> Self { pub fn new(val: bool) -> Self {
Self(val) Self(val)
@ -234,10 +326,19 @@ impl DexBoolean {
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct DexArray(pub Vec<DexValue>); pub struct DexArray(pub Vec<DexValue>);
#[pymethods] #[pymethods]
impl DexArray { impl DexArray {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string(self)?)
}
#[staticmethod]
pub fn from_json(json: &str) -> Result<Self> {
Ok(serde_json::from_str(json)?)
}
#[new] #[new]
pub fn _new(arr: Vec<DexValue>) -> Self { pub fn _new(arr: Vec<DexValue>) -> Self {
Self(arr) Self(arr)

View file

@ -1,5 +1,6 @@
//! The class identifying dex structure. //! The class identifying dex structure.
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use pyo3::exceptions::PyTypeError; use pyo3::exceptions::PyTypeError;
@ -7,7 +8,7 @@ use pyo3::prelude::*;
use crate::{dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle}; use crate::{dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle};
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub enum DexValue { pub enum DexValue {
Byte(DexByte), Byte(DexByte),
Short(DexShort), Short(DexShort),

92
test.py
View file

@ -27,49 +27,49 @@ clazz = apk.classes[clazz_id]
method = clazz.virtual_methods[method_id] method = clazz.virtual_methods[method_id]
code = method.code code = method.code
logging.getLogger().setLevel(logging.ERROR) # logging.getLogger().setLevel(logging.ERROR)
#
print(f"Code of {method_id}") # print(f"Code of {method_id}")
for i in code.insns: # for i in code.insns:
print(i) # print(i)
#
new_insns = [] # new_insns = []
for i in code.insns: # for i in code.insns:
if isinstance(i, asc.ins.ConstString): # if isinstance(i, asc.ins.ConstString):
if i.lit == "Hello": # if i.lit == "Hello":
i = asc.ins.ConstString(i.reg, DexString("Degemer Mat")) # i = asc.ins.ConstString(i.reg, DexString("Degemer Mat"))
elif i.lit == "Bye": # elif i.lit == "Bye":
i = asc.ins.ConstString(i.reg, DexString("Kenavo")) # i = asc.ins.ConstString(i.reg, DexString("Kenavo"))
new_insns.append(i) # new_insns.append(i)
#
# This need improving! ## This need improving!
code = asc.Code(code.registers_size, code.ins_size, code.outs_size, new_insns) # code = asc.Code(code.registers_size, code.ins_size, code.outs_size, new_insns)
apk.set_method_code(method_id, code) # apk.set_method_code(method_id, code)
# apk.set_method_code(method.descriptor, code) ## apk.set_method_code(method.descriptor, code)
#
clazz = apk.classes[clazz_id] # clazz = apk.classes[clazz_id]
method = clazz.virtual_methods[method_id] # method = clazz.virtual_methods[method_id]
code = method.code # code = method.code
#
print(f"Code of {method_id}") # print(f"Code of {method_id}")
for i in code.insns: # for i in code.insns:
print(i) # print(i)
#
dex_raw = apk.gen_raw_dex() # dex_raw = apk.gen_raw_dex()
assert len(dex_raw) == 1 # assert len(dex_raw) == 1
with open(DEX_NAME, "wb") as file: # with open(DEX_NAME, "wb") as file:
file.write(dex_raw[0]) # file.write(dex_raw[0])
#
#
with open(DEX_NAME, "rb") as file: # with open(DEX_NAME, "rb") as file:
dex = file.read() # dex = file.read()
new_apk = asc.Apk() # new_apk = asc.Apk()
new_apk.add_dex_file(dex) # new_apk.add_dex_file(dex)
#
clazz = new_apk.classes[clazz_id] # clazz = new_apk.classes[clazz_id]
method = clazz.virtual_methods[method_id] # method = clazz.virtual_methods[method_id]
code = method.code # code = method.code
#
print(f"Code of {method_id} in new apk") # print(f"Code of {method_id} in new apk")
for i in code.insns: # for i in code.insns:
print(i) # print(i)