Files
lief-project-LIEF/api/python/examples/objc_dump.py
T
2026-04-11 12:41:55 +02:00

68 lines
1.8 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())