diff options
| author | Camille Mougey <camille.mougey@cea.fr> | 2015-01-18 18:24:13 +0100 |
|---|---|---|
| committer | Camille Mougey <camille.mougey@cea.fr> | 2015-01-23 17:24:43 +0100 |
| commit | 488cb99d4d61a0b3b176f7e3c53431872fc234ef (patch) | |
| tree | 8d443acb6c92669cdeaa50a40af3496917a9448f /example/jitter/unpack_upx.py | |
| parent | 829f8b98a658532b40382640223c0c3ea12ab15c (diff) | |
| download | focaccia-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.py | 117 |
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)) |