diff options
Diffstat (limited to 'example')
| -rw-r--r-- | example/jitter/run_with_linuxenv.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/example/jitter/run_with_linuxenv.py b/example/jitter/run_with_linuxenv.py new file mode 100644 index 00000000..933459f4 --- /dev/null +++ b/example/jitter/run_with_linuxenv.py @@ -0,0 +1,85 @@ +from argparse import ArgumentParser +import logging +import os +import re + +from elfesteem import elf as elf_csts + +from miasm2.os_dep.linux import environment, syscall +from miasm2.analysis.machine import Machine +from miasm2.analysis.binary import Container + +parser = ArgumentParser("Run an ELF in a Linux-like environment") +parser.add_argument("target", help="Target ELF") +parser.add_argument("extra_args", help="Arguments for the target ELF", + nargs="*", default=[]) +parser.add_argument("-j", "--jitter", help="Jitter engine", default="llvm") +parser.add_argument("-p", "--passthrough", help="Reg-exp for passthrough files", + default="^$") +parser.add_argument("-f", "--flags", help="Flags") +parser.add_argument("-v", "--verbose", action="store_true", + help="Activate verbose syscalls") +args = parser.parse_args() + +if args.verbose: + syscall.log.setLevel(logging.DEBUG) + +# Get corresponding interpreter and reloc address +cont_target_tmp = Container.from_stream(open(args.target)) +ld_path = str(cont_target_tmp.executable.getsectionbyname(".interp").content).strip("\x00") +if cont_target_tmp.executable.Ehdr.type in [elf_csts.ET_REL, elf_csts.ET_DYN]: + elf_base_addr = 0x40000000 +elif cont_target_tmp.executable.Ehdr.type == elf_csts.ET_EXEC: + elf_base_addr = 0 # Not relocatable +else: + raise ValueError("Unsuported type %d" % cont_target_tmp.executable.Ehdr.type) + +# Instanciate a jitter +machine = Machine(cont_target_tmp.arch) +jitter = machine.jitter(args.jitter) +jitter.init_stack() + +# Get elements for the target architecture +if cont_target_tmp.arch == "arml": + LinuxEnvironment = environment.LinuxEnvironment_arml + syscall_callbacks = syscall.syscall_callbacks_arml + prepare_loader = environment.prepare_loader_arml +elif cont_target_tmp.arch == "x86_64": + LinuxEnvironment = environment.LinuxEnvironment_x86_64 + syscall_callbacks = syscall.syscall_callbacks_x86_64 + prepare_loader = environment.prepare_loader_x86_64 +else: + raise ValueError("Unsupported architecture: %r", cont_target_tmp.arch) + +# Load the interpreter in memory, applying relocation +linux_env = LinuxEnvironment() +linux_env.filesystem.passthrough.append(re.compile(args.passthrough)) +ld_path = linux_env.filesystem.resolve_path(ld_path) +cont_ld = Container.from_stream(open(ld_path), + vm=jitter.vm, + addr=0x80000000, + apply_reloc=True) +# Load the target ELF in memory, without applying reloc +loc_db = cont_ld.loc_db +cont_target = Container.from_stream(open(args.target), vm=jitter.vm, + loc_db=loc_db, + addr=elf_base_addr, + apply_reloc=False) +# PHDR containing the PH header +elf_phdr_header = [ph32.ph for ph32 in cont_target.executable.ph + if ph32.ph.type == elf_csts.PT_PHDR][0] + +# Prepare the desired environment +argv = [args.target] + args.extra_args +if args.flags: + argv += ["-%s" % args.flags] +envp = {"PATH": "/usr/local/bin", "USER": linux_env.user_name} +auxv = environment.AuxVec(elf_base_addr + elf_phdr_header.vaddr, + cont_target.entry_point, linux_env) +prepare_loader(jitter, argv, envp, auxv, linux_env) +syscall.enable_syscall_handling(jitter, linux_env, syscall_callbacks) + + +# Run +jitter.init_run(cont_ld.entry_point) +jitter.continue_run() |