handle automatic file selection for classes
This commit is contained in:
parent
91859170c3
commit
0bd5617f38
1 changed files with 66 additions and 6 deletions
|
|
@ -2931,13 +2931,72 @@ impl Apk {
|
||||||
Ok(bin_dex_files)
|
Ok(bin_dex_files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check for android platform classes?
|
||||||
/// Search for the given class. If several classes with the same name are found,
|
/// Search for the given class. If several classes with the same name are found,
|
||||||
/// return the class used by android (classes.dex over classes2.dex over classes3.dex ...),
|
/// return the class used by android (classes.dex over classes2.dex over classes3.dex until
|
||||||
|
/// classesN.dex does not exists),
|
||||||
/// and if not found in files used by android, look in any other files (classes0.dex,
|
/// and if not found in files used by android, look in any other files (classes0.dex,
|
||||||
/// classses1.dex, classes02.dex, assets/stuff.dex, ...), and select the first one in
|
/// classses1.dex, classes02.dex, assets/stuff.dex, ...), and select the first one in
|
||||||
/// alphabetical order of dex file name.
|
/// alphabetical order of dex file name.
|
||||||
pub fn get_class_mut(&mut self, class_id: IdType) -> Option<&mut Class> {
|
pub fn get_class_mut(&mut self, class_id: &IdType) -> Option<&mut Class> {
|
||||||
todo!()
|
self.get_file_of_class(class_id, false).and_then(|file| {
|
||||||
|
self.dex_files
|
||||||
|
.get_mut(&file)
|
||||||
|
.expect("`get_file_of_class()` return a string not in `dex_files`")
|
||||||
|
.classes
|
||||||
|
.get_mut(class_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Search for the dex file of a given class. If several classes with the same name exist,
|
||||||
|
/// return the file used by android (classes.dex over classes2.dex over classes3.dex until
|
||||||
|
/// classesN.dex does not exists), and if `valid_file_only` is set to false, look in any
|
||||||
|
/// other files (classes0.dex, classses1.dex, classes02.dex, assets/stuff.dex, ...), and
|
||||||
|
/// select the first one with the class in alphabetical order of dex file name.
|
||||||
|
fn get_file_of_class(&self, class_id: &IdType, valid_file_only: bool) -> Option<String> {
|
||||||
|
let mut files: HashSet<&String> = self.dex_files.keys().collect();
|
||||||
|
let mut i = 0;
|
||||||
|
let mut name: String = "classes.dex".into();
|
||||||
|
while files.contains(&name) {
|
||||||
|
if self
|
||||||
|
.dex_files
|
||||||
|
.get(&name)
|
||||||
|
.expect(
|
||||||
|
"Something went wrong: `name` is from \
|
||||||
|
`dex_files.keys()` but `dex_files.get(&name)` \
|
||||||
|
failled",
|
||||||
|
)
|
||||||
|
.classes
|
||||||
|
.contains_key(class_id)
|
||||||
|
{
|
||||||
|
return Some(name);
|
||||||
|
}
|
||||||
|
files.remove(&name);
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
}
|
||||||
|
if valid_file_only {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut files = files.into_iter().collect::<Vec<&String>>();
|
||||||
|
files.sort();
|
||||||
|
for name in files.into_iter() {
|
||||||
|
if self
|
||||||
|
.dex_files
|
||||||
|
.get(name)
|
||||||
|
.expect(
|
||||||
|
"Something went wrong: `name` is from \
|
||||||
|
`dex_files.keys()` but `dex_files.get(&name)` \
|
||||||
|
failled",
|
||||||
|
)
|
||||||
|
.classes
|
||||||
|
.contains_key(class_id)
|
||||||
|
{
|
||||||
|
return Some(name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3012,7 +3071,7 @@ impl Apk {
|
||||||
)
|
)
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
self.get_class_mut(ty.clone())
|
self.get_class_mut(ty)
|
||||||
.with_context(|| format!("{} not found in apk", method_id.class_.__repr__()))?
|
.with_context(|| format!("{} not found in apk", method_id.class_.__repr__()))?
|
||||||
};
|
};
|
||||||
let method = class
|
let method = class
|
||||||
|
|
@ -3047,7 +3106,6 @@ 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<()> {
|
||||||
// TODO: remove all if dex_file is not provided
|
|
||||||
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.to_string())
|
||||||
|
|
@ -3055,7 +3113,9 @@ impl Apk {
|
||||||
.classes
|
.classes
|
||||||
.remove(class);
|
.remove(class);
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
for DexFile { classes, .. } in self.dex_files.values_mut() {
|
||||||
|
classes.remove(class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue