Source code for vdb.extensions.windows

import os
import sys
import getopt

import vtrace
import vtrace.tools.win32heap as win32heap
import vtrace.tools.win32aslr as win32_aslr
import vtrace.tools.iathook as vt_iathook
import vtrace.tools.win32stealth as win32_stealth
import vtrace.util as v_util

import envi.memory as e_mem
import envi.cli as e_cli
import envi.bits as e_bits

import PE
import vstruct.defs.pe as vs_pe

[docs]def teb(vdb, line): """ Print out the TEB for the current or specified thread. Usage: teb [threadid] """ t = vdb.getTrace() threads = t.getThreads() tid = t.getMeta("ThreadId") if len(line): tid = t.parseExpression(line) taddr = threads.get(tid) if taddr == None: vdb.vprint("Invalid Thread ID: %d" % tid) return teb = t.getStruct("ntdll.TEB", taddr) vdb.vprint(teb.tree(va=taddr, reprmax=32))
[docs]def peb(vdb, line): """ Print the PEB Usage: peb """ t = vdb.getTrace() t.requireAttached() pebaddr = t.getMeta("PEB") peb = t.getStruct("ntdll.PEB", pebaddr) vdb.vprint(peb.tree(pebaddr, reprmax=32))
[docs]def regkeys(vdb, line): """ Show all the registry keys the target process currently has open. Usage: regkeys """ t = vdb.getTrace() t.requireAttached() vdb.vprint("\nOpen Registry Keys:\n") for fd,ftype,fname in t.getFds(): if ftype == vtrace.FD_REGKEY: vdb.vprint("\t%s" % fname) vdb.vprint("")
[docs]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') 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)
[docs]def seh(vdb, line): """ Walk and print the SEH chain for the current (or specified) thread. Usage: seh [threadid] """ t = vdb.getTrace() if len(line) == 0: tid = t.getMeta("ThreadId") else: tid = int(line) tinfo = t.getThreads().get(tid, None) if tinfo == None: vdb.vprint("Unknown Thread Id: %d" % tid) return teb = t.getStruct("ntdll.TEB", tinfo) addr = long(teb.NtTib.ExceptionList) vdb.vprint("REG HANDLER") while addr != 0xffffffff: #FIXME print out which frame these are in er = t.getStruct("ntdll.EXCEPTION_REGISTRATION_RECORD", addr) vdb.vprint("0x%.8x 0x%.8x" % (addr, er.Handler)) addr = long(er.Next)
[docs]def safeseh(vdb, line): """ Show the SafeSEH status of all the loaded DLLs or list the handlers for a particular dll by normalized name. Usage: safeseh [libname] """ t = vdb.getTrace() libs = t.getMeta("LibraryBases") if len(line): base = libs.get(line) if base == None: vdb.vprint("Unknown library: %s" % line) return vdb.vprint("%s:" % line) try: p = PE.peFromMemoryObject(t, base) except Exception, e: vdb.vprint('Error: %s (0x%.8x) %s' % (line, base, e)) return if p.IMAGE_LOAD_CONFIG != None: va = int(p.IMAGE_LOAD_CONFIG.SEHandlerTable) if va != 0: count = int(p.IMAGE_LOAD_CONFIG.SEHandlerCount) for h in t.readMemoryFormat(va, "<%dL" % count): vdb.vprint("\t0x%.8x %s" % (base+h, vdb.reprPointer(base+h))) return vdb.vprint("None...") else: lnames = libs.keys() lnames.sort() for name in lnames: base = libs.get(name) try: p = PE.peFromMemoryObject(t, base) except Exception, e: vdb.vprint('Error: %s (0x%.8x) %s' % (name, base, e)) continue enabled = False if p.IMAGE_LOAD_CONFIG != None: va = int(p.IMAGE_LOAD_CONFIG.SEHandlerTable) if va != 0: enabled = True #print name #print p.IMAGE_LOAD_CONFIG vdb.vprint("%16s\t%s" % (name, enabled))
[docs]def validate_heaps(db): """ A simple routine that works like the built in windows heap checkers to show where blocks and/or freelist is potentially dorked. """ trace = db.getTrace() db.vprint("Validating:") for heap in win32heap.getHeaps(trace): db.vprint("%s: 0x%.8x" % ("heap".rjust(9), heap.address)) try: f = heap.getFreeLists() except Exception, e: #import traceback #traceback.print_exc() db.vprint("%s: %s" % (e.__class__.__name__,e)) for seg in heap.getSegments(): db.vprint("%s: 0x%.8x" % ("segment".rjust(9),seg.address)) try: blist = seg.getChunks() for i,chunk in enumerate(blist): if i == 0: continue if heap._win7_heap: continue pchunk = blist[i-1] if chunk.chunk.PreviousSize != pchunk.chunk.Size: db.vprint('Corruption! (block at 0x%.8x (size: %d) block at 0x%.8x (prevsize: %d)' % (pchunk.address, pchunk.chunk.Size, chunk.address, chunk.chunk.PreviousSize)) break except Exception, e: db.vprint("%s: %s" % (e.__class__.__name__,e))
[docs]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') for opt,optarg in opts: if opt == "-F": freelist_heap = t.parseExpression(optarg) elif opt == "-C": chunkfind_addr = t.parseExpression(optarg) elif opt == "-L": lookaside_heap = t.parseExpression(optarg) elif opt == "-S": chunklist_seg = t.parseExpression(optarg) elif opt == "-V": return validate_heaps(vdb) elif opt == "-l": leakfind_heap = t.parseExpression(optarg) elif opt == '-U': uncommit_heap = t.parseExpression(optarg) if lookaside_heap != None: haddrs = [h.address for h in win32heap.getHeaps(t)] if lookaside_heap not in haddrs: vdb.vprint("0x%.8x is NOT a valid heap!" % lookaside_heap) return heap = win32heap.Win32Heap(t, lookaside_heap) vdb.vprint('[Index] [Chunks]') for i,l in enumerate(heap.getLookAsideLists()): vdb.vprint("[%d]" % i) for c in l: vdb.vprint(" %s" % (repr(c))) elif uncommit_heap != None: haddrs = [h.address for h in win32heap.getHeaps(t)] if uncommit_heap not in haddrs: vdb.vprint("0x%.8x is NOT a valid heap!" % uncommit_heap) return heap = win32heap.Win32Heap(t, uncommit_heap) ucrdict = heap.getUCRDict() addrs = ucrdict.keys() addrs.sort() if len(addrs) == 0: vdb.vprint('Heap 0x%.8x has 0 uncommited-ranges!' % uncommit_heap) return vdb.vprint('Uncommited ranges for heap: 0x%.8x' % uncommit_heap) for ucraddr in addrs: size = ucrdict.get(ucraddr) vdb.vprint('0x%.8x (%d)' % (ucraddr, size)) return elif freelist_heap != None: haddrs = [h.address for h in win32heap.getHeaps(t)] if freelist_heap not in haddrs: vdb.vprint("0x%.8x is NOT a valid heap!" % freelist_heap) return heap = win32heap.Win32Heap(t, freelist_heap) for i,l in enumerate(heap.getFreeLists()): if len(l): vdb.vprint("Freelist Index: %d" % i) for c in l: vdb.vprint(" %s" % repr(c)) elif chunkfind_addr != None: heap,seg,chunk = win32heap.getHeapSegChunk(t, chunkfind_addr) vdb.vprint("Address 0x%.8x found in:" % (chunkfind_addr,)) vdb.vprint("Heap: 0x%.8x" % (heap.address)) vdb.vprint("Segment: 0x%.8x" % (seg.address)) vdb.vprint("Chunk: 0x%.8x (%d) FLAGS: %s" % (chunk.address, len(chunk),chunk.reprFlags())) elif chunklist_seg != None: for heap in win32heap.getHeaps(t): for seg in heap.getSegments(): if chunklist_seg == seg.address: vdb.vprint("Chunks for segment at 0x%.8x (X == in use)" % chunklist_seg) for chunk in seg.getChunks(): c = " " if chunk.isBusy(): c = "X" vdb.vprint("0x%.8x %s (%d)" % (chunk.address,c,len(chunk))) return vdb.vprint("Segment 0x%.8x not found!" % chunklist_seg) elif leakfind_heap != None: # FIXME do this the slow way for now... haddrs = [h.address for h in win32heap.getHeaps(t)] if leakfind_heap not in haddrs: vdb.vprint("0x%.8x is NOT a valid heap!" % leakfind_heap) return h = win32heap.Win32Heap(t, leakfind_heap) for seg in h.getSegments(): for chunk in seg.getChunks(): if chunk.address == seg.address: continue # Obviously, only check for leaks if they are in use... # FIXME we will need to check the lookaside also... if not chunk.isBusy(): continue addr = chunk.getDataAddress() # FIXME get size and endian from trace pat = e_bits.buildbytes(addr, 4) l = t.searchMemory(pat) if len(l) == 0: vdb.vprint("0x%.8x may be leaked!" % addr) else: vdb.vprint("Heap\t\tSegment") for heap in win32heap.getHeaps(t): flags = " ".join(heap.getFlagNames()) for s in heap.getSegments(): vdb.vprint("0x%.8x\t0x%.8x\t%s" % (heap.address, s.address, flags))
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040
[docs]def showaslr(vdb, base, libname): t = vdb.getTrace() try: p = PE.peFromMemoryObject(t, base) except Exception, e: vdb.vprint('Error: %s (0x%.8x) %s' % (name, base, e)) return enabled = False c = p.IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics if c & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE: enabled = True vdb.vprint("%16s\t%s" % (libname, enabled))
[docs]def aslr(vdb, line): """ Determine which PE's in the current process address space support Vista's ASLR implementation by the presence of the IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE (0x0040) bit in the DllCharacteristics field of the PE header. Usage: aslr [libname] """ t = vdb.getTrace() libs = t.getMeta("LibraryBases") if line: base = libs.get(line) if base == None: vdb.vprint("Unknown library: %s" % line) return showaslr(vdb, base, line) else: lnames = libs.keys() lnames.sort() for name in lnames: base = libs.get(name) showaslr(vdb, base, name)
def _printPageHits(vdb, hits, unique=False): vdb.vprint('[ eip ] [ mem addr ] [ access ]') if unique: newhits = [] [newhits.append(h) for h in hits if not newhits.count(h)] hits = newhits for eip,addr,perm in hits: vdb.vprint("0x%.8x 0x%.8x %s" % (eip,addr,e_mem.getPermName(perm)))
[docs]def pagewatch(vdb, line): """ Enable write access watching on a given memory page. This works by setting the page to read-only and then specially handling the access violations as though they were hardware Watchpoints. Usage: pagewatch [options] [<addr_expression>] -C - Clear the current pagewatch log -F - Toggle auto-continue behavior (run and record vs. stop on hit) -L - List the current hits from the pagewatch log -M - Add page watches to the entire memory map from addr_expression -R - Use to enable *read* watching while adding a page watch -S <addr> - Show touches to the specified address -P <addr> - Show memory touched by specifed program counter (eip) -u - When listing, show only *unique* entries """ argv = e_cli.splitargs(line) try: opts,args = getopt.getopt(argv, "CFLMP:RS:u") except Exception, e: return vdb.do_help('pagewatch') if vdb.trace.getMeta('pagewatch') == None: vdb.trace.setMeta('pagewatch', []) if vdb.trace.getMeta('pagerun') == None: vdb.trace.setMeta('pagerun', False) domap = False unique = False watchread = False for opt,optarg in opts: if opt == "-C": vdb.trace.setMeta("pagewatch", []) vdb.vprint("Pagewatch log cleared") return elif opt == '-F': pr = vdb.trace.getMeta('pagerun', False) pr = not pr vdb.trace.setMeta('pagerun', pr) vdb.vprint('Pagewatch Auto Continue: %s' % pr) return elif opt == "-L": hits = vdb.trace.getMeta('pagewatch', []) _printPageHits(vdb, hits, unique=unique) return elif opt == "-M": domap = True elif opt == '-R': watchread = True elif opt == "-S": saddr = vdb.trace.parseExpression(optarg) hits = vdb.trace.getMeta("pagewatch") if hits == None: vdb.vprint("No pagewatch log!") return hits = [ h for h in hits if h[1] == saddr ] _printPageHits(vdb, hits, unique=unique) return elif opt == "-P": saddr = vdb.trace.parseExpression(optarg) hits = vdb.trace.getMeta("pagewatch") if hits == None: vdb.vprint("No pagewatch log!") return hits = [ h for h in hits if h[0] == saddr ] _printPageHits(vdb, hits, unique=unique) return elif opt == '-u': unique = True if len(args) == 0: return vdb.do_help('pagewatch') baseaddr = vdb.trace.parseExpression(args[0]) # Page align baseaddr = baseaddr & 0xfffff000 maxaddr = baseaddr + 4096 map = vdb.trace.getMemoryMap(baseaddr) if map == None: raise Exception("Invalid memory map address 0x%.8x" % baseaddr) if domap: baseaddr = map[0] maxaddr = baseaddr + map[1] bpset = vdb.trace.breakpoints while baseaddr < maxaddr: # Skip ones that are already there! if not bpset.get(baseaddr): wp = vtrace.PageWatchpoint(baseaddr, size=4096, watchread=watchread) wpid = vdb.trace.addBreakpoint(wp) baseaddr += 4096
[docs]def stealth(vdb, line): """ Enable basic debugger stealth. This has the following effects: Change PEB to show BeingDebugged == 0 Special breakpoint on CheckRemoteDebuggerPresent WARNING: break/sendBreak() behave VERY strange with this because the kernel aparently doesn't think he needs to post the exception to the debugger? """ if vdb.trace.getMeta("Win32Stealth") != None: win32_stealth.unstealthify(vdb.trace) vdb.vprint("Stealth disabled") else: win32_stealth.stealthify(vdb.trace) vdb.vprint("Stealth enabled")
gflag_stuff = [ ('loader_snaps', 'ntdll.ShowSnaps', '<B', 0, 1), ('loader_debug', 'ntdll.LdrpDebugFlags', '<I', 0, 0xffffffff), ]
[docs]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 for hname, symname, fmt, offval, onval in gflag_stuff: status = 'Unknown' try: addr = vdb.trace.parseExpression(symname) val = vdb.trace.readMemoryFormat(addr, fmt)[0] if val == offval: status = 'Off' elif val == onval: status = 'On' except Exception, e: pass vdb.vprint('%s : %s' % (hname.rjust(20), status))
[docs]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+10 """ #-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') inmem = True showsecs = False showvers = False showtime = False showimps = False shownthd = False showexps = False showvsin = False for opt,optarg in opts: if opt == '-I': showimps = True elif opt == '-t': showtime = True elif opt == '-v': showvers = True elif opt == '-V': showvsin = True elif opt == '-N': shownthd = True elif opt == '-m': inmem = False elif opt == '-S': showsecs = True elif opt == '-E': showexps = True t = vdb.trace bases = t.getMeta("LibraryBases") paths = t.getMeta("LibraryPaths") names = args if len(names) == 0: names = t.getNormalizedLibNames() names.sort() names = e_cli.columnstr(names) for libname in names: base = bases.get(libname.strip(), None) if base == None: base = vdb.trace.parseExpression(libname) path = paths.get(base, "unknown") try: pobj = PE.peFromMemoryObject(t, base) except Exception, e: vdb.vprint('Error: %s (0x%.8x) %s' % (libname, base, e)) continue if showimps: ldeps = {} try: for rva,lname,fname in pobj.getImports(): ldeps[lname.lower()] = True lnames = ldeps.keys() lnames.sort() vdb.vprint('0x%.8x - %.30s %s' % (base, libname, ' '.join(lnames))) except Exception, e: vdb.vprint('Import Parser Error On %s: %s' % (libname, e)) elif showvers: version = 'Unknown!' vs = pobj.getVS_VERSIONINFO() if vs != None: version = vs.getVersionValue('FileVersion') vdb.vprint('%s: %s' % (libname.rjust(30),version)) elif showvsin: vs = pobj.getVS_VERSIONINFO() vdb.vprint('==== %s' % libname) if vs == None: vdb.vprint('no VS_VERSIONINFO...') else: vskeys = vs.getVersionKeys() vskeys.sort() for vskey in vskeys: vsval = vs.getVersionValue(vskey) vdb.vprint('%s: %s' % (vskey.rjust(20), vsval[:50])) elif showtime: tstamp = pobj.IMAGE_NT_HEADERS.FileHeader.TimeDateStamp vdb.vprint('0x%.8x - %.30s 0x%.8x' % (base, libname, tstamp)) elif shownthd: t = pobj.IMAGE_NT_HEADERS.tree(reprmax=32) vdb.vprint(t) elif showsecs: for sec in pobj.getSections(): vdb.vprint(sec.tree(reprmax=32)) elif showexps: vdb.vprint('[Ord] [Address] [Name]') for fva, ord, name in pobj.getExports(): vdb.vprint('%.4d 0x%.8x %s' % (ord, fva, name)) else: vdb.vprint('0x%.8x - %.30s %s' % (base, libname, path))
[docs]def bindiff(mem1, mem2): ret = [] i = 0 imax = len(mem1) while i < imax: r = i while mem1[r] != mem2[r] and r < imax: r += 1 # We found a discrepency if r != i: size = (r-i) ret.append((i,size)) i+=r i+=1 return ret
[docs]def deaslr(vdb, line): ''' Rebase the specified address expression as though the origin library had gotten it's suggested base address rather than being ASLR'd. Usage: deaslr <addr_expr> ''' if len(line) == 0: return vdb.do_help('deaslr') addr = vdb.trace.parseExpression(line) newaddr = win32_aslr.deAslr(vdb.trace, addr) vdb.vprint('aslr: 0x%.8x deaslr: 0x%.8x' % (addr, newaddr))
[docs]def sympath(vdb, line): ''' Set the symbol path for the tracer. This will currently only effect *subsequent* library loads! Usage: sympath <new_path> ''' if len(line): vdb.trace.setMeta('NtSymbolPath', line) sympath = vdb.trace.getMeta('NtSymbolPath') if sympath == None: sympath = os.getenv('_NT_SYMBOL_PATH') vdb.vprint('Current Symbol Path: %s' % sympath)
[docs]def stepb(vdb, line): ''' Use the extended intel hardware support to step to the next branch target. Usage: stepb NOTE: This will *not* work inside VMware / VirtualBox. Other hypervisors may vary... (it will simply single step) ''' if len(line): vdb.do_help('stepb') orig = vdb.trace.getMode('BranchStep') vdb.trace.setMode('BranchStep', True) # For now, lets cheat so we get FastStep behavior for free... vdb.do_stepi('') vdb.trace.setMode('BranchStep', orig)
[docs]def hooks(vdb, line): ''' Check the executable regions of the target process for any hooks by comparing against the PE on disk. This will account for relocations and import entries. ''' t = vdb.getTrace() bases = t.getMeta("LibraryBases") paths = t.getMeta("LibraryPaths") found = False for bname in bases.keys(): base = bases.get(bname) fpath = paths.get(base) pobj = PE.PE(file(fpath,'rb')) filebase = pobj.IMAGE_NT_HEADERS.OptionalHeader.ImageBase skips = {} # Get relocations for skipping r = (0,1,2,3) for relrva, reltype in pobj.getRelocations(): for i in r: skips[base+relrva+i] = True # Add the import entries to skip for iva,libname,name in pobj.getImports(): for i in r: skips[base+iva+i] = True for sec in pobj.getSections(): if sec.Characteristics & PE.IMAGE_SCN_MEM_EXECUTE: size = sec.VirtualSize va = base + sec.VirtualAddress fileva = filebase + sec.VirtualAddress filebytes = pobj.readAtRva(sec.VirtualAddress, sec.VirtualSize) procbytes = t.readMemory(va, size) for off,size in bindiff(filebytes, procbytes): difva = va + off fdifva = fileva + off # Check for a relocation covering this... if skips.get(difva): continue found = True dmem = procbytes[off:off+size].encode('hex')[:10] dfil = filebytes[off:off+size].encode('hex')[:10] vdb.canvas.addVaText('0x%.8x' % difva, difva) vdb.canvas.addText(' (0x%.8x) (%d)' % (fdifva,size)) vdb.canvas.addText(' mem: %s file: %s ' % (dmem, dfil)) sym = vdb.symobj.getSymByAddr(difva, exact=False) if sym != None: vdb.canvas.addText(' ') vdb.canvas.addVaText('%s + %d' % (repr(sym),difva-long(sym)), difva) vdb.canvas.addText('\n') if not found: vdb.canvas.addText('No Hooks Found!\n')
[docs]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') try: import _winreg except Exception, 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)
[docs]def svclist(vdb, line): ''' List the running service names and pids. Usage: svclist ''' cols = [] pids = [] names = [] descrs = [] for pid, name, descr in vdb.trace._getSvcList(): pids.append('%d' % pid) names.append(name) descrs.append(descr) names = e_cli.columnstr(names) for i in xrange(len(pids)): vdb.vprint('%8s %s %s' % (pids[i], names[i], descrs[i]))
[docs]def injectso(vdb, line): ''' Inject a shared object (DLL) into the target process. Usage: injectso <dllname> ''' if not line: return vdb.do_help('injectso') t = vdb.trace t.injectso(line)
token_elevation_types = { 0: 'UAC Not Present', 1: 'Default Elevation', 2: 'Elevated', 3: 'Low', }
[docs]def uac(db, line): ''' Display the current UAC status of the target process. (User Account Control) Usage: uac ''' t = db.trace u = t._getUacStatus() db.vprint('UAC Status: %s' % token_elevation_types.get(u))
[docs]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)) # The necissary module extension function
[docs]def vdbExtension(db, trace): db.registerCmdExtension(hookiat) db.registerCmdExtension(pe) db.registerCmdExtension(peb) db.registerCmdExtension(einfo) db.registerCmdExtension(heaps) db.registerCmdExtension(regkeys) db.registerCmdExtension(seh) db.registerCmdExtension(safeseh) db.registerCmdExtension(teb) db.registerCmdExtension(pagewatch) db.registerCmdExtension(stealth) db.registerCmdExtension(aslr) db.registerCmdExtension(hooks) db.registerCmdExtension(gflags) #db.registerCmdExtension(deaslr) db.registerCmdExtension(sympath) db.registerCmdExtension(jit) db.registerCmdExtension(svclist) #db.registerCmdExtension(stepb) db.registerCmdExtension(injectso) db.registerCmdExtension(uac)