diff options
Diffstat (limited to 'example')
| -rw-r--r-- | example/unpack_gen.py | 169 | ||||
| -rw-r--r-- | example/unpack_upx.py | 190 |
2 files changed, 74 insertions, 285 deletions
diff --git a/example/unpack_gen.py b/example/unpack_gen.py index c60063dc..ffca512e 100644 --- a/example/unpack_gen.py +++ b/example/unpack_gen.py @@ -1,168 +1,21 @@ -import sys, os -from optparse import OptionParser -from miasm2.analysis.machine import Machine -from miasm2.jitter.jitload import vm_load_pe, preload_pe, libimp -from miasm2.jitter.jitload import bin_stream_vm -from miasm2.jitter.os_dep import win_api_x86_32, win_api_x86_32_seh -from miasm2.analysis import debugging - -# Debug settings -import inspect +import os from pdb import pm +from miasm2.analysis.sandbox import Sandbox_Win_x86_32 -# Environment settings +# Python auto completion filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): execfile(filename) -parser = OptionParser(usage = "usage: %prog [options] file") -parser.add_option('-a', "--address", dest="address", metavar="ADDRESS", - help="Force entry point address", default=None) -parser.add_option('-s', "--segm", dest="usesegm", action="store_true", - help="Use segments fs:", default=False) -parser.add_option('-o', "--hdr", dest="loadhdr", action="store_true", - help="Load pe hdr", default=False) -parser.add_option('-l', "--loadbasedll", dest="loadbasedll", - action="store_true", help="Load base dll (path './win_dll')", - default=False) -parser.add_option('-x', "--dumpall", dest="dumpall", action="store_true", - help="Load base dll", default=False) -parser.add_option('-e', "--loadmainpe", dest="loadmainpe", action="store_true", - help="Load main pe", default=False) -parser.add_option('-r', "--parseresources", dest="parse_resources", - action="store_true", help="Load resources", default=False) -parser.add_option('-b', "--dumpblocs", dest="dumpblocs", action="store_true", - help="Log disasm blocks", default=False) -parser.add_option('-y', "--useseh", dest="use_seh", action="store_true", - help="Use windows SEH", default=False) -parser.add_option('-z', "--singlestep", dest="singlestep", action="store_true", - help="Log single step", default=False) -parser.add_option('-d', "--debugging", dest="debugging", action="store_true", - help="Debug shell", default=False) -parser.add_option('-g', "--gdbserver", dest="gdbserver", - help="Listen on port @port", default=False) -parser.add_option("-j", "--jitter", dest="jitter", - help="Jitter engine. Possible values are : tcc (default),\ -llvm, python", - default="tcc") - -(options, args) = parser.parse_args(sys.argv[1:]) -if not args: - parser.print_help() - sys.exit(0) - -#### INSERT HERE CUSTOM DLL METHODS ### -####################################### - -fname = args[0] -machine = Machine("x86_32") - -myjit = machine.jitter(options.jitter) -if options.usesegm: - myjit.ir_arch.do_stk_segm= True - myjit.ir_arch.do_ds_segm= True - myjit.ir_arch.do_str_segm = True - myjit.ir_arch.do_all_segm = True - -bs = bin_stream_vm(myjit.vm) -myjit.jit.bs = bs - -# Init stack -myjit.stack_size = 0x100000 -myjit.init_stack() - -# Import manager -libs = libimp() - -# Set libs for win_32 api -win_api_x86_32.winobjs.runtime_dll = libs - -all_imp_dll = [] -if options.loadbasedll: - - # Load library - all_imp_dll = ["ntdll.dll", "kernel32.dll", "user32.dll", - "ole32.dll", "urlmon.dll", - "ws2_32.dll", 'advapi32.dll', "psapi.dll" - ] - mod_list = all_imp_dll - all_pe = [] - # Load libs in memory - for n in mod_list: - fname_dll = os.path.join('win_dll', n) - e_lib = vm_load_pe(myjit.vm, fname_dll) - - libs.add_export_lib(e_lib, n) - all_pe.append(e_lib) - - # Patch libs imports - for ee in all_pe: - preload_pe(myjit.vm, ee, libs) +# Insert here user defined methods +# Parse arguments +parser = Sandbox_Win_x86_32.parser() +parser.add_argument("filename", help="PE Filename") +options = parser.parse_args() -# Load main pe -e = vm_load_pe(myjit.vm, fname) - -# Fix mainpe imports -preload_pe(myjit.vm, e, libs) - -# Library calls handler -myjit.add_lib_handler(libs, globals()) - -# Manage SEH -if options.use_seh: - win_api_x86_32_seh.main_pe_name = fname - win_api_x86_32_seh.main_pe = e - win_api_x86_32_seh.loaded_modules = all_imp_dll - win_api_x86_32_seh.init_seh(myjit) - win_api_x86_32_seh.set_win_fs_0(myjit) - -# Get entry point address -if options.address is not None: - addr = int(options.address, 16) -else: - addr = e.rva2virt(e.Opthdr.AddressOfEntryPoint) - -# Logging options -if options.singlestep: - myjit.jit.log_mn = True - myjit.jit.log_regs = True - -if options.dumpblocs: - myjit.jit.log_newbloc = True - -# Pre-stack some arguments -myjit.vm_push_uint32_t(2) -myjit.vm_push_uint32_t(1) -myjit.vm_push_uint32_t(0) -myjit.vm_push_uint32_t(0x1337beef) - -# Set the runtime guard -def code_sentinelle(myjit): - print 'emulation stop' - myjit.run = False - return False - -myjit.add_breakpoint(0x1337beef, code_sentinelle) - -#### INSERT HERE CUSTOM BREAKPOINTS ### -####################################### +# Create sandbox +sb = Sandbox_Win_x86_32(options.filename, options, globals()) # Run -if any([options.debugging, options.gdbserver]): - dbg = debugging.Debugguer(myjit) - dbg.init_run(addr) - - if options.gdbserver is not False: - port = int(options.gdbserver) - print "Listen on port %d" % port - gdb = machine.gdbserver(dbg, port) - gdb.run() - else: - cmd = debugging.DebugCmd(dbg) - cmd.cmdloop() - -else: - print "Start emulation", hex(addr) - myjit.init_run(addr) - print myjit.continue_run() +sb.run() diff --git a/example/unpack_upx.py b/example/unpack_upx.py index 6805c82d..c185b01b 100644 --- a/example/unpack_upx.py +++ b/example/unpack_upx.py @@ -1,80 +1,60 @@ -import sys +from pdb import pm import os -import inspect +from miasm2.analysis.sandbox import Sandbox_Win_x86_32 import logging -import struct -from argparse import ArgumentParser - -from elfesteem import pe -from elfesteem import * -from elfesteem.strpatchwork import StrPatchwork - from miasm2.core import asmbloc -from miasm2.jitter.jitload import vm_load_pe, preload_pe, libimp -from miasm2.jitter.jitload import bin_stream_vm -from miasm2.jitter.csts import * -from miasm2.jitter.os_dep import win_api_x86_32 - -from miasm2.analysis.machine import Machine -# Debug settings # -from pdb import pm +from elfesteem.strpatchwork import StrPatchwork +from elfesteem import pe filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): execfile(filename) -# -# Handle arguments -parser = ArgumentParser(description="Sandbox a PE binary packed with UPX") -parser.add_argument("filename", help="PE binary") -parser.add_argument("-r", "--log-regs", - help="Log registers value for each instruction", - action="store_true") -parser.add_argument("-m", "--log-mn", - help="Log desassembly conversion for each instruction", - action="store_true") -parser.add_argument("-n", "--log-newbloc", - help="Log basic blocks processed by the Jitter", - action="store_true") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -parser.add_argument("-g", "--graph", +# User defined methods + +def kernel32_GetProcAddress(myjit): + ret_ad, args = myjit.func_args_stdcall(2) + libbase, fname = args + + dst_ad = myjit.cpu.EBX + logging.info('EBX ' + hex(dst_ad)) + + if fname < 0x10000: + fname = fname + else: + fname = myjit.get_str_ansi(fname) + logging.info(fname) + + ad = sb.libs.lib_get_add_func(libbase, fname, dst_ad) + myjit.func_ret_stdcall(ret_ad, ad) + + + +parser = Sandbox_Win_x86_32.parser() +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") -parser.add_argument("-v", "--verbose", - help="Verbose mode", - action="store_true") -args = parser.parse_args() +options = parser.parse_args() +sb = Sandbox_Win_x86_32(options.filename, options, globals()) + -# Verbose mode -if args.verbose is True: +if options.verbose is True: logging.basicConfig(level=logging.INFO) else: logging.basicConfig(level=logging.WARNING) -# Init arch -machine = Machine("x86_32") -myjit = machine.jitter(args.jitter) -myjit.init_stack() +if options.verbose is True: + sb.jitter.vm.vm_dump_memory_page_pool() -# Log level (if available with jitter engine) -myjit.jit.log_regs = args.log_regs -myjit.jit.log_mn = args.log_mn -myjit.jit.log_newbloc = args.log_newbloc -# Load pe and get entry point address -e = vm_load_pe(myjit.vm, args.filename) -libs = libimp() -preload_pe(myjit.vm, e, libs) - -if args.verbose is True: - myjit.vm.vm_dump_memory_page_pool() -ep = e.rva2virt(e.Opthdr.AddressOfEntryPoint) +ep = sb.entry_point # Ensure there is one and only one leave (for OEP discovering) -mdis = machine.dis_engine(myjit.bs) +mdis = sb.machine.dis_engine(sb.jitter.bs) mdis.dont_dis_nulstart_bloc = True ab = mdis.dis_multibloc(ep) @@ -89,95 +69,51 @@ logging.info('final label') logging.info(end_label) # Export CFG graph (dot format) -if args.graph is True: +if options.graph is True: g = asmbloc.bloc2graph(ab) open("graph.txt", "w").write(g) -# User defined methods - -def kernel32_GetProcAddress(myjit): - global libs - ret_ad, args = myjit.func_args_stdcall(2) - libbase, fname = args - - dst_ad = myjit.cpu.EBX - logging.info('EBX ' + hex(dst_ad)) - - if fname < 0x10000: - fname = fname - else: - fname = myjit.get_str_ansi(fname) - logging.info(fname) - - ad = libs.lib_get_add_func(libbase, fname, dst_ad) - myjit.func_ret_stdcall(ret_ad, ad) - -# Set libs for win_32 api -win_api_x86_32.winobjs.runtime_dll = libs -if args.verbose is True: - myjit.vm.vm_dump_memory_page_pool() - -# Set up stack -myjit.vm_push_uint32_t(1) # reason code if dll -myjit.vm_push_uint32_t(1) # reason code if dll -myjit.vm_push_uint32_t(0x1337beef) - -# Breakpoint callbacks +if options.verbose is True: + sb.jitter.vm.vm_dump_memory_page_pool() def update_binary(myjit): - e.Opthdr.AddressOfEntryPoint = e.virt2rva(myjit.pc) + sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(myjit.pc) logging.info('updating binary') - for s in e.SHList: - sdata = myjit.vm.vm_get_mem(e.rva2virt(s.addr), s.rawsize) - e.virt[e.rva2virt(s.addr)] = sdata + for s in sb.pe.SHList: + sdata = sb.jitter.vm.vm_get_mem(sb.pe.rva2virt(s.addr), s.rawsize) + sb.pe.virt[sb.pe.rva2virt(s.addr)] = sdata # Set callbacks -myjit.add_breakpoint(end_label, update_binary) -myjit.add_lib_handler(libs, globals()) - -# Run until breakpoint is reached -myjit.init_run(ep) -myjit.continue_run() - +sb.jitter.add_breakpoint(end_label, update_binary) -regs = myjit.cpu.vm_get_gpreg() +sb.run() +regs = sb.jitter.cpu.vm_get_gpreg() new_dll = [] - - # XXXXX -e.SHList.align_sections(0x1000, 0x1000) -logging.info(repr(e.SHList)) -st = StrPatchwork() -st[0] = e.content - -# get back data from emulator -for s in e.SHList: - ad1 = e.rva2virt(s.addr) - ad2 = ad1 + len(s.data) - st[s.offset] = e.virt(ad1, ad2) -# e.content = str(st) - -e.DirRes = pe.DirRes(e) -e.DirImport.impdesc = None -logging.info(repr(e.DirImport.impdesc)) -new_dll = libs.gen_new_lib(e) +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) -e.DirImport.impdesc = [] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -logging.info(repr(e.SHList)) -e.DirImport.set_rva(s_myimp.addr) +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 -e.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 +sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 -e.Opthdr.AddressOfEntryPoint = e.virt2rva(end_label) -bname, fname = os.path.split(args.filename) +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(e)) +open(fname + '_unupx.bin', 'w').write(str(sb.pe)) |