diff --git a/Cargo.lock b/Cargo.lock index e2f1c5c..419f5ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,9 @@ name = "androscalpel" version = "0.1.0" dependencies = [ "androscalpel_serializer", + "log", "pyo3", + "pyo3-log", ] [[package]] @@ -15,6 +17,7 @@ name = "androscalpel_serializer" version = "0.1.0" dependencies = [ "androscalpel_serializer_derive", + "log", ] [[package]] @@ -27,6 +30,12 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + [[package]] name = "autocfg" version = "1.1.0" @@ -67,6 +76,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "memoffset" version = "0.9.0" @@ -151,6 +166,17 @@ dependencies = [ "pyo3-build-config", ] +[[package]] +name = "pyo3-log" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f47b0777feb17f61eea78667d61103758b243a871edc09a7786500a50467b605" +dependencies = [ + "arc-swap", + "log", + "pyo3", +] + [[package]] name = "pyo3-macros" version = "0.19.2" diff --git a/TODO.md b/TODO.md index 913e264..de5e1ab 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,4 @@ - edditable format -- python binding - sanity checks - tests - https://source.android.com/docs/core/runtime/dex-format#system-annotation diff --git a/androscalpel/Cargo.toml b/androscalpel/Cargo.toml index 655050f..841d100 100644 --- a/androscalpel/Cargo.toml +++ b/androscalpel/Cargo.toml @@ -10,4 +10,6 @@ crate-type = ["cdylib"] [dependencies] androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" } +log = "0.4.20" pyo3 = "0.19.0" +pyo3-log = "0.8.3" diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index e45840d..89cec20 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -1,4 +1,5 @@ //! Representation of an apk. +use log::info; use pyo3::prelude::*; use crate::{Class, DexString, Error, Result}; @@ -92,11 +93,11 @@ impl Apk { | ACC_ENUM)) != 0 { - println!( + info!( "Unexpected flags found in class_def_item.access_flags for {}: 0x{:x}", <&DexString as Into>::into(&name), class_item.access_flags - ); // TODO: better logging + ); } self.classes.push(Class { name, diff --git a/androscalpel/src/class.rs b/androscalpel/src/class.rs index f5a6410..ceccf57 100644 --- a/androscalpel/src/class.rs +++ b/androscalpel/src/class.rs @@ -14,7 +14,7 @@ pub struct Class { pub name: DexString, /// If the class is visible everywhere #[pyo3(get, set)] - pub is_public: bool, // TODO: is it possible to not be public non a non inner class? + pub is_public: bool, /// If the class is subclassable #[pyo3(get, set)] pub is_final: bool, diff --git a/androscalpel/src/lib.rs b/androscalpel/src/lib.rs index 5cd8cb7..b20ddb6 100644 --- a/androscalpel/src/lib.rs +++ b/androscalpel/src/lib.rs @@ -145,6 +145,7 @@ impl DexString { /// Androscalpel. #[pymodule] fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> { + pyo3_log::init(); m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/androscalpel_serializer/Cargo.toml b/androscalpel_serializer/Cargo.toml index a81eaef..5f8a136 100644 --- a/androscalpel_serializer/Cargo.toml +++ b/androscalpel_serializer/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] androscalpel_serializer_derive = { path = "../androscalpel_serializer_derive" } +log = "0.4.20" diff --git a/androscalpel_serializer/src/annotation/encoded_annotation.rs b/androscalpel_serializer/src/annotation/encoded_annotation.rs index cc25d07..fd5add6 100644 --- a/androscalpel_serializer/src/annotation/encoded_annotation.rs +++ b/androscalpel_serializer/src/annotation/encoded_annotation.rs @@ -1,4 +1,5 @@ use crate::{EncodedValue, Error, ReadSeek, Result, Serializable, Uleb128}; +use log::warn; use std::io::Write; // To derive Serializable @@ -60,9 +61,8 @@ impl Serializable for EncodedAnnotation { let mut idx_0 = elements[0].name_idx; for idx_1 in elements.iter().map(|elt| elt.name_idx).skip(1) { if idx_0 > idx_1 { - // TODO: use proper logging - println!( - "Waring while deserializing EncodedAnnotation: element must be sorted in increasing order by string_id index, found {idx_0:?} before {idx_1:?}" + warn!( + "while deserializing EncodedAnnotation: element must be sorted in increasing order by string_id index, found {idx_0:?} before {idx_1:?}" ); } idx_0 = idx_1; diff --git a/androscalpel_serializer/src/file_reader.rs b/androscalpel_serializer/src/file_reader.rs index 436d45e..ccff92b 100644 --- a/androscalpel_serializer/src/file_reader.rs +++ b/androscalpel_serializer/src/file_reader.rs @@ -5,6 +5,7 @@ use crate::{ MapList, MethodHandleItem, MethodIdItem, ProtoIdItem, Result, Serializable, StringDataItem, StringIdItem, TypeIdItem, }; +use log::{error, info, warn}; use std::io::{Cursor, Seek, SeekFrom}; pub struct DexFileReader<'a> { @@ -144,32 +145,32 @@ impl<'a> DexFileReader<'a> { fn sanity_check(&self) -> Result<()> { if self.header.magic.version != [0x30, 0x33, 0x39] { - println!( + warn!( "DEX 039 is the only verion currently supported, found {}", std::str::from_utf8(self.header.magic.version.as_slice()) .unwrap_or(&format!("{:x?}", self.header.magic.version)) - ); // TODO: use proper logging + ); } // TODO: check checksum // TODO: check signature if self.header.file_size as usize != self.data.len() { - println!( + info!( "Unexpected file size found: {}, expected {}", self.header.file_size, self.data.len() - ); // TODO: use proper logging + ); } if self.header.header_size != 0x70 { - println!( + info!( "Unexpected header size found: 0x{:x}", self.header.header_size - ); // TODO: use proper logging + ); } if self.header.endian_tag != EndianConstant::EndianConstant { - println!("Wrong endian_tag found: {:x?}", self.header.endian_tag); // TODO: use proper logging + warn!("Wrong endian_tag found: {:x?}", self.header.endian_tag); } if self.header.link_off != 0 || self.header.link_size != 0 { - println!("Found non empty link section"); // TODO: use proper logging + info!("Found non empty link section, the section will be ignored"); } for item in &self.map_list.list { match item.type_ { @@ -261,8 +262,7 @@ impl<'a> DexFileReader<'a> { MapItemType::HiddenapiClassDataItem => todo!(), */ MapItemType::UnkownType(ty) => { - println!("Unknown Type found in map_list: 0x{ty:04x}"); // TODO: use proper - // loggin + info!("Unknown Type found in map_list: 0x{ty:04x}, it will be ignored"); } _ => (), } @@ -273,8 +273,7 @@ impl<'a> DexFileReader<'a> { let mut duplicate = false; for (ty, val) in occurences { if val > 1 { - println!("Found multiple {} occurence of {:?} in map_list", val, ty); - // TODO: use proper loggin + error!("Found multiple {} occurence of {:?} in map_list", val, ty); duplicate = true; } } diff --git a/test.py b/test.py index 56b3f99..2d523a6 100644 --- a/test.py +++ b/test.py @@ -1,3 +1,9 @@ +import logging + +FORMAT = "[%(levelname)s] %(name)s %(filename)s:%(lineno)d: %(message)s" +logging.basicConfig(format=FORMAT) +logging.getLogger().setLevel(logging.INFO) + import androscalpel as asc import zipfile as z