Files
lief-project-LIEF/api/python/examples/objc_dump.py
T
2024-07-13 07:51:52 +02:00

67 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env python
'''
This script dumps the Objective-C metadata from the provided binary and
generate a header-like of different structure identified.
Note: this script is only working with the extended version of LIEF
'''
import sys
import lief
import argparse
from pathlib import Path
from typing import Optional
def process(filepath: str, skip_protocols: bool = False,
output_path: Optional[str] = None) -> int:
target = Path(filepath)
if not target.is_file():
print(f"'{target}' is not a valid file", file=sys.stderr)
return 1
macho = lief.MachO.parse(target)
if macho is None:
print(f"Can't parse Mach-O file: {target}", file=sys.stderr)
metadata = macho.at(0).objc_metadata
if metadata is None:
print(f"Can't parse ObjC metadata in {target}'", file=sys.stderr)
return 1
if skip_protocols:
output = ""
for cls in metadata.classes:
output += cls.to_decl()
else:
output = metadata.to_decl()
print(output)
if output_path is not None:
out = Path(output_path)
if out.is_dir():
out /= f"{target.name}_objc.h"
out.write_text(output)
print(f"Saved in {out}")
else:
print(f"Saved in {out}")
out.write_text(output)
return 0
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output',
help='Output file',
default=None)
parser.add_argument('--skip-protocols',
help='Skip ObjC protocols definition',
action='store_true')
parser.add_argument("file", help='Mach-O file')
args = parser.parse_args()
lief.logging.set_level(lief.logging.LEVEL.WARN)
return process(args.file, args.skip_protocols, args.output)
if __name__ == "__main__":
raise SystemExit(main())