def Create(self): title = "Switches" idaapi.simplecustviewer_t.Create(self, title) comment = idaapi.COLSTR("; Double-click to follow", idaapi.SCOLOR_BINPREF) self.AddLine(comment) #comment = idaapi.COLSTR("; Hover for preview", idaapi.SCOLOR_BINPREF) comment = "" self.AddLine(comment) for item in self.switches: addy = item[0] cases = item[1] interesting_calls = item[2] self.calls[addy] = interesting_calls address_element = idaapi.COLSTR("0x%08x: " % addy, idaapi.SCOLOR_REG) value_element = idaapi.COLSTR("%s" % cases, idaapi.SCOLOR_STRING) line = address_element + value_element self.AddLine(line) return True
def create_colored_line(self, n): # todo item = self.get_item(n) if item != None: typ = item.type width = self.payload.proc.get_pointer_size() cline = idaapi.COLSTR("%04X " % (n * width), idaapi.SCOLOR_AUTOCMT) ea = item.ea fmt = self.payload.proc.get_data_fmt_string() elem = fmt % ea if typ == Item.TYPE_CODE: color = idaapi.SCOLOR_CODNAME if SegStart( ea) != BADADDR else idaapi.SCOLOR_ERROR elem = idaapi.COLSTR(elem, color) else: elem = idaapi.COLSTR(elem, idaapi.SCOLOR_DNUM) cline += elem comm = "" if len(item.comment): comm += " ; %s" % item.comment if len(comm): cline += idaapi.COLSTR(comm, idaapi.SCOLOR_AUTOCMT) return cline
def as_id(self, s): t = s.lower() if t in self.register_list: return idaapi.COLSTR(s, idaapi.SCOLOR_REG) elif t in self.instruction_list: return idaapi.COLSTR(s, idaapi.SCOLOR_INSN) else: return s
def chunk_info(self, chunk_addr, chunk): line1 = idaapi.COLSTR("Chunk ", idaapi.SCOLOR_NUMBER) line2 = idaapi.COLSTR("0x%x\n\n" % (chunk_addr), idaapi.SCOLOR_INSN) line3 = idaapi.COLSTR( "size: 0x%x\nfd: 0x%x - %s" % ( chunk.size, chunk.fd, SegName(chunk.fd), ), SCOLOR_DEFAULT) return line1 + line2 + line3
def from_ExprCompose(self, expr): out = "{" out += ", ".join([ "%s, %s, %s" % (self.from_expr(subexpr), idaapi.COLSTR(str(idx), idaapi.SCOLOR_RPTCMT), idaapi.COLSTR(str(idx + subexpr.size), idaapi.SCOLOR_RPTCMT)) for idx, subexpr in expr.iter_args() ]) out += "}" return out
def color_irblock(irblock, ir_arch): out = [] lbl = idaapi.COLSTR("%s:" % ir_arch.loc_db.pretty_str(irblock.loc_key), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock: for dst, src in sorted(viewitems(assignblk)): dst_f = expr2colorstr(dst, loc_db=ir_arch.loc_db) src_f = expr2colorstr(src, loc_db=ir_arch.loc_db) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) out.append(' %s' % line) out.append("") out.pop() return "\n".join(out)
def bin_info(self, node_title, chunk_addr, chunk, with_size=True): line = idaapi.COLSTR("%s " % node_title, idaapi.SCOLOR_NUMBER) line += idaapi.COLSTR("0x%x\n\n" % chunk_addr, idaapi.SCOLOR_INSN) chunk_info = "" if with_size: chunk_info += "size: 0x%x\n" % chunk.size chunk_info += "fd: 0x%x - %s\nbk: 0x%x - %s" % ( chunk.fd, SegName(chunk.fd), chunk.bk, SegName(chunk.bk)) line += idaapi.COLSTR(chunk_info, SCOLOR_DEFAULT) return line
def updateDataWatch(self): print("in updateDataWatch") #self.Close() #self.Create() #print('did create') retval = [] self.ClearLines() #self.Refresh() print('did refresh of clear') command = '@cgc.getWatchMarks()' simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) if type(simicsString) is int: print('updateStackTrace got an int? %d' % simicsString) return if simicsString.startswith('None'): simicsString = simicsString[5:] try: data_json = json.loads(simicsString) except: print('could not get json from %s' % simicsString) return index = 0 for entry in data_json: instruct = idc.GetDisasm(entry['ip']) uline = '%3d 0x%08x 0x%08x %s' % (index, entry['ip'], entry['cycle'], entry['msg']) line = uline.encode('ascii', 'replace') #print('do %s' % line) if 'return from' in str(line): cline = idaapi.COLSTR(str(line), idaapi.SCOLOR_DREF) elif 'closed FD' in str(line): cline = idaapi.COLSTR(str(line), idaapi.SCOLOR_DREF) else: cline = str(line) #print("added %s" % line) retval.append(str(line)) self.AddLine(cline) index += 1 self.Refresh() command = '@cgc.nextWatchMark()' simicsString = gdbProt.Evalx('SendGDBMonitor("%s");' % command) try: index = int(simicsString) except: print('%s' % simicsString) return self.Jump(index) #self.Show() return retval
def on_refresh(self): """Callback function invoked when the graph needs to be refreshed.""" try: line = 0 nodes = dict() for block in self.ir: instructions_block = list() #if block.hasLabel(): # instructions_block.append("%s\n\n" % block.getLabel() #if self.ir.getBlockIndex(block) == 0: # instructions_block.append(self.generateFunctionOpening() #for stmt in block: for inst in block: inst_line = "" #if stmt.wasRemoved(): # continue #inst = stmt.get() #if isinstance(inst, GotoStatement): # continue str_address = "%08X:%03X" % (inst.address, line) str_address = \ idaapi.COLSTR(str_address, idaapi.SCOLOR_ASMDIR) str_inst = \ idaapi.COLSTR(str(inst), idaapi.SCOLOR_INSN) instructions_block.append("%(str_address)s %(str_inst)s" % vars()) line += 1 nodes[block] = self.add_node("\n".join(instructions_block)) for idx, bb in enumerate(self.ir): for succ in bb.successors(): node_a = nodes[bb] node_b = nodes[succ] #print "Adding %s ---> %s" % (node_a, node_b) self.add_edge(node_a, node_b) except Exception, err: if self.debug: print format_exc()
def from_ExprLoc(self, expr): if self.symbol_pool is not None: out = self.symbol_pool.str_loc_key(expr.loc_key) else: out = str(expr) out = idaapi.COLSTR(out, idaapi.SCOLOR_REG) return out
def make_fastbin_graph(self): fastbin_id = self.info['fastbin_id'] size = self.info['size'] fastbin = self.heap.get_fastbin_by_id(fastbin_id) if fastbin == 0: warning("Empty fastbin entry") return False line1 = idaapi.COLSTR("FASTBIN - 0x%02X" % size, idaapi.SCOLOR_ERROR) id_header = self.AddNode( (True, "fastbin[%x]" % size, "FASTBIN - 0x%02X" % size)) id_chunk = id_header chain, c_error = self.heap.chunk_chain(fastbin, stop=0, add_stop=False) for i, chunk_addr in enumerate(chain): chunk_info = self.heap.get_chunk(chunk_addr) prev_chunk = id_chunk id_chunk = self.AddNode((True, str(chunk_info), self.chunk_info(chunk_addr, chunk_info))) self.AddEdge(prev_chunk, id_chunk) if c_error: warn = self.warning_line( "[...] - List corrupted or infinite cycle detected") id_end = self.AddNode((True, "[...]", warn)) self.AddEdge(id_chunk, id_end) else: id_end = self.AddNode((True, "TAIL - 0", "TAIL")) self.AddEdge(id_chunk, id_end) return True
def ResetOutput(self): self.ClearLines() self.AddLine( idaapi.COLSTR( "Please press INS to enter command; X to clear output", idaapi.SCOLOR_AUTOCMT)) self.Refresh()
def color_irblock(irblock, ir_arch): out = [] lbl = idaapi.COLSTR(ir_arch.symbol_pool.str_loc_key(irblock.loc_key), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock: for dst, src in sorted(assignblk.iteritems()): dst_f = expr2colorstr(dst, symbol_pool=ir_arch.symbol_pool) src_f = expr2colorstr(src, symbol_pool=ir_arch.symbol_pool) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) out.append(' %s' % line) out.append("") out.pop() dst = str(' Dst: %s' % irblock.dst) dst = idaapi.COLSTR(dst, idaapi.SCOLOR_RPTCMT) out.append(dst) return "\n".join(out)
def from_ExprLoc(self, expr): if self.loc_db is not None: out = self.loc_db.pretty_str(expr.loc_key) else: out = str(expr) out = idaapi.COLSTR(out, idaapi.SCOLOR_REG) return out
def Create(self, sn=None, use_colors=True): # Form the title title = "Simple custom view test" if sn: title += " %d" % sn self.use_colors = use_colors # Create the customviewer if not simplecustviewer_t.Create(self, title): return False for i in xrange(0, 100): prefix, bg = idaapi.COLOR_DEFAULT, None # make every 10th line a bit special if i % 10 == 0: prefix = idaapi.COLOR_DNAME # i.e., dark yellow... bg = 0xFFFF00 # ...on cyan pfx = idaapi.COLSTR("%3d" % i, idaapi.SCOLOR_PREFIX) if self.use_colors: self.AddLine("%s: Line %d" % (pfx, i), fgcolor=prefix, bgcolor=bg) else: self.AddLine("%s: Line %d" % (pfx, i)) return True
def __init__(self, query, targets): idaapi.simplecustviewer_t.__init__(self) self.Create("BinaryAI - {}".format(query)) func = targets[0] for line in self.source_code_comment(query, func).split("\n"): self.AddLine(idaapi.COLSTR(line, idaapi.SCOLOR_RPTCMT)) for line in self.source_code_body(func): self.AddLine(str(line))
def get_disasm(ea, align=50): # GetDisasm() sometimes returns a few bytes from next instruction: # https://www.hex-rays.com/products/ida/support/idapython_docs/idc-module.html#GetDisasm asm = idc.GetDisasm(ea).split(';')[0] # Format the line to always be at least 'align' number of chars line = idaapi.add_spaces(asm, align) return idaapi.COLSTR(line, idaapi.SCOLOR_INSN)
def color_irblock(irblock, ir_arch): out = [] lbl = idaapi.COLSTR(str(irblock.label), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock.irs: for dst, src in sorted(assignblk.iteritems()): dst_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, dst) src_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, src) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) out.append(' %s' % line) out.append("") out.pop() dst = str(' Dst: %s' % irblock.dst) dst = idaapi.COLSTR(dst, idaapi.SCOLOR_RPTCMT) out.append(dst) return "\n".join(out)
def _repaint(self): self.ClearLines() func = self.targets[self.idx] for line in SourceCodeViewer.source_code_comment(self.query, func, self.idx).split("\n"): self.AddLine(idaapi.COLSTR(line, idaapi.SCOLOR_RPTCMT)) for line in SourceCodeViewer.source_code_body(func): self.AddLine(str(line)) self.Refresh()
def getText(self, addy): #print "Fetching text for %08x" % addy color = idaapi.SCOLOR_STRING if addy == function.top(addy): name = idc.NameEx(addy, addy) try: name = idc.Demangle(name, idc.GetLongPrm(idc.INF_SHORT_DN)) except: pass else: name = idc.NameEx(addy, addy) if name: return idaapi.COLSTR(" %s " % name, color) else: return idaapi.COLSTR(" 0x%08x " % addy, color)
def Create(self): title = "Hit Functions" idaapi.simplecustviewer_t.Create(self, title) comment = idaapi.COLSTR("#### Double-click to follow ####", idaapi.SCOLOR_BINPREF) self.AddLine(comment) self.AddLine("") for s in self.hitfuncs: line = idaapi.COLSTR("%s:" % s['name'], idaapi.SCOLOR_BINPREF) self.AddLine(line) for addr in s['src']: line = idaapi.COLSTR(" %s" % addr, idaapi.SCOLOR_INSN) self.AddLine(line) self.AddLine("") return True
def OnKeydown(self, vkey, shift): """ User pressed a key @param vkey: Virtual key code @param shift: Shift flag @return: Boolean. True if you handled the event """ print "OnKeydown, vk=%d shift=%d" % (vkey, shift) # ESCAPE? if vkey == 27: self.Close() # VK_DELETE elif vkey == 46: n = self.GetLineNo() if n is not None: self.DelLine(n) self.Refresh() print "Deleted line %d" % n # Goto? elif vkey == ord('G'): n = self.GetLineNo() if n is not None: v = idaapi.ask_long(self.GetLineNo(), "Where to go?") if v: self.Jump(v, 0, 5) elif vkey == ord('R'): print "refreshing...." self.Refresh() elif vkey == ord('C'): print "refreshing current line..." self.RefreshCurrent() elif vkey == ord('A'): s = idaapi.ask_str("NewLine%d" % self.Count(), 0, "Append new line") self.AddLine(s) self.Refresh() elif vkey == ord('X'): print "Clearing all lines" self.ClearLines() self.Refresh() elif vkey == ord('I'): n = self.GetLineNo() s = idaapi.ask_str("InsertedLine%d" % n, 0, "Insert new line") self.InsertLine(n, s) self.Refresh() elif vkey == ord('E'): l = self.GetCurrentLine(notags=1) if not l: return False n = self.GetLineNo() print "curline=<%s>" % l l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP) self.EditLine(n, l) self.RefreshCurrent() print "Edited line %d" % n else: return False return True
def OnGetText(self, id): block = self.idmap[id] stmts = block.container[:] if len(stmts) == 0: return '' if type(stmts[-1]) == goto_t: stmts.pop(-1) if type(stmts[-1]) == if_t: _if = stmts.pop(-1) s = '\n'.join([idaapi.COLSTR(str(stmt), idaapi.SCOLOR_KEYWORD) for stmt in stmts]) if len(stmts) > 0: s += '\n' return s + idaapi.COLSTR('if(' + str(_if.expr) + ')', idaapi.SCOLOR_KEYWORD) return '\n'.join([idaapi.COLSTR(str(stmt), idaapi.SCOLOR_KEYWORD) for stmt in stmts])
def IssueCommand(self): s = idaapi.askstr(0, self.last_cmd, "Please enter a debugger command") if not s: return # Save last command self.last_cmd = s # Add it using a different color self.AddLine("debugger>" + idaapi.COLSTR(s, idaapi.SCOLOR_VOIDOP)) try: r = SendDbgCommand(s).split("\n") for s in r: self.AddLine(idaapi.COLSTR(s, idaapi.SCOLOR_LIBNAME)) except: self.AddLine(idaapi.COLSTR("Debugger is not active or does not export SendDbgCommand()", idaapi.SCOLOR_ERROR)) self.Refresh()
def get_colored_line (self, n): # todo typ = self.get_type (n) cline = idaapi.COLSTR("%03X " % (n*4), idaapi.SCOLOR_AUTOCMT) val = self.get_value (n) elem = "%08X" % val if typ: elem = idaapi.COLSTR(elem, idaapi.SCOLOR_CODNAME) else: elem = idaapi.COLSTR(elem, idaapi.SCOLOR_DNUM) cline += elem comm = "" if SegStart (val) != BADADDR: # TODO: add DEP/ASLR status? comm = " ; %s %s" % (SegName (val), self.comment[n]) elif self.comment[n] != "": comm = " ; %s" % self.comment[n] cline += idaapi.COLSTR (comm, idaapi.SCOLOR_AUTOCMT) return cline
def expr2colorstr(regs_ids, expr): """Colorize an Expr instance for IDA @regs_ids: list of ExprId corresponding to available registers @expr: Expr instance to colorize """ if isinstance(expr, m2_expr.ExprId): s = str(expr) if expr in regs_ids: s = idaapi.COLSTR(s, idaapi.SCOLOR_REG) elif isinstance(expr, m2_expr.ExprInt): s = str(expr) s = idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER) elif isinstance(expr, m2_expr.ExprMem): s = '%s[%s]' % (idaapi.COLSTR( '@' + str(expr.size), idaapi.SCOLOR_RPTCMT), expr2colorstr(regs_ids, expr.arg)) elif isinstance(expr, m2_expr.ExprOp): out = [] for a in expr.args: s = expr2colorstr(regs_ids, a) if isinstance(a, m2_expr.ExprOp): s = "(%s)" % s out.append(s) if len(out) == 1: s = "%s %s" % (expr.op, str(out[0])) else: s = (" " + expr.op + " ").join(out) elif isinstance(expr, m2_expr.ExprAff): s = "%s = %s" % (expr2colorstr( regs_ids, expr.dst), expr2colorstr(regs_ids, expr.src)) elif isinstance(expr, m2_expr.ExprCond): cond = expr2colorstr(regs_ids, expr.cond) src1 = expr2colorstr(regs_ids, expr.src1) src2 = expr2colorstr(regs_ids, expr.src2) s = "(%s?%s:%s)" % (cond, src1, src2) elif isinstance(expr, m2_expr.ExprSlice): s = "(%s)[%s:%s]" % ( expr2colorstr(regs_ids, expr.arg), idaapi.COLSTR(str(expr.start), idaapi.SCOLOR_RPTCMT), idaapi.COLSTR(str(expr.stop), idaapi.SCOLOR_RPTCMT)) elif isinstance(expr, m2_expr.ExprCompose): s = "{" s += ", ".join([ "%s, %s, %s" % (expr2colorstr(regs_ids, subexpr), idaapi.COLSTR(str(idx), idaapi.SCOLOR_RPTCMT), idaapi.COLSTR(str(idx + expr.size), idaapi.SCOLOR_RPTCMT)) for idx, subexpr in expr.iter_args() ]) s += "}" else: s = str(expr) return s
def get_disasm(self, ea): disasm = [] insns = self.get_disasm_internal(ea) for i in insns: if i != None: ea,ins,line,isret,strm = i strm = to_hex_str(strm) if isret: color = idaapi.SCOLOR_CREFTAIL else: color = idaapi.SCOLOR_CODNAME asm = idaapi.COLSTR("%s\n" % line, color) data = idaapi.COLSTR("%s\n" % strm, color) else: asm = idaapi.COLSTR("; invalid instruction \n", idaapi.SCOLOR_HIDNAME) data = "" disasm.append((asm, data)) if len(disasm) == self.get_max_insn(): cont = idaapi.COLSTR("...", idaapi.SCOLOR_HIDNAME) disasm.append((cont, cont)) return disasm
def OnHint (self, lineno): global ph if not ph.get_type (lineno): return None ea = ph.get_value (lineno) g = Gadget () dis = g.get_disasm (ea) hint = "" for l in dis: hint += idaapi.COLSTR ("%s\n" % l, idaapi.SCOLOR_CODNAME) return (len (dis), hint)
def update_content_viewers(self, n=None): if n is None: n = self.GetLineNo() item = self.get_item(n) self.dav.clear() self.hv.clear() self.iv.clear() if item is not None: if item.type == Item.TYPE_CODE: # get disassembly and hex stream dis = self.payload.da.get_disasm(item.ea) for line in dis: self.dav.add_line(line[0]) self.hv.add_line(line[1]) # get various info seg = idaapi.getseg(item.ea) if seg: name = idaapi.get_true_segm_name(seg) perm = seg.perm ltype = "ld" if seg.is_loader_segm() else "dbg" ea_start = seg.startEA ea_end = seg.endEA perms = "" perms += "R" if perm & idaapi.SEGPERM_READ != 0 else "." perms += "W" if perm & idaapi.SEGPERM_WRITE != 0 else "." perms += "X" if perm & idaapi.SEGPERM_EXEC != 0 else "." self.iv.add_line("<%s> [%X - %X], %s, [%s]" % (name, ea_start, ea_end, ltype, perms)) else: stype = GetStringType(item.ea) if stype is not None: scontent = GetString(item.ea, -1, stype) if scontent != None and len(scontent): self.dav.add_line( idaapi.COLSTR("\"%s\"" % scontent, idaapi.SCOLOR_DSTR)) # length = idaapi.get_max_ascii_length(item.ea, stype, idaapi.ALOPT_IGNHEADS) # self.hv.add_line() else: scontent = GetString(item.ea, -1, ASCSTR_C) if scontent != None and len(scontent): self.dav.add_line("\"%s\"" % scontent) self.dav.update() self.hv.update() self.iv.update()
def make_fastbin_graph(self): fastbin_id, size = self.info['fastbin_id'], self.info['size'] fastbin = self.heap.get_fastbin_by_id(fastbin_id) address = [fastbin] line1 = idaapi.COLSTR("FASTBIN - 0x%02X" % size, idaapi.SCOLOR_ERROR) id_header = self.AddNode( (True, "fastbin[%x]" % size, "FASTBIN - 0x%02X" % size)) chunk = self.heap.get_chunk(fastbin) id_parent = self.AddNode( (True, str(chunk), self.chunk_info(fastbin, chunk))) self.AddEdge(id_header, id_parent) breaked = False id_chunk = None while chunk.fd != 0: fastbin_ea = chunk.fd # current chunk if address.count(fastbin_ea) >= 2: breaked = True break address.append(fastbin_ea) chunk = self.heap.get_chunk(chunk.fd) id_chunk = self.AddNode( (True, str(chunk), self.chunk_info(fastbin_ea, chunk))) self.AddEdge(id_parent, id_chunk) id_parent = id_chunk if breaked: warn = self.warning_line( "[...] - List corrupted or infinite cycle detected") id_end = self.AddNode((True, "[...]", warn)) self.AddEdge(id_parent, id_end) else: id_end = self.AddNode((True, "TAIL - 0", "TAIL")) self.AddEdge(id_parent, id_end) return True