Files
2026-04-25 09:44:02 +02:00

54 lines
1.5 KiB
Python

#!/usr/bin/env python
"""Promote a PIE executable to a shared library by exporting a function.
Takes a PIE ELF executable, declares an exported function at the
given address, and rewrites the binary so that it can be ``dlopen``-ed
and the function invoked via ``dlsym``.
Example:
$ python elf_bin2lib.py -n compute -o libcompute.so ./prog 0x1200
"""
import argparse
import sys
import lief
def bin2lib(binary: lief.ELF.Binary, address: int, output: str, name: str = "") -> int:
if not binary.is_pie:
print("It only works with PIE binaries", file=sys.stderr)
return 1
function = binary.add_exported_function(address, name)
print("Function created:", function)
binary.write(output)
return 0
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument(
"--name", "-n", default="", help="Name of the function to create"
)
parser.add_argument(
"--output", "-o", default="libfoo.so", help="Output name (default: %(default)s)"
)
parser.add_argument("binary", help="The target ELF binary")
parser.add_argument(
"address", type=lambda e: int(e, 0), help="Address of the function to export"
)
args = parser.parse_args()
binary = lief.ELF.parse(args.binary)
if binary is None:
print(f"Error: failed to parse '{args.binary}' as ELF", file=sys.stderr)
return 1
return bin2lib(binary, args.address, args.output, name=args.name)
if __name__ == "__main__":
sys.exit(main())