about summary refs log tree commit diff stats
path: root/example/jitter/run_with_linuxenv.py
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-07-17 12:12:25 +0200
committerAjax <commial@gmail.com>2018-07-24 13:46:38 +0200
commitab0cf7308e9fb0c5ddeb2e49da75193cd7d50304 (patch)
tree3bb319291b2bd1dc1deeec4bbb76878739a508bc /example/jitter/run_with_linuxenv.py
parentbcd764692b084ebd61868a2561d710dbb0d4ffb9 (diff)
downloadmiasm-ab0cf7308e9fb0c5ddeb2e49da75193cd7d50304.tar.gz
miasm-ab0cf7308e9fb0c5ddeb2e49da75193cd7d50304.zip
Add an example for LinuxEnvironment & Syscall handling
Diffstat (limited to 'example/jitter/run_with_linuxenv.py')
-rw-r--r--example/jitter/run_with_linuxenv.py85
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()