#![allow(warnings)]
mod utils;
use lief;
use std::path::Path;
fn explore_method(meth: &lief::objc::Method) {
println!(
"{}{}{}{}{}",
meth.name(),
meth.mangled_type(),
meth.address(),
meth.address(),
meth.is_instance()
);
}
fn explore_proptocol(prot: &lief::objc::Protocol) {
println!("{}", prot.to_decl());
println!("{}", prot.to_decl_with_opt(&lief::objc::DeclOpt::default()));
println!("{}", prot.mangled_name());
for meth in prot.optional_methods() {
explore_method(&meth);
}
for meth in prot.required_methods() {
explore_method(&meth);
}
for prop in prot.properties() {
explore_property(&prop);
}
}
fn explore_property(prop: &lief::objc::Property) {
println!("{}{}", prop.name(), prop.attribute());
}
fn explore_ivar(ivar: &lief::objc::IVar) {
println!("{}{}", ivar.name(), ivar.mangled_type());
}
fn explore_class(class: &lief::objc::Class) {
println!("{}", class.to_decl());
println!(
"{}",
class.to_decl_with_opt(&lief::objc::DeclOpt::default())
);
println!(
"{}{}{:?}",
class.name(),
class.demangled_name(),
class.is_meta()
);
if let Some(parent) = class.super_class() {
explore_class(&parent);
}
for meth in class.methods() {
explore_method(&meth);
}
for prot in class.protocols() {
explore_proptocol(&prot);
}
for prop in class.properties() {
explore_property(&prop);
}
for ivar in class.ivars() {
explore_ivar(&ivar);
}
}
fn explore_metadata(name: &str, metadata: &lief::objc::Metadata) {
for cls in metadata.classes() {
explore_class(&cls);
}
for prot in metadata.protocols() {
explore_proptocol(&prot);
}
println!("{}", metadata.to_decl());
println!(
"{}",
metadata.to_decl_with_opt(&lief::objc::DeclOpt::default())
);
if name == "Module_Framework" {
assert!(metadata.class_by_name("GADGestureRecognizer").is_some());
assert!(
metadata
.class_by_name("GADGestureRecognizer_xxxx")
.is_none()
);
assert!(metadata.protocol_by_name("PINCaching").is_some());
assert!(metadata.protocol_by_name("PINCaching_xxx").is_none());
}
}
fn test_with_str(name: &str, path_str: &str) {
if let Some(lief::Binary::MachO(fat)) = lief::Binary::parse(path_str) {
for bin in fat.iter() {
if let Some(metadata) = bin.objc_metadata() {
explore_metadata(name, &metadata);
}
}
}
}
fn test_with_fullpath(name: &str, suffix: &str) {
let path = utils::get_sample(Path::new(suffix)).unwrap();
let path_str = path.to_str().unwrap();
test_with_str(name, path_str);
}
#[test]
fn test_api() {
if !lief::is_extended() {
return;
}
test_with_fullpath("DebugHierarchyKit", "MachO/ios17/DebugHierarchyKit");
test_with_fullpath(
"NTKPrideWeaveFaceBundleCompanion",
"MachO/ios17/NTKPrideWeaveFaceBundleCompanion",
);
test_with_fullpath("RNCryptor.bin", "MachO/RNCryptor.bin");
test_with_fullpath("SingPass", "private/MachO/SingPass");
test_with_fullpath("Module_Framework", "private/MachO/Module_Framework");
}