def hookiat(db, line): ''' Hook the specified IAT entries by munging a pointer and emulating "breakpoint" like behavior on the resultant memory access errors. Basically, break on import call... Usage: hookiat <libname> [ <implibname> [ <impfuncname> ] ] Example: hookiat calc hookiat calc kernel32 hookiat calc kernel32 LoadLibraryA NOTE: Once added, you may use "bp" and commands like "bpedit" to modify, remove, or add code to "iat hooks" ''' argv = e_cli.splitargs(line) arglen = len(argv) if arglen < 1: return db.do_help('hookiat') if arglen > 3: return db.do_help('hookiat') db.vprint('Adding IAT Hooks (use bp/bpedit cmds to review/modify...)') hooks = vt_iathook.hookIat(db.trace, *argv) if len(hooks): db.vprint('[ bpid ] [ IAT Name ]') for iatname, bpid in hooks: db.vprint('[%6d] %s' % (bpid, iatname)) db.vprint('Added %d hooks.' % len(hooks))
def heaps(vdb, line): """ Show Win32 Heap Information. Usage: heaps [-F <heapaddr>] [-C <address>] [-L <segmentaddr>] -F <heapaddr> print the freelist for the heap -C <address> Find and print the heap chunk containing <address> -S <segmentaddr> Print the chunks for the given heap segment -L <heapaddr> Print the look aside list for the given heap -V Validate the heaps (check next/prev sizes and free list) -l <heapaddr> Leak detection (list probable leaked chunks) -U <heapaddr> Show un-commited ranges for the specified heap (no options lists heaps and segments) """ t = vdb.getTrace() t.requireAttached() if t.getMeta('Architecture') == 'amd64': vdb.vprint("WARNING: not all 64bit heap stuff works quite right yet!") argv = e_cli.splitargs(line) freelist_heap = None chunkfind_addr = None chunklist_seg = None lookaside_heap = None leakfind_heap = None uncommit_heap = None try: opts, args = getopt.getopt(argv, "F:C:S:L:l:U:V") except Exception, e: return vdb.do_help('heaps')
def do_var(self, line): """ Set a variable in the expression parsing context. This allows for scratchspace names (python compatable names) to be used in expressions. Usage: var <name> <addr_expression> NOTE: The address expression *must* resolve at the time you set it. """ t = self.trace if len(line): argv = e_cli.splitargs(line) if len(argv) == 1: return self.do_help("var") name = argv[0] expr = " ".join(argv[1:]) addr = t.parseExpression(expr) t.setVariable(name, addr) vars = t.getVariables() self.vprint("Current Variables:") if not vars: self.vprint("None.") else: vnames = vars.keys() vnames.sort() for n in vnames: val = vars.get(n) self.vprint("%20s = 0x%.8x" % (n,val))
def eproc(db, line): ''' Display the details for the eprocesses. Usage: eproc [addrexpr] ''' argv = e_cli.splitargs(line) parser = optparse.OptionParser('eproc') parser.add_option('--name',dest='doname',default=None) parser.add_option('--threads',dest='dothreads',default=False,action='store_true') parser.add_option('--handles',dest='dohandles',default=False,action='store_true') parser.add_option('--objects',dest='doobjects',default=False,action='store_true') opts,argv = parser.parse_args(argv) t = db.getTrace() if argv: for expr in argv: eprocva = t.parseExpression(expr) eproc = t.getStruct('nt.EPROCESS',eprocva) showeproc(db,t,opts,eprocva,eproc) return dbgdata64 = db.getRunCacheVar('KDDEBUGGER_DATA64') phead = dbgdata64.PsActiveProcessHead for eprocva,eproc in walkEprocesses(db,t): if opts.doname: pname = ''.join([ chr(c[1]) for c in eproc.ImageFileName ]).strip('\x00').lower() if opts.doname.lower() != pname: continue showeproc(db,t,opts,eprocva,eproc)
def gflags(vdb, line): ''' Support a subset of gflags like behavior on windows. This enables features *exclusively* by direct process manipulation and does NOT set any registry settings or persist across processes... Usage: gflags [toggle_type] NOTE: Most of these options require symbols! ''' argv = e_cli.splitargs(line) optnames = [x[0] for x in gflag_stuff] for opt in argv: if opt not in optnames: vdb.vprint('Unknown/Unsupported Option: %s' % opt) continue for hname, symname, fmt, offval, onval in gflag_stuff: if opt == hname: try: addr = vdb.trace.parseExpression(symname) cur = vdb.trace.readMemoryFormat(addr, fmt)[0] if cur == offval: newval = onval else: newval = offval vdb.trace.writeMemoryFormat(addr, fmt, newval) except Exception, e: vdb.vprint('Symbol Failure: %s' % symname) break
def heaps(vdb, line): """ Show Win32 Heap Information. Usage: heaps [-F <heapaddr>] [-C <address>] [-L <segmentaddr>] -F <heapaddr> print the freelist for the heap -C <address> Find and print the heap chunk containing <address> -S <segmentaddr> Print the chunks for the given heap segment -L <heapaddr> Print the look aside list for the given heap -V Validate the heaps (check next/prev sizes and free list) -l <heapaddr> Leak detection (list probable leaked chunks) (no options lists heaps and segments) """ t = vdb.getTrace() t.requireAttached() argv = e_cli.splitargs(line) freelist_heap = None chunkfind_addr = None chunklist_seg = None lookaside_heap = None leakfind_heap = None try: opts,args = getopt.getopt(argv, "F:C:S:L:l:V") except Exception, e: return vdb.do_help('heaps')
def do_filemeta(self, line): ''' Show/List file metadata. Usage: filemeta [ fname [ keyname ] ] Example: filemeta kernel32 Example: filemeta kernel32 md5 ''' argv = e_cli.splitargs(line) if len(argv) == 0: self.vprint('Loaded Files:') for fname in self.getFiles(): self.vprint(' %s' % fname) elif len(argv) == 1: d = self.getFileMetaDict(argv[0]) self.vprint(pprint.pformat(d)) elif len(argv) == 2: val = self.getFileMeta(argv[0], argv[1]) self.vprint('%s (%s):' % (argv[1], argv[0])) self.vprint(pprint.pformat(val)) else: self.do_help('filemeta')
def gflags(vdb, line): ''' Support a subset of gflags like behavior on windows. This enables features *exclusively* by direct process manipulation and does NOT set any registry settings or persist across processes... Usage: gflags [toggle_type] NOTE: Most of these options require symbols! ''' argv = e_cli.splitargs(line) optnames = [ x[0] for x in gflag_stuff ] for opt in argv: if opt not in optnames: vdb.vprint('Unknown/Unsupported Option: %s' % opt) continue for hname, symname, fmt, offval, onval in gflag_stuff: if opt == hname: try: addr = vdb.trace.parseExpression(symname) cur = vdb.trace.readMemoryFormat(addr, fmt)[0] if cur == offval: newval = onval else: newval = offval vdb.trace.writeMemoryFormat(addr, fmt, newval) except Exception, e: vdb.vprint('Symbol Failure: %s' % symname) break
def heaps(vdb, line): """ Show Win32 Heap Information. Usage: heaps [-F <heapaddr>] [-C <address>] [-L <segmentaddr>] -F <heapaddr> print the freelist for the heap -C <address> Find and print the heap chunk containing <address> -S <segmentaddr> Print the chunks for the given heap segment -L <heapaddr> Print the look aside list for the given heap -V Validate the heaps (check next/prev sizes and free list) -l <heapaddr> Leak detection (list probable leaked chunks) -U <heapaddr> Show un-commited ranges for the specified heap (no options lists heaps and segments) """ t = vdb.getTrace() t.requireAttached() if t.getMeta('Architecture') == 'amd64': vdb.vprint("WARNING: not all 64bit heap stuff works quite right yet!") argv = e_cli.splitargs(line) freelist_heap = None chunkfind_addr = None chunklist_seg = None lookaside_heap = None leakfind_heap = None uncommit_heap = None try: opts,args = getopt.getopt(argv, "F:C:S:L:l:U:V") except Exception, e: return vdb.do_help('heaps')
def pe(vdb, line): """ Show extended info about loaded PE binaries. Usage: pe [opts] [<libname>...] -I Show PE import files. -m Toggle inmem/ondisk behavior (directly mapped DLLs) -N Show full NT header -t Show PE timestamp information -E Show PE exports -S Show PE sections -v Show FileVersion from VS_VERSIONINFO -V Show all keys from VS_VERSIONINFO NOTE: "libname" may be a vtrace expression: Examples: # Show the imports from a PE loaded at 0x777c0000 pe -I 0x777c0000 # Show the exports from advapi32.dll pe -E advapi32 # Show the build timestamp of the PE pointed to by a register pe -t esi """ #-v Show PE version information argv = e_cli.splitargs(line) try: opts,args = getopt.getopt(argv, "EImNStvV") except Exception, e: return vdb.do_help('pe')
def armthumbdis(db, line, disasmobj): ''' Core of disassmbly, for code-reuse. Only difference is the object actually doing the disassembly. ''' t = db.getTrace() argv = e_cli.splitargs(line) size = 20 argc = len(argv) if argc == 0: addr = t.getProgramCounter() else: addr = t.parseExpression(argv[0]) if argc > 1: size = t.parseExpression(argv[1]) bytez = t.readMemory(addr, size) offset = 0 db.vprint("Dissassembly:") while offset < size: va = addr + offset op = disasmobj.disasm(bytez, offset, va) obytez = bytez[offset:offset + len(op)] db.canvas.addVaText('0x%.8x' % va, va=va) db.canvas.addText(": %s " % e_common.hexify(obytez).ljust(17)) op.render(db.canvas) db.canvas.addText("\n") offset += len(op)
def pe(vdb, line): """ Show extended info about loaded PE binaries. Usage: pe [opts] [<libname>...] -I Show PE import files. -m Toggle inmem/ondisk behavior (directly mapped DLLs) -N Show full NT header -t Show PE timestamp information -E Show PE exports -S Show PE sections -v Show FileVersion from VS_VERSIONINFO -V Show all keys from VS_VERSIONINFO NOTE: "libname" may be a vtrace expression: Examples: # Show the imports from a PE loaded at 0x777c0000 pe -I 0x777c0000 # Show the exports from advapi32.dll pe -E advapi32 # Show the build timestamp of the PE pointed to by a register pe -t esi """ #-v Show PE version information argv = e_cli.splitargs(line) try: opts, args = getopt.getopt(argv, "EImNStvV") except Exception, e: return vdb.do_help('pe')
def heaps(vdb, line): """ Show Win32 Heap Information. Usage: heaps [-F <heapaddr>] [-C <address>] [-L <segmentaddr>] -F <heapaddr> print the freelist for the heap -C <address> Find and print the heap chunk containing <address> -S <segmentaddr> Print the chunks for the given heap segment -L <heapaddr> Print the look aside list for the given heap -V Validate the heaps (check next/prev sizes and free list) -l <heapaddr> Leak detection (list probable leaked chunks) (no options lists heaps and segments) """ t = vdb.getTrace() t.requireAttached() argv = e_cli.splitargs(line) freelist_heap = None chunkfind_addr = None chunklist_seg = None lookaside_heap = None leakfind_heap = None try: opts, args = getopt.getopt(argv, "F:C:S:L:l:V") except Exception, e: return vdb.do_help('heaps')
def adb(db, line): ''' Pass a command directly to the adb bridge command. (mostly just so you don't need another prompt) Usage adb <adb args> ''' argv = e_cli.splitargs(line) db.vprint(vt_android.adbCommand('adb', *argv))
def adb(db, line): ''' Pass a command directly to the adb bridge command. (mostly just so you don't need another prompt) Usage adb <adb args> ''' argv = e_cli.splitargs(line) db.vprint( vt_android.adbCommand('adb', *argv) )
def do_eignore(self, line): """ Print out the opcodes for a given address expression Usage: dis <address expression> [<size expression>] """ argv = e_cli.splitargs(line) print argv
def platformExec(self, cmdline): self.execing = True cmdlist = e_cli.splitargs(cmdline) os.stat(cmdlist[0]) pid = os.fork() if pid == 0: ptrace(PT_TRACE_ME, 0, 0, 0) os.execv(cmdlist[0], cmdlist) sys.exit(-1) return pid
def _do_argtrack(self, line): #FIXME: this is currently broken and needs to be revamped to use # apiCall and VivTaints """ Track input arguments to the given function by name or address. (this is currently broken. sorry!) Usage: argtrack <func_addr_expr> <arg_idx> """ if not line: return self.do_help("argtrack") argv = e_cli.splitargs(line) if len(argv) != 2: return self.do_help("argtrack") try: fva = self.parseExpression(argv[0]) except Exception: self.vprint("Invalid Address Expression: %s" % argv[0]) return try: idx = self.parseExpression(argv[1]) except Exception: self.vprint("Invalid Index Expression: %s" % argv[1]) return if self.getFunction(fva) != fva: self.vprint("Invalid Function Address: (0x%.8x) %s" % (fva, line)) for pleaf in viv_vector.trackArgOrigin(self, fva, idx): self.vprint('=' * 80) path = vg_path.getPathToNode(pleaf) path.reverse() for pnode in path: fva = vg_path.getNodeProp(pnode, 'fva') argv = vg_path.getNodeProp(pnode, 'argv') callva = vg_path.getNodeProp(pnode, 'cva') argidx = vg_path.getNodeProp(pnode, 'argidx') if callva is not None: aval, amagic = argv[argidx] arepr = '0x%.8x' % aval if amagic is not None: arepr = repr(amagic) frepr = 'UNKNOWN' if fva is not None: frepr = '0x%.8x' % fva self.vprint('func: %s calls at: 0x%.8x with his own: %s' % (frepr, callva, arepr)) self.vprint("=" * 80)
def do_resume(self, line): """ Resume a thread. Usage: resume <-A | <tid>[ <tid>...]> """ argv = e_cli.splitargs(line) try: opts, args = getopt(argv, "A") except Exception, e: return self.do_help("suspend")
def do_resume(self, line): """ Resume a thread. Usage: resume <-A | <tid>[ <tid>...]> """ argv = e_cli.splitargs(line) try: opts,args = getopt(argv, "A") except Exception, e: return self.do_help("suspend")
def platformExec(self, cmdline): # Basically just like the one in the Ptrace mixin... self.execing = True cmdlist = e_cli.splitargs(cmdline) os.stat(cmdlist[0]) pid = os.fork() if pid == 0: v_posix.ptrace(PT_TRACE_ME, 0, 0, 0) os.execv(cmdlist[0], cmdlist) sys.exit(-1) return pid
def do_memdiff(self, line): """ Save and compare snapshots of memory to enumerate changes. Usage: memdiff [options] -C Clear all current memory diff snapshots. -A <va:size> Add the given virtual address to the list. -M <va> Add the entire memory map which contains VA to the list. -D Compare currently tracked memory with the target process and show any differences. """ argv = e_cli.splitargs(line) opts,args = getopt(argv, "A:CDM:") if len(opts) == 0: return self.do_help('memdiff') self.trace.requireNotRunning() for opt,optarg in opts: if opt == "-A": if optarg.find(':') == -1: return self.do_help('memdiff') vastr,sizestr = optarg.split(':') va = self.parseExpression(vastr) size = self.parseExpression(sizestr) bytes = self.trace.readMemory(va,size) self.difftracks[va] = bytes elif opt == '-C': self.difftracks = {} elif opt == '-D': difs = self._getDiffs() if len(difs) == 0: self.vprint('No Differences!') else: for va,thenbytes,nowbytes in difs: self.vprint('0x%.8x: %s %s' % (va, thenbytes.encode('hex'), nowbytes.encode('hex'))) elif opt == '-M': va = self.parseExpression(optarg) map = self.trace.getMemoryMap(va) if map == None: self.vprint('No Memory Map At: 0x%.8x' % va) return mva,msize,mperm,mfile = map bytes = self.trace.readMemory(mva, msize) self.difftracks[mva] = bytes
def do_symboliks(self, line): ''' Use the new symboliks subsystem. (NOTE: i386 only for a bit...) Usage: symboliks [ options ] -A Run the emu and show the state of the machine for all found paths to the given address ''' if not line: return self.do_help("symboliks") watchaddr = None argv = e_cli.splitargs(line) try: opts, argv = getopt(argv, 'A:') except Exception: return self.do_help('symboliks') for opt, optarg in opts: if opt == '-A': # TODO: USE THIS watchaddr = self.parseExpression(optarg) va = self.parseExpression(argv[0]) fva = self.getFunction(va) import vivisect.symboliks as viv_symboliks import vivisect.symboliks.common as sym_common import vivisect.symboliks.effects as viv_sym_effects import vivisect.symboliks.analysis as vsym_analysis symctx = vsym_analysis.getSymbolikAnalysisContext(self) for emu, effects in symctx.getSymbolikPaths(fva): self.vprint('PATH %s' % ('=' * 60)) for eff in effects: eff.reduce(emu) if eff.efftype in (EFFTYPE_CONSTRAIN, EFFTYPE_CALLFUNC): self.vprint(str(eff)) for addrsym, valsym in emu._sym_mem.values(): addrsym = addrsym.reduce(emu=emu) valsym = valsym.reduce(emu=emu) if emu.isLocalMemory(addrsym): continue self.vprint('[ %s ] = %s' % (addrsym, valsym)) self.vprint('RETURN %r' % emu.getFunctionReturn().reduce())
def do_memdiff(self, line): """ Save and compare snapshots of memory to enumerate changes. Usage: memdiff [options] -C Clear all current memory diff snapshots. -A <va:size> Add the given virtual address to the list. -M <va> Add the entire memory map which contains VA to the list. -D Compare currently tracked memory with the target process and show any differences. """ argv = e_cli.splitargs(line) opts, args = getopt(argv, "A:CDM:") if len(opts) == 0: return self.do_help('memdiff') self.trace.requireNotRunning() for opt, optarg in opts: if opt == "-A": if optarg.find(':') == -1: return self.do_help('memdiff') vastr, sizestr = optarg.split(':') va = self.parseExpression(vastr) size = self.parseExpression(sizestr) bytes = self.trace.readMemory(va, size) self.difftracks[va] = bytes elif opt == '-C': self.difftracks = {} elif opt == '-D': difs = self._getDiffs() if len(difs) == 0: self.vprint('No Differences!') else: for va, thenbytes, nowbytes in difs: self.vprint('0x%.8x: %s %s' % (va, thenbytes.encode('hex'), nowbytes.encode('hex'))) elif opt == '-M': va = self.parseExpression(optarg) map = self.trace.getMemoryMap(va) if map == None: self.vprint('No Memory Map At: 0x%.8x' % va) return mva, msize, mperm, mfile = map bytes = self.trace.readMemory(mva, msize) self.difftracks[mva] = bytes
def do_make(self, line): """ Create new instances of locations in the vivisect workspace. Usage: make [options] <va_expr> -c Make code -f Make function -s Make a string -u Make a unicode string -n <size> Make a number -p <size> Make a pad -S <structname> Make a structure """ argv = e_cli.splitargs(line) try: opts, args = getopt(argv, "csup:S:") except Exception as e: logger.warning(str(e)) return self.do_help("make") if len(args) != 1 or len(opts) != 1: return self.do_help("make") addr = self.parseExpression(args[0]) opt, optarg = opts[0] if opt == "-f": logger.debug('new function (manual-cli): 0x%x', addr) self.makeFunction(addr) elif opt == "-c": self.makeCode(addr) elif opt == "-s": self.makeString(addr) elif opt == "-u": self.makeUnicode(addr) elif opt == "-n": size = self.parseExpression(optarg) self.makeNumber(addr, size) elif opt == "-p": size = self.parseExpression(optarg) self.makePad(addr, size) elif opt == "-S": self.makeStructure(addr, optarg) else: return self.do_help("make")
def do_fscope(self, line): ''' The fscope command can be used to enumerate things from the scope of one function and down it's calling graph. Usage: fscope [options] <func_addr_expr> -I - Show import calls from this function scope -S - Show strings from this function scope Example: fscope -I kernel32.CreateFileW (Show imports called by CreateFileW and down...) ''' showimp = False showstr = False argv = e_cli.splitargs(line) try: opts, args = getopt(argv, 'IS') except Exception: return self.do_help('fscope') if not len(args) or not len(opts): return self.do_help('fscope') for opt, optarg in opts: if opt == '-I': showimp = True elif opt == '-S': showstr = True for expr in args: va = self.parseExpression(expr) if showimp: for callva, impname in v_t_fscope.getImportCalls(self, va): pstr = self.arch.pointerString(callva) self.canvas.addVaText(pstr, callva) # FIXME best name symbol etc? self.canvas.addText(' %s\n' % impname) if showstr: for refva, strva, strbytes in v_t_fscope.getStringRefs( self, va): pstr = self.arch.pointerString(refva) self.canvas.addVaText(pstr, refva) self.canvas.addText(' ') self.canvas.addVaText(strbytes, strva) self.canvas.addText('\n')
def do_argtrack(self, line): """ Track input arguments to the given function by name or address. Usage: argtrack <func_addr_expr> <arg_idx> """ if not line: return self.do_help("argtrack") argv = e_cli.splitargs(line) if len(argv) != 2: return self.do_help("argtrack") try: fva = self.parseExpression(argv[0]) except Exception as e: self.vprint("Invalid Address Expression: %s" % argv[0]) return try: idx = self.parseExpression(argv[1]) except Exception as e: self.vprint("Invalid Index Expression: %s" % argv[1]) return if self.getFunction(fva) != fva: self.vprint("Invalid Function Address: (0x%.8x) %s" % (fva, line)) for pleaf in viv_vector.trackArgOrigin(self, fva, idx): self.vprint('='*80) path = vg_path.getPathToNode(pleaf) path.reverse() for pnode in path: fva = vg_path.getNodeProp(pnode, 'fva') argv = vg_path.getNodeProp(pnode, 'argv') callva = vg_path.getNodeProp(pnode, 'cva') argidx = vg_path.getNodeProp(pnode, 'argidx') if callva != None: aval, amagic = argv[argidx] arepr = '0x%.8x' % aval if amagic != None: arepr = repr(amagic) frepr = 'UNKNOWN' if fva != None: frepr = '0x%.8x' % fva self.vprint('func: %s calls at: 0x%.8x with his own: %s' % (frepr, callva, arepr)) self.vprint("="*80)
def do_make(self, line): """ Create new instances of locations in the vivisect workspace. Usage: make [options] <va_expr> -c Make code -f Make function -s Make a string -u Make a unicode string -n <size> Make a number -p <size> Make a pad -S <structname> Make a structure """ argv = e_cli.splitargs(line) try: opts,args = getopt(argv, "csup:S:") except Exception as e: return self.do_help("make") if len(args) != 1 or len(opts) != 1: return self.do_help("make") addr = self.parseExpression(args[0]) opt, optarg = opts[0] if opt == "-f": self.makeFunction(addr) elif opt == "-c": self.makeCode(addr) elif opt == "-s": self.makeString(addr) elif opt == "-u": self.makeUnicode(addr) elif opt == "-n": size = self.parseExpression(optarg) self.makeNumber(addr, size) elif opt == "-p": size = self.parseExpression(optarg) self.makePad(addr, size) elif opt == "-S": self.makeStructure(addr, optarg) else: return self.do_help("make")
def do_fscope(self, line): ''' The fscope command can be used to enumerate things from the scope of one function and down it's calling graph. Usage: fscope [options] <func_addr_expr> -I - Show import calls from this function scope -S - Show strings from this function scope Example: fscope -I kernel32.CreateFileW (Show imports called by CreateFileW and down...) ''' showimp = False showstr = False argv = e_cli.splitargs(line) try: opts,args = getopt(argv, 'IS') except Exception as e: return self.do_help('fscope') if not len(args) or not len(opts): return self.do_help('fscope') for opt,optarg in opts: if opt == '-I': showimp = True elif opt == '-S': showstr = True for expr in args: va = self.parseExpression(expr) if showimp: for callva, impname in v_t_fscope.getImportCalls(self, va): pstr = self.arch.pointerString(callva) self.canvas.addVaText(pstr, callva) # FIXME best name symbol etc? self.canvas.addText(' %s\n' % impname) if showstr: for refva, strva, strbytes in v_t_fscope.getStringRefs(self, va): pstr = self.arch.pointerString(refva) self.canvas.addVaText(pstr, refva) self.canvas.addText(' ') self.canvas.addVaText(strbytes, strva) self.canvas.addText('\n')
def jit(vdb, line): ''' Enable/Disable the current VDB location as the current Just-In-Time debugger for windows applications. Usage: jitenable [-D] -E Enable VDB JIT debugging -D Disable JIT debugging ''' argv = e_cli.splitargs(line) try: opts,args = getopt.getopt(argv, "ED") except Exception, e: return vdb.do_help('jit')
def jit(vdb, line): ''' Enable/Disable the current VDB location as the current Just-In-Time debugger for windows applications. Usage: jitenable [-D] -E Enable VDB JIT debugging -D Disable JIT debugging ''' argv = e_cli.splitargs(line) try: opts, args = getopt.getopt(argv, "ED") except Exception, e: return vdb.do_help('jit')
def pe(vdb, line): """ Show extended info about loaded PE binaries. Usage: pe [opts] [<libname>...] -I Show PE import files. -t Show PE timestamp information """ #-v Show PE version information argv = e_cli.splitargs(line) try: opts, args = getopt.getopt(argv, "Itv") except Exception, e: vdb.vprint(pe.__doc__) return
def do_bpfile(self, line): """ Set the python code for a breakpoint from the contents of a file. Usage: bpfile <bpid> <filename> """ argv = e_cli.splitargs(line) if len(argv) != 2: return self.do_help("bpfile") bpid = int(argv[0]) pycode = file(argv[1], "rU").read() self.trace.setBreakpointCode(bpid, pycode)
def pe(vdb, line): """ Show extended info about loaded PE binaries. Usage: pe [opts] [<libname>...] -I Show PE import files. -t Show PE timestamp information """ #-v Show PE version information argv = e_cli.splitargs(line) try: opts,args = getopt.getopt(argv, "Itv") except Exception, e: vdb.vprint(pe.__doc__) return
def jit(vdb, line): ''' Enable/Disable the current VDB location as the current Just-In-Time debugger for windows applications. Usage: jitenable [-D] -E Enable VDB JIT debugging -D Disable JIT debugging ''' argv = e_cli.splitargs(line) try: opts, args = getopt.getopt(argv, "ED") except Exception: return vdb.do_help('jit') try: import _winreg except Exception: vdb.vprint('Error Importing _winreg: %s' % e) return HKLM = _winreg.HKEY_LOCAL_MACHINE HKCU = _winreg.HKEY_CURRENT_USER REG_SZ = _winreg.REG_SZ regpath = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug' #wow64path = r'SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug' #regkey = _winreg.CreateKey(HKLM, regpath) regkey = _winreg.CreateKey(HKLM, regpath) vdb.vprint('JIT Currently: %s' % _winreg.QueryValueEx(regkey, 'Debugger')[0]) setval = None for opt, optarg in opts: if opt == '-D': setval = '' elif opt == '-E': vdbpath = os.path.abspath(sys.argv[0]) setval = '%s %s -r -p %%ld -e %%Id' % (sys.executable, vdbpath) #_winreg.SetValue(HKLM if setval is not None: vdb.vprint('Setting JIT: %s' % (setval, )) _winreg.SetValueEx(regkey, 'Debugger', None, REG_SZ, setval)
def einfo(vdb, line): """ Show all the current exception information. -P Toggle the "PendingSignal" meta key which controls delivery (or handling) of the current exception. Usage: einfo [options] """ argv = e_cli.splitargs(line) t = vdb.getTrace() try: opts,args = getopt.getopt(argv, 'P') except Exception, e: return vdb.do_help('einfo')
def einfo(vdb, line): """ Show all the current exception information. -P Toggle the "PendingException" meta key which controls delivery (or handling) of the current exception. Usage: einfo [options] """ argv = e_cli.splitargs(line) t = vdb.getTrace() try: opts, args = getopt.getopt(argv, 'P') except Exception, e: return vdb.do_help('einfo')
def jit(vdb, line): ''' Enable/Disable the current VDB location as the current Just-In-Time debugger for windows applications. Usage: jitenable [-D] -E Enable VDB JIT debugging -D Disable JIT debugging ''' argv = e_cli.splitargs(line) try: opts,args = getopt.getopt(argv, "ED") except Exception as e: return vdb.do_help('jit') try: import winreg except Exception as e: vdb.vprint('Error Importing _winreg: %s' % e) return HKLM = winreg.HKEY_LOCAL_MACHINE HKCU = winreg.HKEY_CURRENT_USER REG_SZ = winreg.REG_SZ regpath = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug' #wow64path = r'SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug' #regkey = _winreg.CreateKey(HKLM, regpath) regkey = winreg.CreateKey(HKLM, regpath) vdb.vprint('JIT Currently: %s' % winreg.QueryValueEx(regkey, 'Debugger')[0]) setval = None for opt,optarg in opts: if opt == '-D': setval = '' elif opt == '-E': vdbpath = os.path.abspath(sys.argv[0]) setval = '%s %s -r -p %%ld -e %%Id' % (sys.executable, vdbpath) #_winreg.SetValue(HKLM if setval != None: vdb.vprint('Setting JIT: %s' % (setval,)) winreg.SetValueEx(regkey, 'Debugger', None, REG_SZ, setval)
def platformExec(self, cmdline): # Very similar to posix, but not # quite close enough... self.execing = True cmdlist = e_cli.splitargs(cmdline) os.stat(cmdlist[0]) pid = os.fork() if pid == 0: try: # Don't use PT_TRACEME -- on some linux (tested on ubuntu) # it will cause immediate asignment of ptrace slot to parent # without parent having PT_ATTACH'D.... MAKES SYNCHRONIZATION HARD # SIGSTOP ourself until parent continues us os.kill(os.getpid(), signal.SIGSTOP) os.execv(cmdlist[0], cmdlist) except Exception as e: print(e) sys.exit(-1) # Attach to child. should cause SIGSTOP if 0 != v_posix.ptrace(PT_ATTACH, pid, 0, 0): raise Exception("PT_ATTACH failed! linux platformExec") # Eat all SIGSTOP (or other signal) and break from loop on SIGTRAP. # SIGTRAP triggered by execv while PTRACE_ATTACH'd while True: wpid, status = os.waitpid(pid, os.WUNTRACED) if wpid != pid: # should never happen continue if os.WIFSTOPPED(status): cause = os.WSTOPSIG(status) if cause == signal.SIGTRAP: break if v_posix.ptrace(v_posix.PT_CONTINUE, pid, 0, 0) != 0: raise Exception("PT_CONTINUE failed! linux platformExec") # Do a single step, which will allow a new stop event for the # rest of vtrace to eat up. if v_posix.ptrace(v_posix.PT_STEP, pid, 0, 0) != 0: raise Exception("PT_CONTINUE failed! linux platformExec") self.pthreads = [ pid, ] self.setMeta("ExeName", self._findExe(pid)) return pid
def vivimport(db, line): ''' Import either a library or memory map from the target process into the current vivisect workspace. ''' vw = db.vw trace = db.getTrace() argv = e_cli.splitargs(line) if len(argv) != 1: return db.do_help("vivimport") try: base = db.parseExpression(line) except Exception, e: db.vprint("Invalid Address Expression: %s" % argv[0]) return
def einfo(vdb, line): """ Show all the current exception information. -P Toggle the "PendingSignal" meta key which controls delivery (or handling) of the current exception. Usage: einfo [options] """ argv = e_cli.splitargs(line) t = vdb.getTrace() try: opts, args = getopt.getopt(argv, 'P') except Exception: return vdb.do_help('einfo') for opt, optarg in opts: if opt == '-P': p = t.getMeta('PendingSignal') if p is not None: t.setMeta('OrigSignal', p) t.setMeta('PendingSignal', None) else: newp = t.getMeta('OrigSignal', None) t.setMeta('PendingSignal', newp) exc = t.getMeta("Win32Event", None) if exc is None: vdb.vprint("No Exception Information Found") ecode = exc.get("ExceptionCode", 0) eaddr = exc.get("ExceptionAddress", 0) chance = 2 if exc.get("FirstChance", False): chance = 1 einfo = exc.get("ExceptionInformation", []) #FIXME get extended infoz #FIXME unify with cli thing vdb.vprint("Win32 Exception 0x%.8x at 0x%.8x (%d chance)" % (ecode, eaddr, chance)) vdb.vprint("Exception Information: %s" % " ".join([hex(i) for i in einfo])) dbool = True if t.getCurrentSignal() is None: dbool = False vdb.vprint('Deliver Exception: %s' % dbool)
def do_struct(self, args): """ Break out a strcuture from memory. You may use the command "vstruct" to show the known structures in vstruct. Usage: struct <StructName> <vtrace expression> """ try: clsname, vexpr = e_cli.splitargs(args) except: return self.do_help("struct") t = self.trace addr = t.parseExpression(vexpr) s = t.getStruct(clsname, addr) self.vprint(s.tree(va=addr))
def einfo(vdb, line): """ Show all the current exception information. -P Toggle the "PendingSignal" meta key which controls delivery (or handling) of the current exception. Usage: einfo [options] """ argv = e_cli.splitargs(line) t = vdb.getTrace() try: opts,args = getopt.getopt(argv, 'P') except Exception as e: return vdb.do_help('einfo') for opt,optarg in opts: if opt == '-P': p = t.getMeta('PendingSignal') if p != None: t.setMeta('OrigSignal', p) t.setMeta('PendingSignal', None) else: newp = t.getMeta('OrigSignal', None) t.setMeta('PendingSignal', newp) exc = t.getMeta("Win32Event", None) if exc == None: vdb.vprint("No Exception Information Found") ecode = exc.get("ExceptionCode", 0) eaddr = exc.get("ExceptionAddress",0) chance = 2 if exc.get("FirstChance", False): chance = 1 einfo = exc.get("ExceptionInformation", []) #FIXME get extended infoz #FIXME unify with cli thing vdb.vprint("Win32 Exception 0x%.8x at 0x%.8x (%d chance)" % (ecode, eaddr, chance)) vdb.vprint("Exception Information: %s" % " ".join([hex(i) for i in einfo])) dbool = True if t.getCurrentSignal() == None: dbool = False vdb.vprint('Deliver Exception: %s' % dbool)
def do_syms(self, line): """ List symbols and by file. Usage: syms [-s <pattern>] [filename] With no arguments, syms will self.vprint(the possible libraries with symbol resolvers. Specify a library to see all the symbols for it. """ argv = e_cli.splitargs(line) try: opts, args = getopt(argv, "s:") except: return self.do_help("syms") pattern = None for opt, optarg in opts: if opt == "-s": pattern = optarg.lower() libs = self.trace.getNormalizedLibNames() if len(args) == 0: self.vprint("Current Library Symbol Resolvers:") libs.sort() for libname in libs: self.vprint(" %s" % libname) else: libname = args[0] if libname not in libs: self.vprint("Unknown libname: %s" % libname) return if pattern: self.vprint("Matching Symbols From %s:" % libname) else: self.vprint("Symbols From %s:" % libname) for sym in self.trace.getSymsForFile(libname): r = repr(sym) if pattern != None: if r.lower().find(pattern) == -1: continue self.vprint("0x%.8x %s" % (sym.value, r))
def do_syms(self, line): """ List symbols and by file. Usage: syms [-s <pattern>] [filename] With no arguments, syms will self.vprint(the possible libraries with symbol resolvers. Specify a library to see all the symbols for it. """ argv = e_cli.splitargs(line) try: opts,args = getopt(argv, "s:") except: return self.do_help("syms") pattern = None for opt,optarg in opts: if opt == "-s": pattern = optarg.lower() libs = self.trace.getNormalizedLibNames() if len(args) == 0: self.vprint("Current Library Symbol Resolvers:") libs.sort() for libname in libs: self.vprint(" %s" % libname) else: libname = args[0] if libname not in libs: self.vprint("Unknown libname: %s" % libname) return if pattern: self.vprint("Matching Symbols From %s:" % libname) else: self.vprint("Symbols From %s:" % libname) for sym in self.trace.getSymsForFile(libname): r = repr(sym) if pattern != None: if r.lower().find(pattern) == -1: continue self.vprint("0x%.8x %s" % (sym.value, r))
def platformExec(self, cmdline): # Very similar to posix, but not # quite close enough... self.execing = True cmdlist = e_cli.splitargs(cmdline) os.stat(cmdlist[0]) pid = os.fork() if pid == 0: try: # Don't use PT_TRACEME -- on some linux (tested on ubuntu) # it will cause immediate asignment of ptrace slot to parent # without parent having PT_ATTACH'D.... MAKES SYNCHRONIZATION HARD # SIGSTOP ourself until parent continues us os.kill(os.getpid(),signal.SIGSTOP) os.execv(cmdlist[0], cmdlist) except Exception as e: print e sys.exit(-1) # Attach to child. should cause SIGSTOP if 0 != v_posix.ptrace(PT_ATTACH, pid, 0, 0): raise Exception("PT_ATTACH failed! linux platformExec") # Eat all SIGSTOP (or other signal) and break from loop on SIGTRAP. # SIGTRAP triggered by execv while PTRACE_ATTACH'd while True: wpid,status = os.waitpid(pid,os.WUNTRACED) if wpid != pid: #should never happen continue if os.WIFSTOPPED(status): cause = os.WSTOPSIG(status) if cause == signal.SIGTRAP: break if v_posix.ptrace(v_posix.PT_CONTINUE, pid, 0, 0) != 0: raise Exception("PT_CONTINUE failed! linux platformExec") # Do a single step, which will allow a new stop event for the # rest of vtrace to eat up. if v_posix.ptrace(v_posix.PT_STEP, pid, 0, 0) != 0: raise Exception("PT_CONTINUE failed! linux platformExec") self.pthreads = [pid,] self.setMeta("ExeName", self._findExe(pid)) return pid
def do_codepath(self, line): """ Enumerate and show any known code paths from the specified from address expression to the to address expression. Usage: codepath <from_expr> <to_expr> """ if not line: return self.do_help("codepath") argv = e_cli.splitargs(line) if len(argv) != 2: return self.do_help("codepath") try: frva = self.parseExpression(argv[0]) except Exception, e: self.vprint("Invalid From Va: %s" % argv[0]) return
def do_argtrack(self, line): """ Track input arguments to the given function by name or address. Usage: argtrack <func_addr_expr> <arg_idx> """ if not line: return self.do_help("argtrack") argv = e_cli.splitargs(line) if len(argv) != 2: return self.do_help("argtrack") try: fva = self.parseExpression(argv[0]) except Exception, e: self.vprint("Invalid Address Expression: %s" % argv[0]) return
def do_make(self, line): """ Create new instances of locations in the vivisect workspace. Usage: make [options] <va_expr> -c Make code -f Make function -s Make a string -u Make a unicode string -n <size> Make a number -p <size> Make a pad -S <structname> Make a structure """ argv = e_cli.splitargs(line) try: opts,args = getopt(argv, "csup:S:") except Exception, e: return self.do_help("make")