mirror of
https://github.com/lief-project/LIEF.git
synced 2026-10-12 02:17:46 +00:00
159 lines
4.3 KiB
Python
159 lines
4.3 KiB
Python
import pathlib
|
|
|
|
import lief
|
|
|
|
|
|
def iterate(fat: lief.MachO.FatBinary) -> lief.MachO.Binary | None:
|
|
# lief-doc: iterate-start
|
|
fat: lief.MachO.FatBinary
|
|
|
|
# Iterate
|
|
for macho in fat:
|
|
print(macho.entrypoint)
|
|
print(len(macho.commands))
|
|
|
|
# Pick one at the specified index
|
|
macho = fat.at(0)
|
|
|
|
# Pick one based on the architecture
|
|
macho = fat.take(lief.MachO.Header.CPU_TYPE.ARM64)
|
|
# lief-doc: iterate-end
|
|
return macho
|
|
|
|
|
|
def write_bytes(macho: lief.MachO.Binary) -> bytes:
|
|
# lief-doc: write-bytes-start
|
|
macho: lief.MachO.Binary
|
|
|
|
new_macho: bytes = macho.write_to_bytes()
|
|
# lief-doc: write-bytes-end
|
|
return new_macho
|
|
|
|
|
|
def parse_from_dump() -> None:
|
|
# lief-doc: dump-start
|
|
# 0x11e32c000 is the (absolute) address at which the dump was mapped
|
|
fat = lief.MachO.parse_from_dump("module.dump", 0x11E32C000)
|
|
assert isinstance(fat, lief.MachO.FatBinary)
|
|
|
|
macho = fat.at(0)
|
|
assert isinstance(fat, lief.MachO.Binary)
|
|
|
|
for segment in macho.segments:
|
|
print(segment.name, hex(segment.virtual_address))
|
|
# lief-doc: dump-end
|
|
|
|
|
|
def module_dump() -> None:
|
|
# lief-doc: dump-runtime-start
|
|
# Find the module to dump in the current process
|
|
mod = lief.runtime.module_from_name("libsystem_c.dylib")
|
|
assert isinstance(mod, lief.runtime.osx.Module)
|
|
|
|
# Dump the module's memory into a file (the raw bytes are also returned) ...
|
|
data: bytes = mod.dump("module.dump")
|
|
|
|
# ... and parse it back using the same imagebase:
|
|
macho = lief.MachO.parse_from_dump(data, mod.imagebase)
|
|
# lief-doc: dump-runtime-end
|
|
assert isinstance(macho, lief.MachO.FatBinary)
|
|
|
|
|
|
def rpath_atrpath(macho: lief.MachO.Binary) -> None:
|
|
# lief-doc: rpath-atrpath-start
|
|
macho: lief.MachO.Binary
|
|
|
|
lib = macho.find_library("libmylib.dylib")
|
|
assert isinstance(lib, lief.MachO.DylibCommand)
|
|
|
|
lib.name = "@rpath/libmylib.dylib"
|
|
|
|
macho.write("hello_fixed.bin")
|
|
# lief-doc: rpath-atrpath-end
|
|
|
|
|
|
def parse_forms() -> lief.MachO.FatBinary | None:
|
|
# lief-doc: parse-start
|
|
|
|
# Using filepath
|
|
macho: lief.MachO.FatBinary | None = lief.MachO.parse("/bin/ls")
|
|
|
|
# Using a Path from pathlib
|
|
macho: lief.MachO.FatBinary | None = lief.MachO.parse(
|
|
pathlib.Path(r"C:\Users\test.macho")
|
|
)
|
|
|
|
# Using an io object
|
|
with open("/bin/ssh", "rb") as f:
|
|
macho: lief.MachO.FatBinary | None = lief.MachO.parse(f)
|
|
# lief-doc: parse-end
|
|
return macho
|
|
|
|
|
|
def write_fat(macho: lief.MachO.FatBinary) -> None:
|
|
# lief-doc: write-fat-start
|
|
macho: lief.MachO.FatBinary
|
|
|
|
macho.at(0).write("fit.macho")
|
|
macho.write("fat.macho") # write-back the whole FAT binary
|
|
# lief-doc: write-fat-end
|
|
|
|
|
|
def advanced_parse_write() -> None:
|
|
# lief-doc: advanced-start
|
|
parser_config = lief.MachO.ParserConfig()
|
|
parser_config.parse_dyld_bindings = False
|
|
|
|
fat = lief.MachO.parse("my.macho", parser_config)
|
|
assert isinstance(fat, lief.MachO.FatBinary)
|
|
|
|
macho = fat.at(0)
|
|
assert isinstance(fat, lief.MachO.Binary)
|
|
|
|
builder_config = lief.MachO.Builder.config_t()
|
|
builder_config.linkedit = False
|
|
|
|
macho.write("new.macho", builder_config)
|
|
# lief-doc: advanced-end
|
|
|
|
|
|
def rpath_change_lib() -> None:
|
|
# lief-doc: rpath-change-lib-start
|
|
fat = lief.MachO.parse("hello.bin")
|
|
assert isinstance(fat, lief.MachO.FatBinary)
|
|
|
|
macho = fat.at(0)
|
|
assert isinstance(fat, lief.MachO.Binary)
|
|
|
|
lib = macho.find_library("libmylib.dylib")
|
|
assert isinstance(lib, lief.MachO.DylibCommand)
|
|
|
|
lib.name = "/opt/homebrew/my_package/libmylib.dylib"
|
|
|
|
macho.write("hello_fixed.bin")
|
|
# lief-doc: rpath-change-lib-end
|
|
|
|
|
|
def rpath_add() -> None:
|
|
# lief-doc: rpath-add-start
|
|
fat = lief.MachO.parse("hello.bin")
|
|
assert isinstance(fat, lief.MachO.FatBinary)
|
|
|
|
macho = fat.at(0)
|
|
assert isinstance(fat, lief.MachO.Binary)
|
|
|
|
rpath = lief.MachO.RPathCommand.create("/opt/homebrew/my_package")
|
|
assert isinstance(rpath, lief.MachO.RPathCommand)
|
|
|
|
macho.add(rpath)
|
|
# lief-doc: rpath-add-end
|
|
|
|
|
|
def parse_config() -> None:
|
|
# lief-doc: parse-config-start
|
|
fatbinary_1 = lief.MachO.parse("/usr/bin/ls", config=lief.MachO.ParserConfig.deep)
|
|
# or
|
|
fatbinary_2 = lief.MachO.parse("/usr/bin/ls", config=lief.MachO.ParserConfig.quick)
|
|
# lief-doc: parse-config-end
|
|
_ = (fatbinary_1, fatbinary_2)
|