def export(self): if self.existed() and not self.f_update: info('{}: The sample records are present in DB. skipped.'.format(self.sha256)) return False self.cur.execute("REPLACE INTO sample values(?, ?)", (self.sha256, self.idb_path)) pnum = tnum = 0 records = [] for fva in idautils.Functions(): fname = get_func_name(fva) tnum += 1 if self.exclude_libthunk(fva, fname): continue fhd, bsize = self.calc_fn_ssdeep(fva, fname) fhm, cfgnum = self.calc_fn_machoc(fva, fname) if fhd and fhm: pnum += 1 f_ana = bool(self.ana_pat.search(fname)) if self.f_ana_exp else False tinfo = idaapi.tinfo_t() idaapi.get_tinfo(fva, tinfo) ptype = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, tinfo, fname, '') ptype = ptype + ';' if ptype is not None else ptype # fva is 64-bit int causing OverflowError records.append((self.sha256, '{:#x}'.format(fva), fname, fhd, fhm, f_ana, bsize, ptype)) self.debug('EXPORT {} at {:#x}: ssdeep={} (size={}), machoc={} (num of CFG={})'.format(fname, fva, fhd, bsize, fhm, cfgnum)) self.cur.executemany("REPLACE INTO function values (?, ?, ?, ?, ?, ?, ?, ?)", records) success ('{} of {} functions exported'.format(pnum, tnum)) return True
def type(self): self.ti = idaapi.tinfo_t() if not idaapi.get_tinfo(self.ti, self.addr): print "[-] can't get type info for ea %x" % ea return return Type(self.ti)
def main(): idaapi.auto_wait() base = idaapi.get_imagebase() tif = idaapi.tinfo_t() f = open(os.environ.get("DESTPATH", "functype_"), 'w') for ea in Segments(): # only code segment if idaapi.segtype(ea) != idaapi.SEG_CODE: continue for fva in Functions(get_segm_start(ea), get_segm_end(ea)): func_name = get_func_name(fva) has_type = idaapi.get_tinfo(tif, fva) or idaapi.guess_tinfo( tif, fva) if not has_type: continue info = serialize(tif) if info is None: continue print( hex(fva - base)[:-1], "|", func_name, "|", tif, "|", len(info['args'])) f.write("0x%x|%s|%s\n" % (fva - base, func_name, json.dumps(info))) f.close() idaapi.qexit(0)
def resolve_objc_self_to_class(self, ea): ''' Get the objective c class for the current function RDI value based on the class of the first argument to the current function ''' f_start = idc.get_func_attr(ea, idc.FUNCATTR_START) tif = ida_typeinf.tinfo_t() idaapi.get_tinfo(tif, f_start) funcdata = idaapi.func_type_data_t() got_data = tif.get_func_details(funcdata) # not happy about casting to a string and then regex replacing... but that's the best I could come up with if got_data: replace_reg = re.compile(' \*', re.IGNORECASE) objc_self_type = funcdata[0].type return objc_self_type else: return None
def imp_cb(self, ea, name, ord_nb): """ get import type and add used types in local types to ensure "correct" export """ # Get type imp_t = idaapi.tinfo_t() if idaapi.get_tinfo(imp_t, ea): if not imp_t.is_func(): self.imports.append(idaapi.print_type(ea, PRTYPE_1LINE) + ";") else: # Iterate over ret type and args for i in range(-1, imp_t.get_nargs()): arg_t = imp_t.get_nth_arg(i) if arg_t.is_ptr_or_array(): no_ptr = arg_t no_ptr.remove_ptr_or_array() self.import_name(str(no_ptr)) self.import_name(str(arg_t)) self.imports.append(idaapi.print_type(ea, PRTYPE_1LINE) + " {}") return True
def visit_expr(self, expression): global Storage self.nodes.append(expression) if expression.op == idaapi.cot_obj: for start, end, off, func in Storage: if expression.obj_ea >= start and expression.obj_ea <= end: if func and self.cfunc.entry_ea != func: return 0 target_ea = expression.obj_ea + off head_ea = idaapi.get_item_head(target_ea) if head_ea != target_ea and idaapi.isStruct(idaapi.getFlags(head_ea)): ref_parent = self.cfunc.body.find_parent_of(expression) if ref_parent.op == idaapi.cot_ref: parent = self.cfunc.body.find_parent_of(ref_parent) if parent.op == idaapi.cot_add: v = target_ea - head_ea num_node = idaapi.make_num(v) num_node.thisown = False num_node.n.thisown = False parent = parent.cexpr # parent.thisown = False tif = idaapi.tinfo_t() if not idaapi.get_tinfo(tif, head_ea): idaapi.guess_tinfo(tif, head_ea) if parent.x == ref_parent.cexpr: # ref_parent.thisown = False # ref_parent.cexpr.thisown = False ref_parent = parent.x # expression = ref_parent.x ref_new = idaapi.cexpr_t(ref_parent) ref_new.thisown = False # expression.thisown = False # expression_new.type.thisown = False # tif.thisown = False element_tif = tif.get_ptrarr_object() element_tif.create_ptr(element_tif) ref_new.type = element_tif ref_new.x.type = tif ref_new.x.obj_ea = head_ea expr_add = idaapi.cexpr_t(idaapi.cot_add, ref_new, num_node) expr_add.thisown = False # expr_add.type = element_tif ref_parent.cexpr.assign(expr_add) # parent.x.thisown = False # parent.x.swap(expr_add) # ref_parent1 = idaapi.cexpr_t(ref_parent.cexpr) # parent.x.swap(ref_parent1) elif parent.y == ref_parent.cexpr: ref_parent.thisown = False ref_parent.cexpr.thisown = False ref_parent = idaapi.cexpr_t(ref_parent.cexpr) expression.thisown = False expression = idaapi.cexpr_t(expression) ref_parent.x.replace_by(expression) expr_add = idaapi.cexpr_t(idaapi.cot_add, ref_parent, num_node) parent.y.thisown = False parent.y.replace_by(expr_add) else: print "F**K!" rc = self.recalc_parent_types() # parent = self.nodes[-2] # parent = self.nodes[-3] # parent = self.nodes[-4] return 0