diff --git a/androscalpel/Cargo.toml b/androscalpel/Cargo.toml index 73f3e96..8d199e3 100644 --- a/androscalpel/Cargo.toml +++ b/androscalpel/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "androscalpel" version = "0.1.0" -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] diff --git a/androscalpel/src/annotation.rs b/androscalpel/src/annotation.rs index bff2abd..4b28599 100644 --- a/androscalpel/src/annotation.rs +++ b/androscalpel/src/annotation.rs @@ -7,8 +7,8 @@ use pyo3::prelude::*; use crate::hashmap_vectorize; use crate::{ - dex_id::IdType, value::DexValue, DexString, IdField, IdMethod, IdMethodType, MethodHandle, - Result, Visitable, VisitableMut, Visitor, VisitorMut, + DexString, IdField, IdMethod, IdMethodType, MethodHandle, Result, Visitable, VisitableMut, + Visitor, VisitorMut, dex_id::IdType, value::DexValue, }; /// Annotation with a visibility diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index 8abfbbd..b4348c9 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -1,6 +1,6 @@ //! Representation of an apk. -use anyhow::{anyhow, bail, Context}; +use anyhow::{Context, anyhow, bail}; use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; use std::fs::File; @@ -11,9 +11,9 @@ use log::{error, info}; #[cfg(feature = "python")] use pyo3::{prelude::*, types::PyBytes}; +use crate::Result; use crate::ins::CallSite; use crate::instructions; -use crate::Result; use crate::*; use androscalpel_serializer::Instruction as InsFormat; use androscalpel_serializer::*; @@ -1030,7 +1030,9 @@ impl Apk { Format11X { op: 0x27, va } => Instruction::Throw { reg: va }, Format10T { op: 0x28, a } => { if a < 0 && (-(a as i64)) as usize > addr { - bail!("Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)"); + bail!( + "Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)" + ); } let dest_addr = if a > 0 { addr + a as usize @@ -1043,7 +1045,9 @@ impl Apk { } Format20T { op: 0x29, a } => { if a < 0 && (-(a as i64)) as usize > addr { - bail!("Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)"); + bail!( + "Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)" + ); } let dest_addr = if a > 0 { addr + a as usize @@ -1056,7 +1060,9 @@ impl Apk { } Format30T { op: 0x2a, a } => { if a < 0 && (-(a as i64)) as usize > addr { - bail!("Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)"); + bail!( + "Found goto {a} at 0x{addr:0x}: the destination is invalid (negative addresse)" + ); } let dest_addr = if a > 0 { addr + a as usize @@ -3053,24 +3059,29 @@ impl Apk { i += 1; dex_name = format!("classes{i}.dex"); } - if let Some(_version) = crate::utils::is_dex(&mut code)? { - let mut data = vec![]; - std::io::copy(&mut code, &mut data)?; - self.add_dex_file(&dex_name, &data, label_ins, cache) - } else if crate::utils::is_zip(&mut code)? { - let mut tmp_apk = Apk::load_apk(code, label_ins, cache)?; - let mut j = 1; - let mut tmp_dex_name: String = "classes.dex".into(); - while let Some(dex_file) = tmp_apk.dex_files.remove(&tmp_dex_name) { - self.dex_files.insert(dex_name, dex_file); - i += 1; - j += 1; - dex_name = format!("classes{i}.dex"); - tmp_dex_name = format!("classes{j}.dex"); + match crate::utils::is_dex(&mut code)? { + Some(_version) => { + let mut data = vec![]; + std::io::copy(&mut code, &mut data)?; + self.add_dex_file(&dex_name, &data, label_ins, cache) + } + _ => { + if crate::utils::is_zip(&mut code)? { + let mut tmp_apk = Apk::load_apk(code, label_ins, cache)?; + let mut j = 1; + let mut tmp_dex_name: String = "classes.dex".into(); + while let Some(dex_file) = tmp_apk.dex_files.remove(&tmp_dex_name) { + self.dex_files.insert(dex_name, dex_file); + i += 1; + j += 1; + dex_name = format!("classes{i}.dex"); + tmp_dex_name = format!("classes{j}.dex"); + } + Ok(()) + } else { + bail!("Could not recognize the type of the input file") + } } - Ok(()) - } else { - bail!("Could not recognize the type of the input file") } } diff --git a/androscalpel/src/code.rs b/androscalpel/src/code.rs index 5e04185..8818a42 100644 --- a/androscalpel/src/code.rs +++ b/androscalpel/src/code.rs @@ -9,8 +9,8 @@ use std::collections::{HashMap, HashSet}; use pyo3::prelude::*; use crate::{ - ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, Method, MethodHandle, - Result, Visitable, VisitableMut, Visitor, VisitorMut, + DexString, IdField, IdMethod, IdMethodType, IdType, Method, MethodHandle, Result, Visitable, + VisitableMut, Visitor, VisitorMut, ins::Instruction, }; // TODO: make this easy to edit/manipulate, maybe move to Method diff --git a/androscalpel/src/code_analysis/method_cfg.rs b/androscalpel/src/code_analysis/method_cfg.rs index 10d7c7d..7c882c3 100644 --- a/androscalpel/src/code_analysis/method_cfg.rs +++ b/androscalpel/src/code_analysis/method_cfg.rs @@ -293,19 +293,24 @@ impl<'a> MethodCFG<'a> { " node_{i} [shape=record,style=filled,fillcolor=lightgrey,label=\"{label}\"];\n\n" ); } - dot_string += - " node_end [shape=record,style=filled,fillcolor=lightgrey,label=\"{\\< EXIT \\>}\"];\n\n"; + dot_string += " node_end [shape=record,style=filled,fillcolor=lightgrey,label=\"{\\< EXIT \\>}\"];\n\n"; for (i, node) in self.nodes.iter().enumerate() { for j in &node.next_nodes { if *j == i + 1 { - dot_string += &format!(" node_{i}:s -> node_{j}:n [style=\"solid,bold\",color=black,weight=100,constraint=true];\n"); + dot_string += &format!( + " node_{i}:s -> node_{j}:n [style=\"solid,bold\",color=black,weight=100,constraint=true];\n" + ); } else { - dot_string += &format!(" node_{i}:s -> node_{j}:n [style=\"solid,bold\",color=black,weight=10,constraint=true];\n"); + dot_string += &format!( + " node_{i}:s -> node_{j}:n [style=\"solid,bold\",color=black,weight=10,constraint=true];\n" + ); } } if node.next_nodes.is_empty() { - dot_string += &format!(" node_{i}:s -> node_end:n [style=\"solid,bold\",color=black,weight=10,constraint=true];\n"); + dot_string += &format!( + " node_{i}:s -> node_end:n [style=\"solid,bold\",color=black,weight=10,constraint=true];\n" + ); } } dot_string += "}\n"; diff --git a/androscalpel/src/code_analysis/register_type.rs b/androscalpel/src/code_analysis/register_type.rs index 3ade15b..582c486 100644 --- a/androscalpel/src/code_analysis/register_type.rs +++ b/androscalpel/src/code_analysis/register_type.rs @@ -123,7 +123,9 @@ impl MethodCFG<'_> { node_label += reg.to_str(); } node_label += "|"; - dot_string += &format!(" node_{label} [shape=record,style=filled,fillcolor=lightgrey,label=\"{node_label}\"];\n"); + dot_string += &format!( + " node_{label} [shape=record,style=filled,fillcolor=lightgrey,label=\"{node_label}\"];\n" + ); } dot_string += "}\n"; diff --git a/androscalpel/src/dex_id.rs b/androscalpel/src/dex_id.rs index 75676ad..3ac49ad 100644 --- a/androscalpel/src/dex_id.rs +++ b/androscalpel/src/dex_id.rs @@ -5,11 +5,11 @@ use std::cmp::{Ord, Ordering, PartialOrd}; use std::collections::HashSet; use std::hash::Hash; -use anyhow::{anyhow, bail, Context}; +use anyhow::{Context, anyhow, bail}; #[cfg(feature = "python")] use pyo3::prelude::*; -use crate::{scalar::*, DexString, DexValue, Result, Visitable, VisitableMut, Visitor, VisitorMut}; +use crate::{DexString, DexValue, Result, Visitable, VisitableMut, Visitor, VisitorMut, scalar::*}; use androscalpel_serializer::{StringDataItem, Uleb128}; /// The type of a method. The shorty is formated as described in @@ -332,15 +332,18 @@ impl IdType { 'J' => Some(Self::long()), 'F' => Some(Self::float()), 'D' => Some(Self::double()), - '[' => { array_dimmention += 1; None }, + '[' => { + array_dimmention += 1; + None + } 'L' => { let mut class_name = String::new(); - for cc in chars.by_ref(){ - if cc == ';' { break;} - else { + for cc in chars.by_ref() { + if cc == ';' { + break; + } else { class_name.push(cc); } - } Some(Self::class(&class_name)) } @@ -350,13 +353,13 @@ impl IdType { }; if let Some(mut new_type) = new_type { if array_dimmention != 0 { - let mut data = vec![0u8; array_dimmention + new_type.0 .0.data.len()]; + let mut data = vec![0u8; array_dimmention + new_type.0.0.data.len()]; for c in &mut data[..array_dimmention] { *c = 0x5b; } - data[array_dimmention..].copy_from_slice(&new_type.0 .0.data); - new_type.0 .0.data = data; - new_type.0 .0.utf16_size.0 += array_dimmention as u32; + data[array_dimmention..].copy_from_slice(&new_type.0.0.data); + new_type.0.0.data = data; + new_type.0.0.utf16_size.0 += array_dimmention as u32; } lst.push(new_type); @@ -443,8 +446,8 @@ impl IdType { #[cfg_attr(feature = "python", staticmethod)] pub fn array(type_: &IdType) -> Self { let mut ty = type_.clone(); - ty.0 .0.utf16_size.0 += 1; - ty.0 .0.data.insert(0, 0x5b); + ty.0.0.utf16_size.0 += 1; + ty.0.0.data.insert(0, 0x5b); ty } @@ -644,7 +647,7 @@ impl IdType { impl SmaliName for IdType { /// Convert a descriptor to its smali representation. fn try_to_smali(&self) -> Result { - let r = (&self.0 .0).try_into()?; // Anyhow conversion stuff + let r = (&self.0.0).try_into()?; // Anyhow conversion stuff Ok(r) } /// Convert a smali representation to its descriptor. diff --git a/androscalpel/src/dex_string.rs b/androscalpel/src/dex_string.rs index bffc79c..fb8425a 100644 --- a/androscalpel/src/dex_string.rs +++ b/androscalpel/src/dex_string.rs @@ -27,27 +27,30 @@ impl VisitableMut for DexString { impl std::fmt::Debug for DexString { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - if let Ok(string) = TryInto::::try_into(self) { - f.write_str(&format!( - "DexString({}, {:#x})", - string, self.0.utf16_size.0 - )) - /* - f.debug_tuple("DexString") - .field(&string) - .field(&self.0.utf16_size.0) - .finish() - */ - } else { - f.write_str(&format!( - "DexString({:?}, {:#x})", - self.0.data, self.0.utf16_size.0 - )) - /*f.debug_tuple("DexString") - .field(&self.0.data) - .field(&self.0.utf16_size.0) - .finish() - */ + match TryInto::::try_into(self) { + Ok(string) => { + f.write_str(&format!( + "DexString({}, {:#x})", + string, self.0.utf16_size.0 + )) + /* + f.debug_tuple("DexString") + .field(&string) + .field(&self.0.utf16_size.0) + .finish() + */ + } + _ => { + f.write_str(&format!( + "DexString({:?}, {:#x})", + self.0.data, self.0.utf16_size.0 + )) + /*f.debug_tuple("DexString") + .field(&self.0.data) + .field(&self.0.utf16_size.0) + .finish() + */ + } } } } @@ -193,10 +196,11 @@ impl DexString { } pub fn __str__(&self) -> String { - if let Ok(string) = TryInto::::try_into(self) { - string - } else { - format!("string{:02x?}", self.0.data) + match TryInto::::try_into(self) { + Ok(string) => string, + _ => { + format!("string{:02x?}", self.0.data) + } } } diff --git a/androscalpel/src/dex_writer.rs b/androscalpel/src/dex_writer.rs index 3ed6ec4..ed57a1e 100644 --- a/androscalpel/src/dex_writer.rs +++ b/androscalpel/src/dex_writer.rs @@ -5,7 +5,7 @@ use std::io; use std::io::{Cursor, Seek, SeekFrom, Write}; use adler::Adler32; -use anyhow::{anyhow, bail, Context}; +use anyhow::{Context, anyhow, bail}; use log::{debug, warn}; use sha1::{Digest, Sha1}; @@ -707,7 +707,7 @@ impl DexWriter { .handlers .push(EncodedTypeAddrPair { type_idx, addr }); } - if let Some(ref label) = default_handler { + if let Some(label) = default_handler { let catch_all_addr = *label_addrs.get(label).ok_or(anyhow!( "Label {} not found in code of {}, but found try \ with this label as catch all", @@ -1523,8 +1523,10 @@ impl DexWriter { (Some(field), None) => (true, field), (None, Some(field)) => (false, field), _ => bail!( - "Unexpected configuration: field {} is both a static and a instance field in {}", - field_id.__repr__(), class_id.__repr__()), + "Unexpected configuration: field {} is both a static and a instance field in {}", + field_id.__repr__(), + class_id.__repr__() + ), }; if !field.annotations.is_empty() { let annotations_off = self @@ -1557,8 +1559,10 @@ impl DexWriter { (Some(method), None) => (true, method), (None, Some(method)) => (false, method), _ => bail!( - "Unexpected configuration: method {} is both a direct and a virtual method in {}", - method_id.__repr__(), class_id.__repr__()), + "Unexpected configuration: method {} is both a direct and a virtual method in {}", + method_id.__repr__(), + class_id.__repr__() + ), }; if !method.annotations.is_empty() { let annotations_off = self @@ -1586,8 +1590,10 @@ impl DexWriter { (Some(method), None) => (true, method), (None, Some(method)) => (false, method), _ => bail!( - "Unexpected configuration: method {} is both a direct and a virtual method in {}", - method_id.__repr__(), class_id.__repr__()), + "Unexpected configuration: method {} is both a direct and a virtual method in {}", + method_id.__repr__(), + class_id.__repr__() + ), }; if !method.parameters_annotations.is_empty() { let annotations_off = self @@ -1763,12 +1769,12 @@ impl DexWriter { debug!("Generate the map_list"); // Get the size of a map item let map_item_size = 12; /* = MapItem { - type_: MapItemType::HeaderItem, - unused: 0, - size: 0, - offset: 0, - } - .size(); */ + type_: MapItemType::HeaderItem, + unused: 0, + size: 0, + offset: 0, + } + .size(); */ // Empty map has a size 4, then we add the size of a MapItem for each element // The size of the map_list must be computed before generating the map list, // as it affect the offset of some sections. @@ -2673,12 +2679,12 @@ impl SectionManager { } let mut map_list_size = 4; let map_item_size = 12; /* = MapItem { - type_: MapItemType::HeaderItem, - unused: 0, - size: 0, - offset: 0, - } - .size(); */ + type_: MapItemType::HeaderItem, + unused: 0, + size: 0, + offset: 0, + } + .size(); */ for section in Section::VARIANT_LIST { if !section.is_data() && (self.get_nb_elt(*section) != 0 || section == &Section::MapList) diff --git a/androscalpel/src/hiddenapi.rs b/androscalpel/src/hiddenapi.rs index 7998cf4..07b402e 100644 --- a/androscalpel/src/hiddenapi.rs +++ b/androscalpel/src/hiddenapi.rs @@ -170,7 +170,9 @@ impl HiddenApiDomain { value += "test-api"; } if self.unknown_flags != 0 { - warn!("This attribut has an unknown hiddenapi domain set, this will not be display for compatibility with apktool"); + warn!( + "This attribut has an unknown hiddenapi domain set, this will not be display for compatibility with apktool" + ); } value } diff --git a/androscalpel/src/py_utils.rs b/androscalpel/src/py_utils.rs index 740e2fc..a8998c6 100644 --- a/androscalpel/src/py_utils.rs +++ b/androscalpel/src/py_utils.rs @@ -12,7 +12,7 @@ use crate::{Apk, IdType, Result}; use androscalpel_serializer::{ DexFileReader, HeaderItem, Serializable, Sleb128, Uleb128, Uleb128p1, }; -use apk_frauder::{end_of_central_directory::EndCentralDirectory, ZipFileReader}; +use apk_frauder::{ZipFileReader, end_of_central_directory::EndCentralDirectory}; /// Convert an integer to the uleb128 byte encoding #[pyfunction] @@ -89,12 +89,12 @@ pub fn is_zip(file: PathBuf) -> Result { /// `bytes` for the content of the file. #[pyfunction] #[pyo3(signature = ( - apk, - dst, - dexfiles, - keystore, - zipalign=None, - apksigner=None, + apk, + dst, + dexfiles, + keystore, + zipalign=None, + apksigner=None, additionnal_files=None ))] pub fn replace_dex( @@ -111,13 +111,18 @@ pub fn replace_dex( .map(PyBytesMethods::as_bytes) .map(Cursor::new) .collect(); - let additionnal_files: Option> = additionnal_files.as_ref().map(|additionnal_files| - additionnal_files.iter() - .map(|(k, v)| ( - k.clone(), - v.as_ref().map(|bytes| bytes.as_bytes()).map(Cursor::new) - )).collect() - ); + let additionnal_files: Option> = + additionnal_files.as_ref().map(|additionnal_files| { + additionnal_files + .iter() + .map(|(k, v)| { + ( + k.clone(), + v.as_ref().map(|bytes| bytes.as_bytes()).map(Cursor::new), + ) + }) + .collect() + }); apk_frauder::replace_dex( apk, dst, diff --git a/androscalpel/src/tests/mod.rs b/androscalpel/src/tests/mod.rs index 5e0fbca..c4d7db0 100644 --- a/androscalpel/src/tests/mod.rs +++ b/androscalpel/src/tests/mod.rs @@ -13,13 +13,14 @@ use std::time::Instant; fn write_to_report(data: &str) { static REPORT_FILE: Mutex> = Mutex::new(None); let mut report_file = REPORT_FILE.lock().unwrap(); - let mut report_file = if let Some(report_file) = report_file.deref() { - report_file - } else { - *report_file = Some( - File::create(&format!("{}/test_repport.txt", env!("CARGO_MANIFEST_DIR"),)).unwrap(), - ); - report_file.deref().as_ref().unwrap() + let mut report_file = match report_file.deref() { + Some(report_file) => report_file, + _ => { + *report_file = Some( + File::create(&format!("{}/test_repport.txt", env!("CARGO_MANIFEST_DIR"),)).unwrap(), + ); + report_file.deref().as_ref().unwrap() + } }; writeln!(report_file, "{data}").unwrap(); } @@ -625,13 +626,16 @@ fn test_hidden_api() { ( sj::Value::String(apktool_hiddenapi), sj::Value::Null, - Some(HiddenApiData { - permission, - domain, - }), - ) if (permission.to_smali_name() == apktool_hiddenapi) && &domain.to_smali_name() == "" => (), + Some(HiddenApiData { permission, domain }), + ) if (permission.to_smali_name() == apktool_hiddenapi) + && &domain.to_smali_name() == "" => + { + () + } - _ => panic!("Expected {apktool_hiddenapi:?} and {apktool_hiddenapi_domain:?}, found {parsed_api:?} in {name}"), + _ => panic!( + "Expected {apktool_hiddenapi:?} and {apktool_hiddenapi_domain:?}, found {parsed_api:?} in {name}" + ), } } let apktool_result = File::open(&apktool_result).expect("core-oj-33_hiddenapi.json not found"); diff --git a/androscalpel/src/utils.rs b/androscalpel/src/utils.rs index 958172e..5d5cb8e 100644 --- a/androscalpel/src/utils.rs +++ b/androscalpel/src/utils.rs @@ -2,7 +2,7 @@ use std::io::{Read, Seek, SeekFrom}; use crate::Result; use androscalpel_serializer::{HeaderItem, Serializable}; -use apk_frauder::{end_of_central_directory::EndCentralDirectory, ZipFileReader}; +use apk_frauder::{ZipFileReader, end_of_central_directory::EndCentralDirectory}; /// Test if a file is as .dex file an return the dex version if it is, else return None. pub fn is_dex(file: &mut (impl Read + Seek)) -> Result> { @@ -18,16 +18,16 @@ pub fn is_dex(file: &mut (impl Read + Seek)) -> Result> { /// Test if a file is a zip file. pub fn is_zip(mut file: impl Read + Seek) -> Result { let pos = file.stream_position()?; - let ecd_off = if let Some(off) = ZipFileReader::get_end_of_central_directory_offset(&mut file) { - off - } else { - return Ok(false); + let ecd_off = match ZipFileReader::get_end_of_central_directory_offset(&mut file) { + Some(off) => off, + _ => { + return Ok(false); + } }; file.seek(SeekFrom::Start(ecd_off))?; - let r = if let Ok(sig) = apk_frauder::Signature::deserialize(&mut file) { - EndCentralDirectory::SIGNATURE == sig - } else { - false + let r = match apk_frauder::Signature::deserialize(&mut file) { + Ok(sig) => EndCentralDirectory::SIGNATURE == sig, + _ => false, }; file.seek(SeekFrom::Start(pos))?; Ok(r) diff --git a/androscalpel/src/value.rs b/androscalpel/src/value.rs index b63c051..de7d7d7 100644 --- a/androscalpel/src/value.rs +++ b/androscalpel/src/value.rs @@ -7,8 +7,8 @@ use std::collections::HashSet; use pyo3::{exceptions::PyTypeError, prelude::*}; use crate::{ - dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle, Result, Visitable, VisitableMut, - Visitor, VisitorMut, + DexAnnotation, DexString, MethodHandle, Result, Visitable, VisitableMut, Visitor, VisitorMut, + dex_id::*, scalar::*, }; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] diff --git a/androscalpel/src/visitor.rs b/androscalpel/src/visitor.rs index 986e58d..64a8e75 100644 --- a/androscalpel/src/visitor.rs +++ b/androscalpel/src/visitor.rs @@ -1,10 +1,10 @@ //! The visitor trait and common implementations. use crate::{ - ins::Instruction, scalar::*, Apk, CallSite, Class, Code, DexAnnotation, DexAnnotationItem, - DexFile, DexString, DexValue, Field, FieldVisibility, HiddenApiData, HiddenApiDomain, - HiddenApiPermission, IdEnum, IdField, IdMethod, IdMethodType, IdType, Method, MethodHandle, - MethodVisibility, Result, + Apk, CallSite, Class, Code, DexAnnotation, DexAnnotationItem, DexFile, DexString, DexValue, + Field, FieldVisibility, HiddenApiData, HiddenApiDomain, HiddenApiPermission, IdEnum, IdField, + IdMethod, IdMethodType, IdType, Method, MethodHandle, MethodVisibility, Result, + ins::Instruction, scalar::*, }; use std::collections::HashSet; diff --git a/androscalpel_serializer/src/core/mod.rs b/androscalpel_serializer/src/core/mod.rs index 66f1d56..1177e81 100644 --- a/androscalpel_serializer/src/core/mod.rs +++ b/androscalpel_serializer/src/core/mod.rs @@ -390,7 +390,9 @@ mod test { fn serialize_u64() { assert_eq!( 0x123456789ABCDEF0u64.serialize_to_vec().unwrap(), - vec![0xF0u8, 0xDEu8, 0xBCu8, 0x9Au8, 0x78u8, 0x56u8, 0x34u8, 0x12u8] + vec![ + 0xF0u8, 0xDEu8, 0xBCu8, 0x9Au8, 0x78u8, 0x56u8, 0x34u8, 0x12u8 + ] ); } diff --git a/androscalpel_serializer/src/core/string.rs b/androscalpel_serializer/src/core/string.rs index 1be3234..0616761 100644 --- a/androscalpel_serializer/src/core/string.rs +++ b/androscalpel_serializer/src/core/string.rs @@ -357,26 +357,34 @@ mod test { /// Test for bug found in : #[test] fn test_tktech_bad_mutf8() { - assert!(TryInto::::try_into(StringDataItem { - utf16_size: Uleb128(0), - data: vec![0x00] - }) - .is_err()); - assert!(TryInto::::try_into(StringDataItem { - utf16_size: Uleb128(0), - data: vec![0xC2] - }) - .is_err()); - assert!(TryInto::::try_into(StringDataItem { - utf16_size: Uleb128(0), - data: vec![0xED] - }) - .is_err()); - assert!(TryInto::::try_into(StringDataItem { - utf16_size: Uleb128(0), - data: vec![0xE2] - }) - .is_err()); + assert!( + TryInto::::try_into(StringDataItem { + utf16_size: Uleb128(0), + data: vec![0x00] + }) + .is_err() + ); + assert!( + TryInto::::try_into(StringDataItem { + utf16_size: Uleb128(0), + data: vec![0xC2] + }) + .is_err() + ); + assert!( + TryInto::::try_into(StringDataItem { + utf16_size: Uleb128(0), + data: vec![0xED] + }) + .is_err() + ); + assert!( + TryInto::::try_into(StringDataItem { + utf16_size: Uleb128(0), + data: vec![0xE2] + }) + .is_err() + ); } /// Test from , test 2 bytes diff --git a/androscalpel_serializer/src/debug.rs b/androscalpel_serializer/src/debug.rs index fe0cdaa..1a93c55 100644 --- a/androscalpel_serializer/src/debug.rs +++ b/androscalpel_serializer/src/debug.rs @@ -2,7 +2,7 @@ use crate as androscalpel_serializer; use crate::{ - Error, ReadSeek, Result, Serializable, SerializableUntil, Sleb128, Uleb128, Uleb128p1, NO_INDEX, + Error, NO_INDEX, ReadSeek, Result, Serializable, SerializableUntil, Sleb128, Uleb128, Uleb128p1, }; use std::io::Write; diff --git a/androscalpel_serializer/src/file_reader.rs b/androscalpel_serializer/src/file_reader.rs index 6b08b7f..8b8d1ca 100644 --- a/androscalpel_serializer/src/file_reader.rs +++ b/androscalpel_serializer/src/file_reader.rs @@ -270,7 +270,7 @@ impl<'a> DexFileReader<'a> { MapItemType::HeaderItem if item.offset != 0 || item.size != 1 => { return Err(Error::InconsistantStruct(format!( "Inconsistant Header Mapping info found in map_list: {item:x?}" - ))) + ))); } MapItemType::StringIdItem if item.offset != self.header.string_ids_off @@ -280,7 +280,7 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.string_ids_off: 0x{:x}, header.string_ids_size: {}", self.header.string_ids_off, self.header.string_ids_size - ))) + ))); } MapItemType::TypeIdItem if item.offset != self.header.type_ids_off @@ -290,7 +290,7 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.type_ids_off: 0x{:x}, header.type_ids_size: {}", self.header.type_ids_off, self.header.type_ids_size - ))) + ))); } MapItemType::ProtoIdItem if item.offset != self.header.proto_ids_off @@ -300,7 +300,7 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.proto_ids_off: 0x{:x}, header.proto_ids_size: {}", self.header.proto_ids_off, self.header.proto_ids_size - ))) + ))); } MapItemType::FieldIdItem if item.offset != self.header.field_ids_off @@ -310,7 +310,7 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.field_ids_off: 0x{:x}, header.field_ids_size: {}", self.header.field_ids_off, self.header.field_ids_size - ))) + ))); } MapItemType::MethodIdItem if item.offset != self.header.method_ids_off @@ -320,7 +320,7 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.method_ids_off: 0x{:x}, header.method_ids_size: {}", self.header.method_ids_off, self.header.method_ids_size - ))) + ))); } MapItemType::ClassDefItem if item.offset != self.header.class_defs_off @@ -330,14 +330,14 @@ impl<'a> DexFileReader<'a> { "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.class_defs_off: 0x{:x}, header.class_defs_size: {}", self.header.class_defs_off, self.header.class_defs_size - ))) + ))); } MapItemType::MapList if item.offset != self.header.map_off || item.size != 1 => { return Err(Error::InconsistantStruct(format!( "Inconsistant MapList Mapping info found in map_list: {item:x?}, \ header.map_list_off: 0x{:x}", self.header.map_off - ))) + ))); } /* MapItemType::CallSiteIdItem => todo!(), diff --git a/androscalpel_serializer/src/items/code.rs b/androscalpel_serializer/src/items/code.rs index ae867a6..99e400f 100644 --- a/androscalpel_serializer/src/items/code.rs +++ b/androscalpel_serializer/src/items/code.rs @@ -977,7 +977,9 @@ mod test { } .serialize_to_vec() .unwrap(), - vec![0x03, 0xb4, 0x01, 0x80, 0x02, 0xc7, 0x08, 0x8e, 0x02, 0xd9, 0x09, 0x87, 0x02,] + vec![ + 0x03, 0xb4, 0x01, 0x80, 0x02, 0xc7, 0x08, 0x8e, 0x02, 0xd9, 0x09, 0x87, 0x02, + ] ); assert_eq!( EncodedCatchHandler { @@ -999,7 +1001,9 @@ mod test { } .serialize_to_vec() .unwrap(), - vec![0x03, 0xe9, 0x46, 0x56, 0xc7, 0x08, 0x8e, 0x02, 0xd9, 0x09, 0x87, 0x02,] + vec![ + 0x03, 0xe9, 0x46, 0x56, 0xc7, 0x08, 0x8e, 0x02, 0xd9, 0x09, 0x87, 0x02, + ] ); assert_eq!( EncodedCatchHandler {