def do_maps(self, line): """ Display either a list of all the memory maps or the memory map details for the given address expression. Usage: maps [addr_expression] """ argv = splitargs(line) if len(argv): expr = " ".join(argv) va = self.parseExpression(expr) map = self.memobj.getMemoryMap(va) if map == None: self.vprint("Memory Map Not Found For: 0x%.8x" % va) else: addr, size, perm, fname = map pname = e_mem.reprPerms(perm) self.canvas.addText("Memory Map For: ") self.canvas.addVaText("0x%.8x" % va, va) self.canvas.addText("\n") self.canvas.addVaText("0x%.8x" % addr, addr) self.canvas.addText("\t%d\t%s\t%s\n" % (size, pname, fname)) else: totsize = 0 self.vprint("[ address ] [ size ] [ perms ] [ File ]") for addr, size, perm, fname in self.memobj.getMemoryMaps(): pname = e_mem.reprPerms(perm) totsize += size self.canvas.addVaText("0x%.8x" % addr, addr) sizestr = ("%dK" % (size / 1024,)).rjust(8) self.canvas.addText("%s\t%s\t%s\n" % (sizestr, pname, fname)) self.vprint("Total Virtual Memory: %.2f MB" % ((float(totsize) / 1024) / 1024))
def do_maps(self, line): """ Display either a list of all the memory maps or the memory map details for the given address expression. Usage: maps [addr_expression] """ argv = splitargs(line) if len(argv): expr = " ".join(argv) va = self.parseExpression(expr) map = self.memobj.getMemoryMap(va) if map == None: self.vprint("Memory Map Not Found For: 0x%.8x"%va) else: addr,size,perm,fname = map pname = e_mem.reprPerms(perm) self.canvas.addText("Memory Map For: ") self.canvas.addVaText("0x%.8x" % va, va) self.canvas.addText("\n") self.canvas.addVaText("0x%.8x" % addr, addr) self.canvas.addText("\t%d\t%s\t%s\n" % (size,pname,fname)) else: totsize = 0 self.vprint("[ address ] [ size ] [ perms ] [ File ]") for addr,size,perm,fname in self.memobj.getMemoryMaps(): pname = e_mem.reprPerms(perm) totsize += size self.canvas.addVaText("0x%.8x" % addr, addr) sizestr = ("%dK" % (size/1024,)).rjust(8) self.canvas.addText("%s\t%s\t%s\n" % (sizestr,pname,fname)) self.vprint("Total Virtual Memory: %.2f MB" % ((float(totsize)/1024)/1024))
def vqLoad(self): model = vq_tree.VQTreeModel(parent=self.parent, columns=self.cols) for mva, msize, mperm, mfile in self.mem.getMemoryMaps(): pstr = e_mem.reprPerms(mperm) model.append(('0x%.8x' % mva, msize, pstr, mfile)) self.setModel(model)
def vwLoad(self): if self.traceIsReady(): self.vwClear() maps = self.trace.getMemoryMaps() for base,size,perms,fname in maps: pname = e_mem.reprPerms(perms) self.model.append((base, "0x%.8x" % base, size, pname, fname))
def vwLoad(self): if self.traceIsReady(): self.vwClear() maps = self.trace.getMemoryMaps() for base, size, perms, fname in maps: pname = e_mem.reprPerms(perms) self.model.append((base, "0x%.8x" % base, size, pname, fname))
def render(self, mcanv, va): trace = mcanv.mem max_readable = trace.getMaxReadSize(va) if max_readable <= 0: return '' rsize = min(self.readsize, max_readable) bytez = trace.readMemory(va, rsize) prettyperm = '' mmap = trace.getMemoryMap(va) if mmap is not None: addr, size, perm, fname = mmap prettyperm = e_mem.reprPerms(perm) ascii_text = getAsciiFormatted(bytez) uni_text = getBasicUnicodeFormatted(bytez) sym = getSymByAddrFormatted(trace, va) fname = getFilenameFromFdFormatted(trace, va) desc = '' pdesc = (ascii_text, uni_text, sym, fname) items = [ppdesc for ppdesc in pdesc if ppdesc != None] if len(items) == 1: desc = items[0] elif len(items) == 0: # if none match, just return the bytes. desc = bytez.encode('hex') elif len(items) > 1: # we only really expect one or none of these to match. desc = 'Error, multiple matches for this address!' else: raise Exception('should never get here') best_desc = '%s %s' % (prettyperm, desc) chopped_best_desc = best_desc[:self.maxrend] if len(best_desc) > len(chopped_best_desc): mcanv.addText(' %s...' % chopped_best_desc) else: mcanv.addText(' %s' % chopped_best_desc) return len(chopped_best_desc)
def render(self, mcanv, va): trace = mcanv.mem max_readable = trace.getMaxReadSize(va) if max_readable <= 0: return '' rsize = min(self.readsize, max_readable) bytez = trace.readMemory(va, rsize) prettyperm = '' mmap = trace.getMemoryMap(va) if mmap != None: addr, size, perm, fname = mmap prettyperm = e_mem.reprPerms(perm) ascii_text = getAsciiFormatted(bytez) uni_text = getBasicUnicodeFormatted(bytez) sym = getSymByAddrFormatted(trace, va) fname = getFilenameFromFdFormatted(trace, va) desc = '' pdesc = (ascii_text, uni_text, sym, fname) items = [ppdesc for ppdesc in pdesc if ppdesc != None] if len(items) == 1: desc = items[0] elif len(items) == 0: # if none match, just return the bytes. desc = bytez.encode('hex') elif len(items) > 1: # we only really expect one or none of these to match. desc = 'Error, multiple matches for this address!' else: raise Exception('should never get here') best_desc = '%s %s' % (prettyperm, desc) chopped_best_desc = best_desc[:self.maxrend] if len(best_desc) > len(chopped_best_desc): mcanv.addText(' %s...' % chopped_best_desc) else: mcanv.addText(' %s' % chopped_best_desc) return len(chopped_best_desc)
def do_maps_filter(self, line): """ Display either a list of all the memory maps or the memory map details for the given address expression. Usage: maps [addr_expression] """ argv = "" if len(line) > 0: argv = line.strip() print "Line", line totsize = 0 self.vprint("[ address ] [ size ] [ perms ] [ File ]") for addr,size,perm,fname in self.memobj.getMemoryMaps(): pname = e_mem.reprPerms(perm) totsize += size sizestr = ("%dK" % (size/1024,)).rjust(8) output_str = "%s\t%s\t%s\n" % (sizestr,pname,fname) if output_str.find(argv) == -1: continue self.canvas.addVaText("0x%.8x" % addr, addr) self.canvas.addText("%s\t%s\t%s\n" % (sizestr,pname,fname)) self.vprint("Total Virtual Memory: %s MB" % ((totsize/1024)/1024))
def do_maps_filter(self, line): """ Display either a list of all the memory maps or the memory map details for the given address expression. Usage: maps [addr_expression] """ argv = "" if len(line) > 0: argv = line.strip() print "Line", line totsize = 0 self.vprint("[ address ] [ size ] [ perms ] [ File ]") for addr, size, perm, fname in self.memobj.getMemoryMaps(): pname = e_mem.reprPerms(perm) totsize += size sizestr = ("%dK" % (size / 1024, )).rjust(8) output_str = "%s\t%s\t%s\n" % (sizestr, pname, fname) if output_str.find(argv) == -1: continue self.canvas.addVaText("0x%.8x" % addr, addr) self.canvas.addText("%s\t%s\t%s\n" % (sizestr, pname, fname)) self.vprint("Total Virtual Memory: %s MB" % ((totsize / 1024) / 1024))
self.canvas.addVaText('0x%.8x' % addr, addr) self.canvas.addText(' for %d bytes\n' % size) res = self.memobj.searchMemoryRange(pattern, addr, size, regex=options.is_regex) else: self.vprint('searching all memory...') res = self.memobj.searchMemory(pattern, regex=options.is_regex) if len(res) == 0: self.vprint('pattern not found: %s (%s)' % (pattern.encode('hex'), repr(pattern))) return brend = e_render.ByteRend() self.vprint('matches for: %s (%s)' % (pattern.encode('hex'), repr(pattern))) for va in res: mbase,msize,mperm,mfile = self.memobj.getMemoryMap(va) pname = e_mem.reprPerms(mperm) sname = self.reprPointer(va) self.canvas.addVaText('0x%.8x' % va, va) self.canvas.addText(': ') self.canvas.addText('%s ' % pname) self.canvas.addText(sname) if options.num_context_bytes != None: self.canvas.addText('\n') self.canvas.renderMemory(va, options.num_context_bytes, rend=brend) self.canvas.addText('\n') self.vprint('done (%d results).' % len(res))
def do_search(self, line): """ search memory for patterns. search [options] <pattern> -e <codec> encode the pattern with a codec (hex, utf-16le, etc) -X pattern is in hex (ie. 41414242 is AABB) -E pattern is an envi memory expression (numeric search) -r pattern is a regular expression -R <baseexpr:sizeexpr> search a range of memory (base + size) -c show context (32 bytes) after each hit """ parser = VOptionParser() parser.add_option('-e', action='store', dest='encode_as') parser.add_option('-X', action='store_true', dest='is_hex') parser.add_option('-E', action='store_true', dest='is_expr') parser.add_option('-r', action='store_true', dest='is_regex') parser.add_option('-R', action='store', dest='range_search') parser.add_option('-c', action='store_const', dest='num_context_bytes', const=32) argv = shlex.split(line) try: options, args = parser.parse_args(argv) except Exception as e: self.vprint(repr(e)) return self.do_help('search') pattern = ' '.join(args) if len(pattern) == 0: self.vprint('you must specify a pattern') return self.do_help('search') if options.is_expr: import struct # FIXME see below sval = self.parseExpression(pattern) pattern = struct.pack('<L', sval) # FIXME 64bit (and alt arch) if options.is_hex: pattern = pattern.decode('hex') if options.encode_as is not None: pattern = pattern.encode(options.encode_as) if options.range_search: try: addrexpr, sizeexpr = options.range_search.split(":") except Exception as e: self.vprint(repr(e)) return self.do_help('search') addr = self.parseExpression(addrexpr) size = self.parseExpression(sizeexpr) self.canvas.addText('searching from ') self.canvas.addVaText('0x%.8x' % addr, addr) self.canvas.addText(' for %d bytes\n' % size) res = self.memobj.searchMemoryRange(pattern, addr, size, regex=options.is_regex) else: self.vprint('searching all memory...') res = self.memobj.searchMemory(pattern, regex=options.is_regex) if len(res) == 0: self.vprint('pattern not found: %s (%s)' % (pattern.encode('hex'), repr(pattern))) return brend = e_render.ByteRend() self.vprint('matches for: %s (%s)' % (pattern.encode('hex'), repr(pattern))) for va in res: mbase, msize, mperm, mfile = self.memobj.getMemoryMap(va) pname = e_mem.reprPerms(mperm) sname = self.reprPointer(va) self.canvas.addVaText('0x%.8x' % va, va) self.canvas.addText(': ') self.canvas.addText('%s ' % pname) self.canvas.addText(sname) if options.num_context_bytes is not None: self.canvas.addText('\n') self.canvas.renderMemory(va, options.num_context_bytes, rend=brend) self.canvas.addText('\n') self.vprint('done (%d results).' % len(res))
def vqLoad(self): model = self.model() for mva, msize, mperm, mfile in self.mem.getMemoryMaps(): pstr = e_mem.reprPerms(mperm) model.append(('0x%.8x' % mva, msize, pstr, mfile)) self.setModel(model)
self.vprint(''.join(traceback.format_exception(*sys.exc_info()))) if len(res) == 0: self.vprint('pattern not found: %s (%s)' % (pattern.encode('hex'), repr(pattern))) return # set the color for each finding color = options.markColor colormap = { va : color for va in res } if self._viv_gui != None: vqtevent('viv:colormap', colormap) self.vprint('matches for: %s (%s)' % (pattern.encode('hex'), repr(pattern))) for va in res: mbase,msize,mperm,mfile = self.memobj.getMemoryMap(va) pname = e_mem.reprPerms(mperm) sname = self.reprPointer(va) op = self.parseOpcode(va) self.canvas.renderMemory(va, len(op)) cmt = self.getComment(va) if cmt != None: self.canvas.addText('\t\t; %s' % cmt) self.canvas.addText('\n') self.vprint('done (%d results).' % len(res)) def do_imports(self, line): """ Show the imports in the workspace (or potentially just one file)
def render(self, mcanv, va): vastr = self.arch.pointerString(va) # NOTE: we assume the memobj is a trace trace = mcanv.mem p = trace.readMemoryFormat(va, 'P')[0] isptr = trace.isValidPointer(p) pstr = self.arch.pointerString(p) vareg = "" preg = "" regs = trace.getRegisters() for name,val in regs.items(): if val == 0: continue if val == va: vareg = "(%s)" % name if val == p: preg = "(%s)" % name bt = trace.getStackTrace() if len(bt) > 1: for i in range(1, len(bt)): spc, sfc = bt[i] if sfc == 0: break if spc == 0: break if va == spc: vareg = "(savepc)" if va == sfc: vareg = "(frame%d)" % i if p == spc: preg = "(savepc)" if p == sfc: preg = "(frame%d)" % i vareg = vareg.ljust(8) preg = preg.ljust(8) #sym = trace.getSymByAddr(va) #if sym != None: #pstr = repr(sym) mcanv.addVaText(vastr, va=va) mcanv.addText(" %s: " % vareg) if isptr: mcanv.addVaText(pstr, p) else: mcanv.addText(pstr) mcanv.addText(preg) if isptr: try: addr,size,perm,fname = trace.getMemoryMap(p) pname = e_mem.reprPerms(perm) mcanv.addText(" ") mcanv.addNameText(pname) mcanv.addText(" ") bytes = trace.readMemory(p, 32) if self.isAscii(bytes): mcanv.addText("'%s'" % bytes.split("\x00")[0]) elif self.isBasicUnicode(bytes): s = bytes.split("\x00\x00")[0].replace("\x00","") mcanv.addText("u'%s'" % s) else: mcanv.addText(bytes.encode('hex')) except Exception, e: mcanv.addText("ERROR: %s" % e)
def do_searchopcodes(self, line): ''' search opcodes/function for a pattern searchopcodes [-f <funcva>] [options] <pattern> -f [fva] - focus on one function -c - search comments -o - search operands -t - search text -M <color> - mark opcodes (default = orange) -R - pattern is REGEX (otherwise just text) ''' parser = e_cli.VOptionParser() parser.add_option('-f', action='store', dest='funcva', type='int') parser.add_option('-c', action='store_true', dest='searchComments') parser.add_option('-o', action='store_true', dest='searchOperands') parser.add_option('-t', action='store_true', dest='searchText') parser.add_option('-M', action='store', dest='markColor', default='orange') parser.add_option('-R', action='store_true', dest='is_regex') argv = shlex.split(line) try: options, args = parser.parse_args(argv) except Exception as e: self.vprint(repr(e)) return self.do_help('searchopcodes') pattern = ' '.join(args) if len(pattern) == 0: self.vprint('you must specify a pattern') return self.do_help('searchopcodes') # generate our interesting va list valist = [] if options.funcva: # setup valist from function data try: fva = options.funcva graph = viv_graph.buildFunctionGraph(self, fva) except Exception as e: self.vprint(repr(e)) return for nva, node in graph.getNodes(): va = nva endva = va + node.get('cbsize') while va < endva: lva, lsz, ltype, ltinfo = self.getLocation(va) valist.append(va) va += lsz else: # the whole workspace is our oyster valist = [ va for va, lvsz, ltype, ltinfo in self.getLocations(LOC_OP) ] res = [] canv = e_canvas.StringMemoryCanvas(self) defaultSearchAll = True for va in valist: try: addthis = False op = self.parseOpcode(va) # search comment if options.searchComments: defaultSearchAll = False cmt = self.getComment(va) if cmt is not None: if options.is_regex: if len(re.findall(pattern, cmt)): addthis = True else: if pattern in cmt: addthis = True # search operands if options.searchOperands: defaultSearchAll = False for opidx, oper in enumerate(op.opers): # we're writing to a temp canvas, so clear it before each test canv.clearCanvas() oper = op.opers[opidx] oper.render(canv, op, opidx) operepr = canv.strval if options.is_regex: if len(re.findall(pattern, operepr)): addthis = True else: if pattern in operepr: addthis = True # if we're doing non-regex, let's test against real numbers # (instead of converting to hex and back) numpattrn = pattern try: numpattrn = int(numpattrn, 0) except: pass if numpattrn in vars(oper).values(): addthis = True # search full text if options.searchText or defaultSearchAll: # search through the rendering of the opcode, as well as the comment canv.clearCanvas() op.render(canv) oprepr = canv.strval cmt = self.getComment(va) if cmt is not None: oprepr += " ; " + cmt if options.is_regex: if len(re.findall(pattern, oprepr)): addthis = True else: if pattern in oprepr: addthis = True # only want one listing of each va, no matter how many times it matches if addthis: res.append(va) except: self.vprint(''.join( traceback.format_exception(*sys.exc_info()))) if len(res) == 0: self.vprint('pattern not found: %s (%s)' % (pattern.encode('utf-8').hex(), repr(pattern))) return # set the color for each finding color = options.markColor colormap = {va: color for va in res} if self._viv_gui is not None: from vqt.main import vqtevent vqtevent('viv:colormap', colormap) self.vprint('matches for: %s (%s)' % (pattern.encode('utf-8').hex(), repr(pattern))) for va in res: mbase, msize, mperm, mfile = self.memobj.getMemoryMap(va) pname = e_memory.reprPerms(mperm) sname = self.reprPointer(va) op = self.parseOpcode(va) self.canvas.renderMemory(va, len(op)) cmt = self.getComment(va) if cmt is not None: self.canvas.addText('\t\t; %s (Perms: %s, Smartname: %s)' % (cmt, pname, sname)) self.canvas.addText('\n') self.vprint('done (%d results).' % len(res))
def do_search(self, line): ''' search memory for patterns. search [options] <pattern> -e <codec> encode the pattern with a codec (hex, utf-16le, etc) -X pattern is in hex (ie. 41414242 is AABB) -E pattern is an envi memory expression (numeric search) -r pattern is a regular expression -R <baseexpr:sizeexpr> search a range of memory (base + size) -c show context (32 bytes) after each hit ''' parser = VOptionParser() parser.add_option('-e', action='store', dest='encode_as') parser.add_option('-X', action='store_true', dest='is_hex') parser.add_option('-E', action='store_true', dest='is_expr') parser.add_option('-r', action='store_true', dest='is_regex') parser.add_option('-R', action='store', dest='range_search') parser.add_option('-c', action='store_const', dest='num_context_bytes', const=32) argv = shlex.split(line) try: options, args = parser.parse_args(argv) except Exception as e: self.vprint(repr(e)) return self.do_help('search') pattern = ' '.join(args) if len(pattern) == 0: self.vprint('you must specify a pattern') return self.do_help('search') if options.is_expr: import struct #FIXME see below sval = self.parseExpression(pattern) pattern = struct.pack('<L', sval) # FIXME 64bit (and alt arch) if options.is_hex: pattern = binascii.unhexlify(pattern) if options.encode_as is not None: if options.encode_as == 'hex': pattern = binascii.hexlify(patter) else: pattern = pattern.encode(options.encode_as) if options.range_search: try: addrexpr, sizeexpr = options.range_search.split(":") except Exception as e: self.vprint(repr(e)) return self.do_help('search') addr = self.parseExpression(addrexpr) size = self.parseExpression(sizeexpr) self.canvas.addText('searching from ') self.canvas.addVaText('0x%.8x' % addr, addr) self.canvas.addText(' for %d bytes\n' % size) res = self.memobj.searchMemoryRange(pattern, addr, size, regex=options.is_regex) else: self.vprint('searching all memory...') res = self.memobj.searchMemory(pattern, regex=options.is_regex) if len(res) == 0: self.vprint('pattern not found: %s (%s)' % (binascii.hexlify(pattern), repr(pattern))) return brend = e_render.ByteRend() self.vprint('matches for: %s (%s)' % (binascii.hexlify(pattern), repr(pattern))) for va in res: mbase, msize, mperm, mfile = self.memobj.getMemoryMap(va) pname = e_mem.reprPerms(mperm) sname = self.reprPointer(va) self.canvas.addVaText('0x%.8x' % va, va) self.canvas.addText(': ') self.canvas.addText('%s ' % pname) self.canvas.addText(sname) if options.num_context_bytes is not None: self.canvas.addText('\n') self.canvas.renderMemory(va, options.num_context_bytes, rend=brend) self.canvas.addText('\n') self.vprint('done (%d results).' % len(res))