about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/jitter/run_with_linuxenv.py85
-rwxr-xr-xtest/test_all.py13
2 files changed, 98 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()
diff --git a/test/test_all.py b/test/test_all.py
index 3fb0a5b7..9bf54608 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python2
 
 import argparse
+from distutils.spawn import find_executable
 import time
 import os
 import tempfile
@@ -686,6 +687,18 @@ for jitter in ExampleJitter.jitter_engines:
                              ["--jitter", jitter],
                              products=[Example.get_sample("box_upx_exe_unupx.bin")],
                              tags=tags.get(jitter, []))
+    if jitter != "python":
+        tags = tags.get(jitter, []) + [TAGS["long"]]
+        ls_path = find_executable("ls")
+        file_path = find_executable("file")
+        # Launch simulation of "file /bin/ls", with access to libs and ld info
+        testset += ExampleJitter(["run_with_linuxenv.py", "-v", "-p",
+                                  '/(.*lib.*\.so(\.\d+)?)|(/etc/ld.so.*)|(.*magic.*)|(%s)' % ls_path,
+                                  ] + ["--jitter", jitter] + [
+                                      file_path, ls_path,
+                                  ],
+                                 tags=tags)
+
 
 for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []),
                     (["arm.py", Example.get_sample("md5_arm"), "--mimic-env"],