about summary refs log tree commit diff stats
path: root/example/jitter/unpack_upx.py
diff options
context:
space:
mode:
authorCamille Mougey <camille.mougey@cea.fr>2015-01-18 18:24:13 +0100
committerCamille Mougey <camille.mougey@cea.fr>2015-01-23 17:24:43 +0100
commit488cb99d4d61a0b3b176f7e3c53431872fc234ef (patch)
tree8d443acb6c92669cdeaa50a40af3496917a9448f /example/jitter/unpack_upx.py
parent829f8b98a658532b40382640223c0c3ea12ab15c (diff)
downloadfocaccia-miasm-488cb99d4d61a0b3b176f7e3c53431872fc234ef.tar.gz
focaccia-miasm-488cb99d4d61a0b3b176f7e3c53431872fc234ef.zip
Example: Move jitter's examples to a `jitter` directory
Diffstat (limited to 'example/jitter/unpack_upx.py')
-rw-r--r--example/jitter/unpack_upx.py117
1 files changed, 117 insertions, 0 deletions
diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py
new file mode 100644
index 00000000..313f75a2
--- /dev/null
+++ b/example/jitter/unpack_upx.py
@@ -0,0 +1,117 @@
+import os
+import logging
+from pdb import pm
+from elfesteem import pe
+from miasm2.analysis.sandbox import Sandbox_Win_x86_32
+from miasm2.core import asmbloc
+
+filename = os.environ.get('PYTHONSTARTUP')
+if filename and os.path.isfile(filename):
+    execfile(filename)
+
+
+# User defined methods
+
+def kernel32_GetProcAddress(jitter):
+    ret_ad, args = jitter.func_args_stdcall(2)
+    libbase, fname = args
+
+    dst_ad = jitter.cpu.EBX
+    logging.info('EBX ' + hex(dst_ad))
+
+    if fname < 0x10000:
+        fname = fname
+    else:
+        fname = jitter.get_str_ansi(fname)
+    logging.info(fname)
+
+    ad = sb.libs.lib_get_add_func(libbase, fname, dst_ad)
+    jitter.func_ret_stdcall(ret_ad, ad)
+
+
+
+parser = Sandbox_Win_x86_32.parser(description="Generic UPX unpacker")
+parser.add_argument("filename", help="PE Filename")
+parser.add_argument('-v', "--verbose",
+                    help="verbose mode", action="store_true")
+parser.add_argument("--graph",
+                    help="Export the CFG graph in graph.txt",
+                    action="store_true")
+options = parser.parse_args()
+sb = Sandbox_Win_x86_32(options.filename, options, globals())
+
+
+if options.verbose is True:
+    logging.basicConfig(level=logging.INFO)
+else:
+    logging.basicConfig(level=logging.WARNING)
+
+if options.verbose is True:
+    sb.jitter.vm.dump_memory_page_pool()
+
+
+ep = sb.entry_point
+
+# Ensure there is one and only one leave (for OEP discovering)
+mdis = sb.machine.dis_engine(sb.jitter.bs)
+mdis.dont_dis_nulstart_bloc = True
+ab = mdis.dis_multibloc(ep)
+
+bb = asmbloc.basicblocs(ab)
+leaves = bb.get_bad_dst()
+assert(len(leaves) == 1)
+l = leaves.pop()
+logging.info(l)
+end_label = l.label.offset
+
+logging.info('final label')
+logging.info(end_label)
+
+# Export CFG graph (dot format)
+if options.graph is True:
+    g = asmbloc.bloc2graph(ab)
+    open("graph.txt", "w").write(g)
+
+
+if options.verbose is True:
+    sb.jitter.vm.dump_memory_page_pool()
+
+
+def update_binary(jitter):
+    sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(jitter.pc)
+    logging.info('updating binary')
+    for s in sb.pe.SHList:
+        sdata = sb.jitter.vm.get_mem(sb.pe.rva2virt(s.addr), s.rawsize)
+        sb.pe.virt[sb.pe.rva2virt(s.addr)] = sdata
+
+
+# Set callbacks
+sb.jitter.add_breakpoint(end_label, update_binary)
+
+# Run
+sb.run()
+
+# Rebuild PE
+new_dll = []
+
+sb.pe.SHList.align_sections(0x1000, 0x1000)
+logging.info(repr(sb.pe.SHList))
+
+sb.pe.DirRes = pe.DirRes(sb.pe)
+sb.pe.DirImport.impdesc = None
+logging.info(repr(sb.pe.DirImport.impdesc))
+new_dll = sb.libs.gen_new_lib(sb.pe)
+logging.info(new_dll)
+sb.pe.DirImport.impdesc = []
+sb.pe.DirImport.add_dlldesc(new_dll)
+s_myimp = sb.pe.SHList.add_section(name="myimp", rawsize=len(sb.pe.DirImport))
+logging.info(repr(sb.pe.SHList))
+sb.pe.DirImport.set_rva(s_myimp.addr)
+
+# XXXX TODO
+sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0
+
+sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(end_label)
+bname, fname = os.path.split(options.filename)
+fname = os.path.join(bname, fname.replace('.', '_'))
+open(fname + '_unupx.bin', 'w').write(str(sb.pe))