fix lints
This commit is contained in:
parent
88ecc534a2
commit
ca31c41726
12 changed files with 115 additions and 112 deletions
|
|
@ -154,7 +154,7 @@ impl Apk {
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Unexpected flags found in class_def_item.access_flags for {}: 0x{:x}",
|
"Unexpected flags found in class_def_item.access_flags for {}: 0x{:x}",
|
||||||
String::from(descriptor.get_name()),
|
descriptor.get_name().__str__(),
|
||||||
class_item.access_flags
|
class_item.access_flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +229,7 @@ impl Apk {
|
||||||
"Inconsistant static_values array found in {}: \
|
"Inconsistant static_values array found in {}: \
|
||||||
|static_values| = {}, |static_fields| = {}, \
|
|static_values| = {}, |static_fields| = {}, \
|
||||||
|static_values| should be <= |static_fields|",
|
|static_values| should be <= |static_fields|",
|
||||||
String::from(&descriptor.get_name()),
|
&descriptor.get_name().__str__(),
|
||||||
values.len(),
|
values.len(),
|
||||||
static_fields_list.len()
|
static_fields_list.len()
|
||||||
));
|
));
|
||||||
|
|
@ -266,7 +266,7 @@ impl Apk {
|
||||||
info!(
|
info!(
|
||||||
"Annotation for field {} found in class {}, dropping it",
|
"Annotation for field {} found in class {}, dropping it",
|
||||||
field_id.__str__(),
|
field_id.__str__(),
|
||||||
String::from(descriptor.get_name()),
|
descriptor.get_name().__str__(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
instance_fields
|
instance_fields
|
||||||
|
|
@ -275,8 +275,8 @@ impl Apk {
|
||||||
static_fields
|
static_fields
|
||||||
.entry(field_id.clone())
|
.entry(field_id.clone())
|
||||||
.and_modify(|field| field.annotations = annotations.clone());
|
.and_modify(|field| field.annotations = annotations.clone());
|
||||||
if instance_fields.get(&field_id).is_none()
|
if !instance_fields.contains_key(&field_id)
|
||||||
&& static_fields.get(&field_id).is_none()
|
&& !static_fields.contains_key(&field_id)
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Annotation found for field {} but could not find the field definition, dropping it",
|
"Annotation found for field {} but could not find the field definition, dropping it",
|
||||||
|
|
@ -299,7 +299,7 @@ impl Apk {
|
||||||
info!(
|
info!(
|
||||||
"Annotation for method {} found in class {}, dropping it",
|
"Annotation for method {} found in class {}, dropping it",
|
||||||
method_id.__str__(),
|
method_id.__str__(),
|
||||||
String::from(descriptor.get_name()),
|
descriptor.get_name().__str__(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
direct_methods
|
direct_methods
|
||||||
|
|
@ -308,8 +308,8 @@ impl Apk {
|
||||||
virtual_methods
|
virtual_methods
|
||||||
.entry(method_id.clone())
|
.entry(method_id.clone())
|
||||||
.and_modify(|method| method.annotations = annotations.clone()); // TODO = or append?
|
.and_modify(|method| method.annotations = annotations.clone()); // TODO = or append?
|
||||||
if direct_methods.get(&method_id).is_none()
|
if !direct_methods.contains_key(&method_id)
|
||||||
&& virtual_methods.get(&method_id).is_none()
|
&& !virtual_methods.contains_key(&method_id)
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Annotation found for method {} but could not find the method definition, dropping it",
|
"Annotation found for method {} but could not find the method definition, dropping it",
|
||||||
|
|
@ -338,7 +338,7 @@ impl Apk {
|
||||||
info!(
|
info!(
|
||||||
"Annotation for parameter of method {} found in class {}, dropping it",
|
"Annotation for parameter of method {} found in class {}, dropping it",
|
||||||
method_id.__str__(),
|
method_id.__str__(),
|
||||||
String::from(descriptor.get_name()),
|
descriptor.get_name().__str__(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
direct_methods
|
direct_methods
|
||||||
|
|
@ -347,8 +347,8 @@ impl Apk {
|
||||||
virtual_methods
|
virtual_methods
|
||||||
.entry(method_id.clone())
|
.entry(method_id.clone())
|
||||||
.and_modify(|method| method.parameters_annotations = annotations_list.clone());
|
.and_modify(|method| method.parameters_annotations = annotations_list.clone());
|
||||||
if direct_methods.get(&method_id).is_none()
|
if !direct_methods.contains_key(&method_id)
|
||||||
&& virtual_methods.get(&method_id).is_none()
|
&& !virtual_methods.contains_key(&method_id)
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Annotation found for parameter of method {} but could not find the method definition, dropping it",
|
"Annotation found for parameter of method {} but could not find the method definition, dropping it",
|
||||||
|
|
@ -654,8 +654,8 @@ impl Apk {
|
||||||
(false, false, true) => FieldVisibility::Protected,
|
(false, false, true) => FieldVisibility::Protected,
|
||||||
(false, false, false) => FieldVisibility::None_,
|
(false, false, false) => FieldVisibility::None_,
|
||||||
(pbl, prv, prt) => {
|
(pbl, prv, prt) => {
|
||||||
let class: String = descriptor.class_.0.into();
|
let class: String = descriptor.class_.0.__str__();
|
||||||
let name: String = descriptor.name.into();
|
let name: String = descriptor.name.__str__();
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Inconsistant visiblity found in {class}.{name}: \
|
"Inconsistant visiblity found in {class}.{name}: \
|
||||||
(public: {pbl}, private: {prv}, protected: {prt})"
|
(public: {pbl}, private: {prv}, protected: {prt})"
|
||||||
|
|
@ -2812,7 +2812,7 @@ impl Apk {
|
||||||
.name_idx
|
.name_idx
|
||||||
.map(|idx| dex.get_string(idx))
|
.map(|idx| dex.get_string(idx))
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.map(|str| DexString(str).into()),
|
.map(DexString),
|
||||||
type_: val
|
type_: val
|
||||||
.type_idx
|
.type_idx
|
||||||
.map(|idx| Self::get_id_type_from_idx(idx as usize, dex))
|
.map(|idx| Self::get_id_type_from_idx(idx as usize, dex))
|
||||||
|
|
@ -2821,7 +2821,7 @@ impl Apk {
|
||||||
.sig_idx
|
.sig_idx
|
||||||
.map(|idx| dex.get_string(idx))
|
.map(|idx| dex.get_string(idx))
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.map(|str| DexString(str).into()),
|
.map(DexString),
|
||||||
},
|
},
|
||||||
DebugInfo::EndLocal { reg, .. } => Instruction::DebugEndLocal { reg },
|
DebugInfo::EndLocal { reg, .. } => Instruction::DebugEndLocal { reg },
|
||||||
DebugInfo::PrologueEnd { .. } => Instruction::DebugEndPrologue {},
|
DebugInfo::PrologueEnd { .. } => Instruction::DebugEndPrologue {},
|
||||||
|
|
@ -2832,7 +2832,7 @@ impl Apk {
|
||||||
file: source_file_idx
|
file: source_file_idx
|
||||||
.map(|idx| dex.get_string(idx))
|
.map(|idx| dex.get_string(idx))
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.map(|str| DexString(str).into()),
|
.map(DexString),
|
||||||
},
|
},
|
||||||
DebugInfo::SetLineNumber { line_num, .. } => Instruction::DebugLine {
|
DebugInfo::SetLineNumber { line_num, .. } => Instruction::DebugLine {
|
||||||
number: line_num as usize,
|
number: line_num as usize,
|
||||||
|
|
@ -3269,14 +3269,7 @@ impl Apk {
|
||||||
if !self.dex_files.contains_key(&file) {
|
if !self.dex_files.contains_key(&file) {
|
||||||
self.dex_files.insert(file.clone(), DexFile::default());
|
self.dex_files.insert(file.clone(), DexFile::default());
|
||||||
}
|
}
|
||||||
if self
|
if self.dex_files.get(&file).unwrap().classes.contains_key(&id) {
|
||||||
.dex_files
|
|
||||||
.get(&file)
|
|
||||||
.unwrap()
|
|
||||||
.classes
|
|
||||||
.get(&id)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
bail!("class {} already exists in {}", id.__str__(), &file);
|
bail!("class {} already exists in {}", id.__str__(), &file);
|
||||||
}
|
}
|
||||||
self.dex_files
|
self.dex_files
|
||||||
|
|
@ -3298,7 +3291,7 @@ impl Apk {
|
||||||
|
|
||||||
let class = if let Some(dex_file) = dex_file {
|
let class = if let Some(dex_file) = dex_file {
|
||||||
self.dex_files
|
self.dex_files
|
||||||
.get_mut(&dex_file.to_string())
|
.get_mut(dex_file)
|
||||||
.with_context(|| format!("file {} not found in apk", dex_file))?
|
.with_context(|| format!("file {} not found in apk", dex_file))?
|
||||||
.classes
|
.classes
|
||||||
.get_mut(&method_id.class_)
|
.get_mut(&method_id.class_)
|
||||||
|
|
@ -3345,7 +3338,7 @@ impl Apk {
|
||||||
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
|
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
|
||||||
if let Some(dex_file) = dex_file {
|
if let Some(dex_file) = dex_file {
|
||||||
self.dex_files
|
self.dex_files
|
||||||
.get_mut(&dex_file.to_string())
|
.get_mut(dex_file)
|
||||||
.with_context(|| format!("file {} not found in apk", dex_file))?
|
.with_context(|| format!("file {} not found in apk", dex_file))?
|
||||||
.classes
|
.classes
|
||||||
.remove(class);
|
.remove(class);
|
||||||
|
|
|
||||||
|
|
@ -109,15 +109,15 @@ impl Class {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __str__(&self) -> String {
|
pub fn __str__(&self) -> String {
|
||||||
let name: String = (&self.descriptor.get_name()).into();
|
let name: String = self.descriptor.get_name().__str__();
|
||||||
let file = if let Some(file) = &self.source_file {
|
let file = if let Some(file) = &self.source_file {
|
||||||
let file: String = file.into();
|
let file: String = file.__str__();
|
||||||
format!(" defined in {file}\n")
|
format!(" defined in {file}\n")
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
"".into()
|
||||||
};
|
};
|
||||||
let superclass = if let Some(spcl) = &self.superclass {
|
let superclass = if let Some(spcl) = &self.superclass {
|
||||||
let spcl: String = spcl.get_name().into();
|
let spcl: String = spcl.get_name().__str__();
|
||||||
format!(" extends: {spcl}\n")
|
format!(" extends: {spcl}\n")
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
"".into()
|
||||||
|
|
@ -127,7 +127,7 @@ impl Class {
|
||||||
} else {
|
} else {
|
||||||
let mut interfaces: String = " implements:\n".into();
|
let mut interfaces: String = " implements:\n".into();
|
||||||
for it in &self.interfaces {
|
for it in &self.interfaces {
|
||||||
let it: String = it.get_name().into();
|
let it: String = it.get_name().__str__();
|
||||||
interfaces += &format!(" {it}\n");
|
interfaces += &format!(" {it}\n");
|
||||||
}
|
}
|
||||||
interfaces
|
interfaces
|
||||||
|
|
@ -137,7 +137,7 @@ impl Class {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __repr__(&self) -> String {
|
pub fn __repr__(&self) -> String {
|
||||||
let name: String = (&self.descriptor.get_name()).into();
|
let name: String = self.descriptor.get_name().__str__();
|
||||||
format!("Class({name})")
|
format!("Class({name})")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
//! Representation of a method.
|
//! Representation of a method.
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use log::debug;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
|
@ -232,7 +233,7 @@ impl Code {
|
||||||
for ins in &self.insns {
|
for ins in &self.insns {
|
||||||
match ins {
|
match ins {
|
||||||
Instruction::Label { name } => {
|
Instruction::Label { name } => {
|
||||||
if used_labels.get(name).is_none() {
|
if !used_labels.contains(name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let new_label_id = if last_ins_was_a_label {
|
let new_label_id = if last_ins_was_a_label {
|
||||||
|
|
@ -250,8 +251,8 @@ impl Code {
|
||||||
}
|
}
|
||||||
|
|
||||||
for label in &used_labels {
|
for label in &used_labels {
|
||||||
if new_labels.get(label).is_none() {
|
if !new_labels.contains_key(label) {
|
||||||
println!("{label} use but not in new_labels");
|
debug!("{label} use but not in new_labels");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -455,7 +456,7 @@ impl Code {
|
||||||
new_insns.push(Instruction::Switch { branches, reg });
|
new_insns.push(Instruction::Switch { branches, reg });
|
||||||
}
|
}
|
||||||
Instruction::Label { name } => {
|
Instruction::Label { name } => {
|
||||||
if used_labels.get(&name).is_none() {
|
if !used_labels.contains(&name) {
|
||||||
//println!("{name} not used");
|
//println!("{name} not used");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,9 +216,10 @@ impl IdMethodType {
|
||||||
/// Compute the format for the shorty as described in
|
/// Compute the format for the shorty as described in
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||||
pub fn compute_shorty(return_type: &IdType, parameters: &[IdType]) -> DexString {
|
pub fn compute_shorty(return_type: &IdType, parameters: &[IdType]) -> DexString {
|
||||||
let mut shorty: String = return_type.get_shorty().into();
|
// TODO: computing on dex string instead of string? that a lot of doubious conversion
|
||||||
|
let mut shorty: String = return_type.get_shorty().__str__();
|
||||||
for ty in parameters {
|
for ty in parameters {
|
||||||
let ty: String = ty.get_shorty().into();
|
let ty: String = ty.get_shorty().__str__();
|
||||||
shorty.push_str(&ty);
|
shorty.push_str(&ty);
|
||||||
}
|
}
|
||||||
shorty.into()
|
shorty.into()
|
||||||
|
|
@ -441,11 +442,11 @@ impl IdType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __str__(&self) -> String {
|
pub fn __str__(&self) -> String {
|
||||||
(&self.0).into()
|
self.0.__str__()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __repr__(&self) -> String {
|
pub fn __repr__(&self) -> String {
|
||||||
let name: String = (&self.0).into();
|
let name: String = self.0.__str__();
|
||||||
format!("IdType(\"{name}\")")
|
format!("IdType(\"{name}\")")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,7 +563,7 @@ impl IdType {
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let format: String = (&self.0).into();
|
let format: String = self.0.__str__();
|
||||||
Err(anyhow!("{format} is not a valid type"))
|
Err(anyhow!("{format} is not a valid type"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -744,15 +745,15 @@ impl IdField {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __str__(&self) -> String {
|
pub fn __str__(&self) -> String {
|
||||||
let class: String = self.class_.get_name().into();
|
let class: String = self.class_.get_name().__str__();
|
||||||
let name: String = (&self.name).into();
|
let name: String = self.name.__str__();
|
||||||
let ty: String = self.type_.get_name().into();
|
let ty: String = self.type_.get_name().__str__();
|
||||||
format!("{class}->{name}:{ty}")
|
format!("{class}->{name}:{ty}")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __repr__(&self) -> String {
|
pub fn __repr__(&self) -> String {
|
||||||
let class: String = self.class_.__repr__();
|
let class: String = self.class_.__repr__();
|
||||||
let name: String = (&self.name).into();
|
let name: String = self.name.__str__();
|
||||||
let ty: String = self.type_.__repr__();
|
let ty: String = self.type_.__repr__();
|
||||||
format!("IdField(\"{name}\", {ty}, {class})")
|
format!("IdField(\"{name}\", {ty}, {class})")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
||||||
|
use anyhow::{Context, Error};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::cmp::{Ord, PartialOrd};
|
use std::cmp::{Ord, PartialOrd};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
@ -26,7 +27,6 @@ impl<V: VisitorMut> VisitableMut<V> for DexString {
|
||||||
|
|
||||||
impl std::fmt::Debug for DexString {
|
impl std::fmt::Debug for DexString {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
#[allow(clippy::unnecessary_fallible_conversions)]
|
|
||||||
if let Ok(string) = TryInto::<String>::try_into(self) {
|
if let Ok(string) = TryInto::<String>::try_into(self) {
|
||||||
f.write_str(&format!(
|
f.write_str(&format!(
|
||||||
"DexString({}, {:#x})",
|
"DexString({}, {:#x})",
|
||||||
|
|
@ -117,17 +117,19 @@ impl From<androscalpel_serializer::StringDataItem> for DexString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&DexString> for String {
|
impl TryFrom<&DexString> for String {
|
||||||
fn from(DexString(string): &DexString) -> Self {
|
type Error = Error;
|
||||||
|
fn try_from(DexString(string): &DexString) -> Result<Self> {
|
||||||
string
|
string
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap_or(format!("InvalidEncoding:{:x?}", string.data))
|
.with_context(|| format!("InvalidEncoding:{:x?}", string.data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DexString> for String {
|
impl TryFrom<DexString> for String {
|
||||||
fn from(string: DexString) -> Self {
|
type Error = Error;
|
||||||
(&string).into()
|
fn try_from(string: DexString) -> Result<Self> {
|
||||||
|
(&string).try_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,11 +193,15 @@ impl DexString {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __str__(&self) -> String {
|
pub fn __str__(&self) -> String {
|
||||||
self.into()
|
if let Ok(string) = TryInto::<String>::try_into(self) {
|
||||||
|
string
|
||||||
|
} else {
|
||||||
|
format!("string{:02x?}", self.0.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __repr__(&self) -> String {
|
pub fn __repr__(&self) -> String {
|
||||||
self.into()
|
format!("{:?}", self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all strings references in the value.
|
/// Return all strings references in the value.
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ impl DexWriter {
|
||||||
let new_nb_types = self.type_ids.len()
|
let new_nb_types = self.type_ids.len()
|
||||||
+ new_types
|
+ new_types
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|ty| self.type_ids.get(ty).is_none())
|
.filter(|ty| !self.type_ids.contains_key(ty))
|
||||||
.count();
|
.count();
|
||||||
if new_nb_types >= u16::MAX as usize {
|
if new_nb_types >= u16::MAX as usize {
|
||||||
return Err(DexWritterError::OutOfSpace(
|
return Err(DexWritterError::OutOfSpace(
|
||||||
|
|
@ -204,7 +204,7 @@ impl DexWriter {
|
||||||
let new_nb_protos = self.proto_ids.len()
|
let new_nb_protos = self.proto_ids.len()
|
||||||
+ new_protos
|
+ new_protos
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|proto| self.proto_ids.get(proto).is_none())
|
.filter(|proto| !self.proto_ids.contains_key(proto))
|
||||||
.count();
|
.count();
|
||||||
if new_nb_protos >= u16::MAX as usize {
|
if new_nb_protos >= u16::MAX as usize {
|
||||||
return Err(DexWritterError::OutOfSpace(
|
return Err(DexWritterError::OutOfSpace(
|
||||||
|
|
@ -216,7 +216,7 @@ impl DexWriter {
|
||||||
let new_nb_field_ids = self.field_ids.len()
|
let new_nb_field_ids = self.field_ids.len()
|
||||||
+ new_field_ids
|
+ new_field_ids
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|field| self.field_ids.get(field).is_none())
|
.filter(|field| !self.field_ids.contains_key(field))
|
||||||
.count();
|
.count();
|
||||||
if new_nb_field_ids >= u16::MAX as usize {
|
if new_nb_field_ids >= u16::MAX as usize {
|
||||||
return Err(DexWritterError::OutOfSpace(
|
return Err(DexWritterError::OutOfSpace(
|
||||||
|
|
@ -228,7 +228,7 @@ impl DexWriter {
|
||||||
let new_nb_method_ids = self.method_ids.len()
|
let new_nb_method_ids = self.method_ids.len()
|
||||||
+ new_method_ids
|
+ new_method_ids
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|meth| self.method_ids.get(meth).is_none())
|
.filter(|meth| !self.method_ids.contains_key(meth))
|
||||||
.count();
|
.count();
|
||||||
if new_nb_method_ids >= u16::MAX as usize {
|
if new_nb_method_ids >= u16::MAX as usize {
|
||||||
return Err(DexWritterError::OutOfSpace(
|
return Err(DexWritterError::OutOfSpace(
|
||||||
|
|
@ -737,7 +737,7 @@ impl DexWriter {
|
||||||
"Could not found type {} of local variable {} in debug info of {} \
|
"Could not found type {} of local variable {} in debug info of {} \
|
||||||
in the dex builder",
|
in the dex builder",
|
||||||
ty.__repr__(),
|
ty.__repr__(),
|
||||||
name.as_deref().unwrap_or(""),
|
name.as_ref().map(DexString::__str__).unwrap_or_default(),
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
@ -745,10 +745,10 @@ impl DexWriter {
|
||||||
.map(|idx| *idx as u32),
|
.map(|idx| *idx as u32),
|
||||||
name_idx: name.as_ref()
|
name_idx: name.as_ref()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
self.strings.get(&name.as_str().into()).ok_or(anyhow!(
|
self.strings.get(name).ok_or(anyhow!(
|
||||||
"Could not found string '{}' (name of local variable in debug info of {}) \
|
"Could not found string '{}' (name of local variable in debug info of {}) \
|
||||||
in the dex builder",
|
in the dex builder",
|
||||||
name.as_str(),
|
name.__str__(),
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
@ -756,11 +756,11 @@ impl DexWriter {
|
||||||
.map(|idx| *idx as u32),
|
.map(|idx| *idx as u32),
|
||||||
sig_idx: signature.as_ref()
|
sig_idx: signature.as_ref()
|
||||||
.map(|sig| {
|
.map(|sig| {
|
||||||
self.strings.get(&sig.as_str().into()).ok_or(anyhow!(
|
self.strings.get(sig).ok_or(anyhow!(
|
||||||
"Could not found string '{}' (signature of local variable {} in debug info of {}) \
|
"Could not found string '{}' (signature of local variable {} in debug info of {}) \
|
||||||
in the dex builder",
|
in the dex builder",
|
||||||
sig,
|
sig.__str__(),
|
||||||
name.as_deref().unwrap_or(""),
|
name.as_ref().map(DexString::__str__).unwrap_or_default(),
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
@ -776,7 +776,7 @@ impl DexWriter {
|
||||||
addr: addr as u32,
|
addr: addr as u32,
|
||||||
reg: *reg,
|
reg: *reg,
|
||||||
})
|
})
|
||||||
.context("Failled to serialize DebugEndLocal information")?,
|
.context("Failled to seri2846alize DebugEndLocal information")?,
|
||||||
Instruction::DebugEndPrologue {} => debug_builder
|
Instruction::DebugEndPrologue {} => debug_builder
|
||||||
.add_info(&DebugInfo::PrologueEnd { addr: addr as u32 })
|
.add_info(&DebugInfo::PrologueEnd { addr: addr as u32 })
|
||||||
.context("Failled to serialize DebugEndPrologue information")?,
|
.context("Failled to serialize DebugEndPrologue information")?,
|
||||||
|
|
@ -788,10 +788,10 @@ impl DexWriter {
|
||||||
addr: addr as u32,
|
addr: addr as u32,
|
||||||
source_file_idx: file.as_ref()
|
source_file_idx: file.as_ref()
|
||||||
.map(|file| {
|
.map(|file| {
|
||||||
self.strings.get(&file.as_str().into()).ok_or(anyhow!(
|
self.strings.get(file).ok_or(anyhow!(
|
||||||
"Could not found string '{}' (name of the source file of part of {}) \
|
"Could not found string '{}' (name of the source file of part of {}) \
|
||||||
in the dex builder",
|
in the dex builder",
|
||||||
file,
|
file.__str__(),
|
||||||
method_id.__repr__()
|
method_id.__repr__()
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
@ -874,7 +874,6 @@ impl DexWriter {
|
||||||
|
|
||||||
/// Insert annotation associated to a class.
|
/// Insert annotation associated to a class.
|
||||||
///
|
///
|
||||||
|
|
||||||
/// Insert a class_data_item in the class_data section (in data).
|
/// Insert a class_data_item in the class_data section (in data).
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
|
|
@ -2273,12 +2272,12 @@ impl DexWriter {
|
||||||
for (ty, (def, _)) in &self.class_defs {
|
for (ty, (def, _)) in &self.class_defs {
|
||||||
let mut edges_to = HashSet::new();
|
let mut edges_to = HashSet::new();
|
||||||
if let Some(sup) = def.superclass.as_ref() {
|
if let Some(sup) = def.superclass.as_ref() {
|
||||||
if self.class_defs.get(sup).is_some() {
|
if self.class_defs.contains_key(sup) {
|
||||||
edges_to.insert(sup);
|
edges_to.insert(sup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for sup in &def.interfaces {
|
for sup in &def.interfaces {
|
||||||
if self.class_defs.get(sup).is_some() {
|
if self.class_defs.contains_key(sup) {
|
||||||
edges_to.insert(sup);
|
edges_to.insert(sup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ impl From<&androscalpel_serializer::HiddenApiFlags> for HiddenApiData {
|
||||||
}
|
}
|
||||||
impl From<androscalpel_serializer::HiddenApiFlags> for HiddenApiData {
|
impl From<androscalpel_serializer::HiddenApiFlags> for HiddenApiData {
|
||||||
fn from(flags: androscalpel_serializer::HiddenApiFlags) -> Self {
|
fn from(flags: androscalpel_serializer::HiddenApiFlags) -> Self {
|
||||||
flags.into()
|
(&flags).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ impl From<&HiddenApiData> for androscalpel_serializer::HiddenApiFlags {
|
||||||
}
|
}
|
||||||
impl From<HiddenApiData> for androscalpel_serializer::HiddenApiFlags {
|
impl From<HiddenApiData> for androscalpel_serializer::HiddenApiFlags {
|
||||||
fn from(flags: HiddenApiData) -> Self {
|
fn from(flags: HiddenApiData) -> Self {
|
||||||
flags.into()
|
(&flags).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -638,9 +638,9 @@ pub enum Instruction {
|
||||||
/// Debug information. Define a local variable associated with a register.
|
/// Debug information. Define a local variable associated with a register.
|
||||||
DebugLocal {
|
DebugLocal {
|
||||||
reg: u32,
|
reg: u32,
|
||||||
name: Option<String>,
|
name: Option<DexString>,
|
||||||
type_: Option<IdType>,
|
type_: Option<IdType>,
|
||||||
signature: Option<String>,
|
signature: Option<DexString>,
|
||||||
},
|
},
|
||||||
/// Debug information. Undefine a local variable associated with a register.
|
/// Debug information. Undefine a local variable associated with a register.
|
||||||
DebugEndLocal { reg: u32 },
|
DebugEndLocal { reg: u32 },
|
||||||
|
|
@ -649,7 +649,7 @@ pub enum Instruction {
|
||||||
/// Debug information. Indicate the beginning of the Epilogue
|
/// Debug information. Indicate the beginning of the Epilogue
|
||||||
DebugBeginEpilogue {},
|
DebugBeginEpilogue {},
|
||||||
/// Debug information. Indicate the source file of the following instructions.
|
/// Debug information. Indicate the source file of the following instructions.
|
||||||
DebugSourceFile { file: Option<String> },
|
DebugSourceFile { file: Option<DexString> },
|
||||||
/// Debug information. Indicate the line number of the following instructions.
|
/// Debug information. Indicate the line number of the following instructions.
|
||||||
DebugLine { number: usize },
|
DebugLine { number: usize },
|
||||||
}
|
}
|
||||||
|
|
@ -1216,20 +1216,25 @@ impl<V: Visitor> Visitable<V> for Instruction {
|
||||||
Self::Label { name: _ } => Ok(()),
|
Self::Label { name: _ } => Ok(()),
|
||||||
Self::DebugLocal {
|
Self::DebugLocal {
|
||||||
reg: _,
|
reg: _,
|
||||||
name: _,
|
name,
|
||||||
type_: Some(type_),
|
type_,
|
||||||
signature: _,
|
signature,
|
||||||
} => v.visit_type(type_),
|
} => {
|
||||||
Self::DebugLocal {
|
if let Some(name) = name {
|
||||||
reg: _,
|
v.visit_string(name)?;
|
||||||
name: _,
|
}
|
||||||
type_: None,
|
if let Some(type_) = type_ {
|
||||||
signature: _,
|
v.visit_type(type_)?;
|
||||||
} => Ok(()),
|
}
|
||||||
|
if let Some(signature) = signature {
|
||||||
|
v.visit_string(signature)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Self::DebugEndLocal { reg: _ } => Ok(()),
|
Self::DebugEndLocal { reg: _ } => Ok(()),
|
||||||
Self::DebugEndPrologue {} => Ok(()),
|
Self::DebugEndPrologue {} => Ok(()),
|
||||||
Self::DebugBeginEpilogue {} => Ok(()),
|
Self::DebugBeginEpilogue {} => Ok(()),
|
||||||
Self::DebugSourceFile { file: Some(file) } => v.visit_string(&(file.as_str().into())),
|
Self::DebugSourceFile { file: Some(file) } => v.visit_string(file),
|
||||||
Self::DebugSourceFile { file: None } => Ok(()),
|
Self::DebugSourceFile { file: None } => Ok(()),
|
||||||
Self::DebugLine { number: _ } => Ok(()),
|
Self::DebugLine { number: _ } => Ok(()),
|
||||||
}
|
}
|
||||||
|
|
@ -1883,19 +1888,18 @@ impl<V: VisitorMut> VisitableMut<V> for Instruction {
|
||||||
signature,
|
signature,
|
||||||
} => Ok(Self::DebugLocal {
|
} => Ok(Self::DebugLocal {
|
||||||
reg,
|
reg,
|
||||||
name,
|
name: name.map(|name| v.visit_string(name)).transpose()?,
|
||||||
type_: type_.map(|type_| v.visit_type(type_)).transpose()?,
|
type_: type_.map(|type_| v.visit_type(type_)).transpose()?,
|
||||||
signature,
|
signature: signature
|
||||||
|
.map(|signature| v.visit_string(signature))
|
||||||
|
.transpose()?,
|
||||||
}),
|
}),
|
||||||
Self::DebugEndLocal { reg: _ } => Ok(self),
|
Self::DebugEndLocal { reg: _ } => Ok(self),
|
||||||
Self::DebugEndPrologue {} => Ok(self),
|
Self::DebugEndPrologue {} => Ok(self),
|
||||||
Self::DebugBeginEpilogue {} => Ok(self),
|
Self::DebugBeginEpilogue {} => Ok(self),
|
||||||
Self::DebugSourceFile { file: Some(file) } => {
|
Self::DebugSourceFile { file: Some(file) } => v
|
||||||
v.visit_string(file.as_str().into())
|
.visit_string(file)
|
||||||
.map(|file| Self::DebugSourceFile {
|
.map(|file| Self::DebugSourceFile { file: Some(file) }),
|
||||||
file: Some(file.into()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Self::DebugSourceFile { file: None } => Ok(self),
|
Self::DebugSourceFile { file: None } => Ok(self),
|
||||||
Self::DebugLine { number: _ } => Ok(self),
|
Self::DebugLine { number: _ } => Ok(self),
|
||||||
}
|
}
|
||||||
|
|
@ -2081,7 +2085,7 @@ macro_rules! raw_ins_invoke {
|
||||||
})
|
})
|
||||||
} else if consec && len <= 255 {
|
} else if consec && len <= 255 {
|
||||||
let a = $args.len() as u8;
|
let a = $args.len() as u8;
|
||||||
let vc = if let Some(vc) = first { vc } else { 0 };
|
let vc = first.unwrap_or(0);
|
||||||
Ok(InsFormat::Format3RC {
|
Ok(InsFormat::Format3RC {
|
||||||
op: $ins_op_3rc,
|
op: $ins_op_3rc,
|
||||||
a,
|
a,
|
||||||
|
|
@ -2833,10 +2837,10 @@ impl Instruction {
|
||||||
signature,
|
signature,
|
||||||
} => {
|
} => {
|
||||||
// TODO: check if/how apktool/smali handles empty name and type
|
// TODO: check if/how apktool/smali handles empty name and type
|
||||||
let name = name.clone().unwrap_or(String::new());
|
let name = name.as_ref().map(DexString::__str__).unwrap_or_default();
|
||||||
let ty = type_.as_ref().map(IdType::__str__).unwrap_or(String::new());
|
let ty = type_.as_ref().map(IdType::__str__).unwrap_or(String::new());
|
||||||
if let Some(signature) = signature {
|
if let Some(signature) = signature {
|
||||||
format!(".local {reg}, \"{name}\":{ty}, \"{signature}\"")
|
format!(".local {reg}, \"{name}\":{ty}, \"{}\"", signature.__str__())
|
||||||
} else {
|
} else {
|
||||||
format!(".local {reg}, \"{name}\":{ty}")
|
format!(".local {reg}, \"{name}\":{ty}")
|
||||||
}
|
}
|
||||||
|
|
@ -2845,7 +2849,9 @@ impl Instruction {
|
||||||
Self::DebugEndPrologue {} => ".prologue".into(),
|
Self::DebugEndPrologue {} => ".prologue".into(),
|
||||||
Self::DebugBeginEpilogue {} => ".epilogue".into(),
|
Self::DebugBeginEpilogue {} => ".epilogue".into(),
|
||||||
// TODO: check if/how apktool/smali handles empty change of src file
|
// TODO: check if/how apktool/smali handles empty change of src file
|
||||||
Self::DebugSourceFile { file: Some(file) } => format!(".source_file {file}"),
|
Self::DebugSourceFile { file: Some(file) } => {
|
||||||
|
format!(".source_file {}", file.__str__())
|
||||||
|
}
|
||||||
// TODO: find a better representation
|
// TODO: find a better representation
|
||||||
Self::DebugSourceFile { file: None } => ".source_file unknown".into(),
|
Self::DebugSourceFile { file: None } => ".source_file unknown".into(),
|
||||||
Self::DebugLine { number } => format!(".line {number}"),
|
Self::DebugLine { number } => format!(".line {number}"),
|
||||||
|
|
@ -3643,12 +3649,12 @@ impl Instruction {
|
||||||
type_,
|
type_,
|
||||||
signature,
|
signature,
|
||||||
} => {
|
} => {
|
||||||
let name = name.clone().unwrap_or("None".into());
|
let name = name.clone().unwrap_or("None".into()).__str__();
|
||||||
let type_ = type_
|
let type_ = type_
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(IdType::__repr__)
|
.map(IdType::__repr__)
|
||||||
.unwrap_or("None".into());
|
.unwrap_or("None".into());
|
||||||
let signature = signature.clone().unwrap_or("None".into());
|
let signature = signature.clone().unwrap_or("None".into()).__str__();
|
||||||
format!("Instruction::DebugLoca({reg}, {name}, {type_}, {signature}")
|
format!("Instruction::DebugLoca({reg}, {name}, {type_}, {signature}")
|
||||||
}
|
}
|
||||||
Self::DebugEndLocal { reg } => format!("Instruction::DebugEndLocal({reg})"),
|
Self::DebugEndLocal { reg } => format!("Instruction::DebugEndLocal({reg})"),
|
||||||
|
|
@ -3656,7 +3662,7 @@ impl Instruction {
|
||||||
Self::DebugBeginEpilogue {} => "Instruction::DebugBeginEpilogue".into(),
|
Self::DebugBeginEpilogue {} => "Instruction::DebugBeginEpilogue".into(),
|
||||||
// TODO: check if/how apktool/smali handles empty change of src file
|
// TODO: check if/how apktool/smali handles empty change of src file
|
||||||
Self::DebugSourceFile { file: Some(file) } => {
|
Self::DebugSourceFile { file: Some(file) } => {
|
||||||
format!("Instruction::DebugSourceFile({file})")
|
format!("Instruction::DebugSourceFile({})", file.__str__())
|
||||||
}
|
}
|
||||||
Self::DebugSourceFile { file: None } => "Instruction::DebugSourceFile(None)".into(),
|
Self::DebugSourceFile { file: None } => "Instruction::DebugSourceFile(None)".into(),
|
||||||
Self::DebugLine { number } => format!("Instruction::DebugLine({number})"),
|
Self::DebugLine { number } => format!("Instruction::DebugLine({number})"),
|
||||||
|
|
@ -4464,7 +4470,7 @@ impl Instruction {
|
||||||
})
|
})
|
||||||
} else if consec && len <= 255 {
|
} else if consec && len <= 255 {
|
||||||
let a = reg_values.len() as u8;
|
let a = reg_values.len() as u8;
|
||||||
let vc = if let Some(vc) = first { vc } else { 0 };
|
let vc = first.unwrap_or(0);
|
||||||
Ok(InsFormat::Format3RC {
|
Ok(InsFormat::Format3RC {
|
||||||
op: 0x25,
|
op: 0x25,
|
||||||
a,
|
a,
|
||||||
|
|
@ -5358,7 +5364,7 @@ impl Instruction {
|
||||||
})
|
})
|
||||||
} else if consec && len <= 255 {
|
} else if consec && len <= 255 {
|
||||||
let a = args.len() as u8;
|
let a = args.len() as u8;
|
||||||
let vc = if let Some(vc) = first { vc } else { 0 };
|
let vc = first.unwrap_or(0);
|
||||||
Ok(InsFormat::Format4RCC {
|
Ok(InsFormat::Format4RCC {
|
||||||
op: 0xfb,
|
op: 0xfb,
|
||||||
a,
|
a,
|
||||||
|
|
@ -5435,7 +5441,7 @@ impl Instruction {
|
||||||
})
|
})
|
||||||
} else if consec && len <= 255 {
|
} else if consec && len <= 255 {
|
||||||
let a = args.len() as u8;
|
let a = args.len() as u8;
|
||||||
let vc = if let Some(vc) = first { vc } else { 0 };
|
let vc = first.unwrap_or(0);
|
||||||
Ok(InsFormat::Format3RC {
|
Ok(InsFormat::Format3RC {
|
||||||
op: 0xfd,
|
op: 0xfd,
|
||||||
a,
|
a,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
//#![allow(clippy::unnecessary_fallible_conversions)]
|
|
||||||
// DexString has Into<String> but it's only for
|
|
||||||
// python, TryInto should be prefered
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@ impl CodeItem {
|
||||||
addresses.push(try_.start_addr);
|
addresses.push(try_.start_addr);
|
||||||
addresses.push(try_.start_addr + try_.insn_count as u32);
|
addresses.push(try_.start_addr + try_.insn_count as u32);
|
||||||
}
|
}
|
||||||
for handler in &self.handlers {
|
if let Some(handlers) = &self.handlers {
|
||||||
for catch in &handler.list {
|
for catch in &handlers.list {
|
||||||
for EncodedTypeAddrPair {
|
for EncodedTypeAddrPair {
|
||||||
addr: Uleb128(addr),
|
addr: Uleb128(addr),
|
||||||
..
|
..
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use apk_frauder::ZipFileReader;
|
use apk_frauder::ZipFileReader;
|
||||||
use std::collections::HashMap;
|
//use std::collections::HashMap;
|
||||||
use std::env;
|
//use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Cursor;
|
//use std::io::Cursor;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue