def init(self): if not _G['inited']: if hasattr(Config, "debug") and Config.debug: Logger.setVerbose(True) HexraysPlugin() UpdateTypeAction("Ctrl-Shift-U").register().addMenu() RenameTypeAction().register().addMenu() SubclassTypeAction().register().addMenu() MapInterfacesAction("Ctrl-Shift-I").register().addMenu() ExploreAction("Ctrl-Shift-E").register().addMenu() ExportTypesAction().register().addMenu() TestAction("Ctrl-Shift-]").register().addMenu() IDAAction('Reload', "Ctrl-Shift-R").setProc( self.reload).register().addMenu() IDAAction('Verbose').setProc(self.verbose).register().addMenu() IDAAction('About').setProc(self.version).register().addMenu() _G['inited'] = True doc = os.path.split(idc.GetIdbPath())[1].split('.')[0] inits = ["ida_init", "ida_init_" + doc.lower()] for y in inits: if not hasattr(Config, y): continue for x in getattr(Config, y).split(';'): x = x.strip() Logger.debug("initcmd: %s", x) try: exec(x, globals()) except Exception as e: print "Error running init cmd", x, ":", str(e) return idaapi.PLUGIN_KEEP
def syncEnums(jsonFile, **kwargs): if not jsonFile: jsonFile = os.path.join(pyout.mypath("doc"), "mapienums.json") with open(jsonFile, "r") as f: enums = json.load(f) for ename in enums: Logger.debug("Sync enum %s", ename) e = Enum(ename.encode('ascii'), True) e.clear() masks = {} for nm, val in enums[ename].iteritems(): nm = nm.encode('ascii') if isinstance(val, (str, unicode)): val = eval(val) if nm.endswith('_MASK_'): masks[val] = nm e.setBitfield() for nm, val in enums[ename].iteritems(): nm = nm.encode('ascii') if isinstance(val, (str, unicode)): val = eval(val) if not nm.endswith('_MASK_'): msk = [m for m in masks.keys() if val & m == val] msk = msk[0] if len(msk) > 0 else None if len(masks) > 0 and not msk: msk = val e.setMember(nm, val, msk) for x in masks: e.setBMask(x, masks[x])
def update(self, **kwargs): tp = self.currentType(self.CHECK_VTBL, **kwargs) tp = self.checkVtblStruct(tp) Logger.debug("Updating class %s", str(tp)) ea = tp['vtblea'] nm = None funcs = [] while (not nm): ofs = idc.Qword(ea) if not ofs or ofs == idc.BADADDR: break func = FuncDescr.fromEA(ofs) if self.untouchedFunc(func.name): func.checkThis(tp['name'] + '*') Logger.debug("found vtbl function: %s", str(func)) name = func.name i = 2 while name in funcs: name = func.name + "_" + str(i) i += 1 self.setStrucPntr(tp['vtblid'], ea - tp['vtblea'], name, func.buildType(True)) funcs += [name] ea += 8 nm = idc.Name(ea)
def checkFunc(self, ea, **kwargs): usage = kwargs.get('usage') or False fn = idc.GetFunctionName(ea) try: func = idaapi.decompile(ea) if not func: return None except Exception as e: Logger.error("Error decompiling " + fn + ": " + str(e)) return None vrs = [] for v in func.lvars: t = v.type().dstr() if self.stname in t: vrs += [v.name + ("->" if '*' in t else '.') + self.fname] #Logger.debug("Checking function %s %s", fn, str(vrs)) ret = [] for i, x in enumerate(str(func).split("\n")): for y in vrs: if y not in x: continue x = x.strip() if not usage: p = x.find(y) if p != 0 or '=' not in x: continue ret += [{ 'address': fn + " : " + str(i), 'code': x, }] return ret
def __init__(self): Logger.debug("Creating") self.lastObj = None self.lastExpr = None self.installed = False self.safe = False if idaapi.init_hexrays_plugin(): if idaapi.install_hexrays_callback(self.callback): self.installed = True
def updateNames(self): upd = [] print "updating names" for n, v in self.getOids().iteritems(): if v != n: continue upd += [n] Logger.debug("Updating oids %s", str(upd)) for x in upd: nm = self.getName(x) if nm: Logger.debug("%s = %s", x, nm) self.oids[x] = nm self.changed = True self.save()
def info(self, addr): v = [ pluginsdk.ReadDword(addr), pluginsdk.ReadWord(addr + 4), pluginsdk.ReadWord(addr + 6), [] ] addr += 8 for i in range(8): v[3] += [pluginsdk.ReadByte(addr)] addr += 1 h = GuidHelper() g = h.guidOfVals(v) info = h.findGuid(g) if not info: Logger.info("Guid %s not found", str(g)) else: Logger.info(str(info))
def run(self, **kwargs): obj = None if self.what in self.REGS: obj = [{ 'name': self.what, 'res': self.what, 'val': idc.GetRegValue(self.what), 'type': kwargs.get('type') }] else: if (self.what): obj = self.findNamedVar(self.what.split('->'), **kwargs) if not obj: return None obj = self.getVar(obj, **kwargs) Logger.debug("explorering object %s", str(obj)) if obj: self.exploreTypes(obj, **kwargs) else: Logger.error("Object not found") return obj
def rename(self, nuname=None, **kwargs): tp = self.currentType(**kwargs) cnm = tp['name'] if not nuname: nuname = idc.AskStr(cnm, "Set new type name for " + cnm + ":") if not nuname or nuname == cnm: Logger.debug("Rename cancelled") return sid = idc.GetStrucIdByName(nuname) if sid and sid != idc.BADADDR: raise self.WrongTypeError("Type already exists", nuname) Logger.debug("Renaming class %s to %s", str(tp), nuname) if tp.get('vtblea'): idc.MakeName(tp['vtblea'], 'vtbl_' + nuname) if tp.get('id'): idc.SetStrucName(tp['id'], nuname) if tp.get('vtblid'): tp['vtblnm'] = nuname + 'Vtbl' idc.SetStrucName(tp['vtblid'], tp['vtblnm']) for nm in idautils.Names(): if nm[1].startswith(cnm): fn = nm[1].replace(cnm, nuname) Logger.debug("Renaming function " + nm[1] + " to " + fn) idc.MakeName(nm[0], fn) self.typeid = nuname self.update()
def find(self, **kwargs): res = [] if kwargs.get('func'): f = kwargs.get('func') if isinstance(f, basestring): f = idaapi.get_name_ea(idc.BADADDR, f) res = self.checkFunc(f, **kwargs) or [] else: for funcea in idautils.Functions(): tp = idc.GetType(funcea) if tp is None or self.stname not in tp: continue r = self.checkFunc(funcea, **kwargs) if r: res += r if kwargs.get("silent"): return res if len(res): dictchooser.DictChooser('.'.join(self.name) + " usage", res, jumpProc=self.jump).Show() else: Logger.info("Nothing found")
def callback(self, event, *args): try: if event <= idaapi.hxe_print_func: self.safe = False if event == idaapi.hxe_switch_pseudocode: self.safe = False if event == idaapi.hxe_func_printed: self.safe = True if event == idaapi.hxe_text_ready: self.safe = True if event == idaapi.hxe_curpos: self.lastObj = None self.lastExpr = None if not self.safe: return 0 it = self.getItem(args[0]) if not it: return 0 self.lastObj = it self.lastExpr = self.lastObj if self.lastObj.is_expr( ) else None except Exception as e: Logger.error("HexraysPlugin Error: " + str(e)) return 0
def subclass(self, sup=None, **kwargs): tp = self.currentType(self.CHECK_VTBL, **kwargs) tp = self.checkVtblStruct(tp) cnm = tp['name'] if not sup: sup = idc.AskStr('', "Subclass " + cnm + " from:") if not sup or sup == cnm: Logger.debug("Subclasssing cancelled") return idc.Til2Idb(-1, sup + 'Vtbl') s = MODS.struct.Struct(sup + 'Vtbl') Logger.debug("Subclassing class %s from %s", str(tp), sup) ea = tp['vtblea'] nm = None funcs = [] while (not nm): ofs = idc.Qword(ea) if not ofs or ofs == idc.BADADDR: break try: func = FuncDescr.fromEA(ofs) except FuncDescr.NotFunctionError as e: func = None if not kwargs.get('force'): raise funcs += [func] ea += 8 nm = idc.Name(ea) flds = s.fields() if len(funcs) != len(flds) and (not kwargs.get('force')): raise self.WrongTypeError("Functions count doesn't match", s.name) for i, fofs in enumerate(sorted(flds.keys())): fld = flds[fofs] f = funcs[i] if f is None: continue refcnt = len(MODS.util.refsFromSeg(f.ea, ".rdata")) if self.untouchedFunc(f.name): nm = cnm if refcnt == 1 else sup was = str(f) f.clearType() f.parseType(fld['type'][0]) f.name = nm + "::" + fld['name'] ni = 1 while idaapi.get_name_ea(idc.BADADDR, f.name) != idc.BADADDR: ni += 1 f.name = nm + "::" + fld['name'] + "_" + str(ni) f.changeParam(0, 'this', nm + '*') f.update(True) Logger.debug("Converted func %s to type %s", was, str(f)) self.update()
def version(self): Logger.info("Pyout package v%s.", pyout.__version__)
def verbose(verb=True): Logger.setVerbose(verb)
def activate(self, ctx): Logger.debug("Explore called") MODS.explore.Explore().run()
def activate(self, ctx): Logger.debug("map interfaces called") MODS.guid.Guid().updateIIDs()
def activate(self, ctx): Logger.debug("subclass type called") MODS.type.Type().subclass()
def activate(self, ctx): Logger.debug("Rename type called") MODS.type.Type().rename()
def activate(self, ctx): Logger.debug("Update type called") MODS.type.Type().update()
def run(self, **kwargs): Logger.debug("Test run with params: " + str(kwargs)) return self.showTnefTbl()
def test(self): Logger.debug("Rename type called") MODS.test.Test().run()
def reload(self): Logger.info("Reloading pyout") MODS.reload()
def verbose(self): Logger.setVerbose(not Logger.isVerbose()) Logger.info("Verbose mode is %s.", "ON" if Logger.isVerbose() else "OFF")
def run(): x = Breaks.x64 Logger.info("break at %08X", x.rip) proc = Breaks.callbacks.get(x.rip) if proc: proc(x)
def activate(self, ctx): Logger.debug("Export types called") MODS.type.Type().exportLib()
def printGuid(self, addr=None, **kwargs): addr = addr or idaapi.get_screen_ea() Logger.info(self.guidAtAddr(addr))