def import_struct(self): if self.has_name_collisions(): self.resolve_name_collisions() cdecl_typedef = '#pragma pack(push, 1)\n' + idaapi.print_tinfo( None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, self.tinfo, self.name, None) previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, self.name) if previous_ordinal: idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl_typedef, idaapi.PT_TYP) else: ordinal = idaapi.idc_set_local_type(-1, cdecl_typedef, idaapi.PT_TYP) if ordinal: self.ordinal = ordinal print 'Imported struct \'%s\', ordinal %#x' % (self.name, self.ordinal) return idaapi.import_type(idaapi.cvar.idati, -1, self.name) else: print 'Error due importing struct \'%s\', ordinal %#x' % ( self.name, ordinal) return idaapi.BADNODE
def import_to_structures(self, ask=False): """ Imports virtual tables and returns tid_t of new structure :return: idaapi.tid_t """ cdecl_typedef = idaapi.print_tinfo( None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, self.create_tinfo(), self.vtable_name, None) if ask: cdecl_typedef = idaapi.ask_text( 0x10000, cdecl_typedef, "The following new type will be created") if not cdecl_typedef: return previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, self.vtable_name) if previous_ordinal: idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl_typedef, idaapi.PT_TYP) else: ordinal = idaapi.idc_set_local_type(-1, cdecl_typedef, idaapi.PT_TYP) if ordinal: print("[Info] Virtual table " + self.vtable_name + " added to Local Types") return idaapi.import_type(idaapi.cvar.idati, -1, self.vtable_name) else: print("[Error] Failed to create virtual table " + self.vtable_name) print("*" * 100) print(cdecl_typedef) print("*" * 100)
def build_structure_in_ida(udt_data, structure_name): # 结构体的创建 final_tinfo = idaapi.tinfo_t() final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) cdecl = idaapi.print_tinfo( None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, final_tinfo, structure_name, None) print cdecl # cdecl = "struct Test_Python_Type{int filed_1;};" # structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0] # 先删除 # tid = idaapi.del_numbered_type(idaapi.cvar.idati, struct_ordinal) # print tid # struct_ordinal = 21 previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name) if previous_ordinal: struct_ordinal = previous_ordinal # 如果之前的编号存在,则删除编号,重新创建 idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) # 创建type tid = idaapi.idc_set_local_type(struct_ordinal, cdecl, idaapi.PT_TYP) # print tid else: tid = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP)
def activate(self, ctx): hx_view = idaapi.get_widget_vdui(ctx.widget) ri = self.extract_recast_info(hx_view.cfunc, hx_view.item) if not ri: return 0 if isinstance(ri, RecastLocalVariable): hx_view.set_lvar_type(ri.local_variable, ri.recast_tinfo) elif isinstance(ri, RecastGlobalVariable): idaapi.apply_tinfo2(ri.global_variable_ea, ri.recast_tinfo, idaapi.TINFO_DEFINITE) elif isinstance(ri, RecastArgument): if ri.recast_tinfo.is_array(): ri.recast_tinfo.convert_array_to_ptr() helper.set_func_argument(ri.func_tinfo, ri.arg_idx, ri.recast_tinfo) idaapi.apply_tinfo2(ri.func_ea, ri.func_tinfo, idaapi.TINFO_DEFINITE) elif isinstance(ri, RecastReturn): cfunc = helper.decompile_function(ri.func_ea) if not cfunc: return 0 func_tinfo = idaapi.tinfo_t() cfunc.get_func_type(func_tinfo) helper.set_func_return(func_tinfo, ri.recast_tinfo) idaapi.apply_tinfo2(cfunc.entry_ea, func_tinfo, idaapi.TINFO_DEFINITE) elif isinstance(ri, RecastStructure): tinfo = idaapi.tinfo_t() tinfo.get_named_type(idaapi.cvar.idati, ri.structure_name) ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, ri.structure_name) if ordinal == 0: return 0 udt_member = idaapi.udt_member_t() udt_member.offset = ri.field_offset * 8 idx = tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member) if udt_member.offset != ri.field_offset * 8: print("[Info] Can't handle with arrays yet") elif udt_member.type.get_size() != ri.recast_tinfo.get_size(): print("[Info] Can't recast different sizes yet") else: udt_data = idaapi.udt_type_data_t() tinfo.get_udt_details(udt_data) udt_data[idx].type = ri.recast_tinfo tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) tinfo.set_numbered_type(idaapi.cvar.idati, ordinal, idaapi.NTF_REPLACE, ri.structure_name) else: raise NotImplementedError hx_view.refresh_view(True) return 0
def pack(self, start=0, stop=None): if self.collisions[start:stop].count(True): print "[Warning] Collisions detected" return final_tinfo = idaapi.tinfo_t() udt_data = idaapi.udt_type_data_t() origin = self.items[start].offset if start else 0 offset = origin for item in filter(lambda x: x.enabled, self.items[start:stop]): # Filter disabled members gap_size = item.offset - offset if gap_size: udt_data.push_back(TemporaryStructureModel.get_padding_member(offset - origin, gap_size)) if item.is_array: array_size = self.calculate_array_size(bisect.bisect_left(self.items, item)) if array_size: udt_data.push_back(item.get_udt_member(array_size, offset=origin)) offset = item.offset + item.size * array_size continue udt_data.push_back(item.get_udt_member(offset=origin)) offset = item.offset + item.size final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) cdecl = idaapi.print_tinfo(None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, final_tinfo, self.structure_name, None) cdecl = idaapi.asktext(0x10000, '#pragma pack(push, 1)\n' + cdecl, "The following new type will be created") if cdecl: structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0] previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name) if previous_ordinal: reply = QtGui.QMessageBox.question( None, "HexRaysPyTools", "Structure already exist. Do you want to overwrite it?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if reply == QtGui.QMessageBox.Yes: idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl, idaapi.PT_TYP) else: return else: ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP) if ordinal: print "[Info] New type {0} was added to Local Types".format(structure_name) tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name) if tid: tinfo = idaapi.create_typedef(structure_name) ptr_tinfo = idaapi.tinfo_t() ptr_tinfo.create_ptr(tinfo) for scanned_var in self.get_unique_scanned_variables(origin): scanned_var.apply_type(ptr_tinfo) return tinfo else: print "[ERROR] Structure {0} probably already exist".format(structure_name)
def create(tinfo, class_): ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, tinfo.dstr()) if ordinal == 0: if idaapi.import_type(idaapi.cvar.idati, -1, tinfo.dstr(), 0) == idaapi.BADNODE: raise ImportError("unable to import type to idb ({})".format(tinfo.dstr())) ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, tinfo.dstr()) result = all_virtual_tables.get(ordinal) if result: result.class_.append(class_) else: udt_data = idaapi.udt_type_data_t() tinfo.get_udt_details(udt_data) result = VirtualTable(ordinal, tinfo, class_) virtual_functions = [VirtualMethod.create(func.type, func.name, result) for func in udt_data] result.virtual_functions = virtual_functions all_virtual_functions[ordinal] = result return result
def create(tinfo, class_): ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, tinfo.dstr()) result = all_virtual_tables.get(ordinal) if result: result.class_.append(class_) else: udt_data = idaapi.udt_type_data_t() tinfo.get_udt_details(udt_data) result = VirtualTable(ordinal, tinfo, class_) virtual_functions = [VirtualMethod.create(func.type, func.name, result) for func in udt_data] result.virtual_functions = virtual_functions all_virtual_functions[ordinal] = result return result
def import_structure(name, tinfo): cdecl_typedef = idaapi.print_tinfo(None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, tinfo, name, None) if idc.parse_decl(cdecl_typedef, idaapi.PT_TYP) is None: return 0 previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, name) if previous_ordinal: idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl_typedef, idaapi.PT_TYP) else: ordinal = idaapi.idc_set_local_type(-1, cdecl_typedef, idaapi.PT_TYP) return ordinal
def GetTypeString(parsedList, name=""): ti = idaapi.get_idati() # print "GetTypeString: name %s"%self.name the_bytes = [] for thing in parsedList: if type(thing) == int: # if it's a byte, just put it back in the_bytes.append(thing) elif len(thing) == 1: if list(thing.keys())[0] == "local_type": the_bytes.append(ord("=")) # a type starts with = # print type(thing["local_type"]),thing["local_type"] ordinal = idaapi.get_type_ordinal( ti, list(thing.values()) [0]) # get the ordinal of the Local Type based on its name if ordinal > 0: the_bytes = the_bytes + encode_ordinal_to_string(ordinal) else: raise NameError("Depends local type not in IDB") else: raise NameError("Wrong depend record for type: %s!" % name) packed = struct.pack("%dB" % len(the_bytes), *the_bytes) return packed
def find_type_by_name(name): my_ti = idaapi.get_idati() ordinal = idaapi.get_type_ordinal(my_ti, name)
def activate(self, ctx): hx_view = idaapi.get_tform_vdui(ctx.form) result = self.check(hx_view.cfunc, hx_view.item) if result: if result[0] == RECAST_LOCAL_VARIABLE: tinfo, lvar = result[1:] if hx_view.set_lvar_type(lvar, tinfo): hx_view.refresh_view(True) elif result[0] == RECAST_GLOBAL_VARIABLE: tinfo, address = result[1:] if idaapi.apply_tinfo2(address, tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_ARGUMENT: arg_index, func_tinfo, arg_tinfo, address = result[1:] func_data = idaapi.func_type_data_t() func_tinfo.get_func_details(func_data) func_data[arg_index].type = arg_tinfo new_func_tinfo = idaapi.tinfo_t() new_func_tinfo.create_func(func_data) if idaapi.apply_tinfo2(address, new_func_tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_RETURN: return_type, func_address = result[1:] try: cfunc = idaapi.decompile( func_address) if func_address else hx_view.cfunc except idaapi.DecompilationFailure: print "[ERROR] Ida failed to decompile function" return function_tinfo = idaapi.tinfo_t() cfunc.get_func_type(function_tinfo) func_data = idaapi.func_type_data_t() function_tinfo.get_func_details(func_data) func_data.rettype = return_type function_tinfo.create_func(func_data) if idaapi.apply_tinfo2(cfunc.entry_ea, function_tinfo, idaapi.TINFO_DEFINITE): hx_view.refresh_view(True) elif result[0] == RECAST_STRUCTURE: structure_name, field_offset, new_type = result[1:] tinfo = idaapi.tinfo_t() tinfo.get_named_type(idaapi.cvar.idati, structure_name) ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name) if ordinal: udt_member = idaapi.udt_member_t() udt_member.offset = field_offset * 8 idx = tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member) if udt_member.offset != field_offset * 8: print "[Info] Can't handle with arrays yet" elif udt_member.type.get_size() != new_type.get_size(): print "[Info] Can't recast different sizes yet" else: udt_data = idaapi.udt_type_data_t() tinfo.get_udt_details(udt_data) udt_data[idx].type = new_type tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) tinfo.set_numbered_type(idaapi.cvar.idati, ordinal, idaapi.NTF_REPLACE, structure_name) hx_view.refresh_view(True)