def make_names(self): ''' make names in idb ''' EFI_GUID = 'EFI_GUID *' EFI_GUID_ID = idc.get_struc_id('EFI_GUID') self.get_boot_services() self.get_protocols() self.get_prot_names() data = self.Protocols['all'] empty = True for element in data: try: idc.SetType(element['address'], EFI_GUID) self.apply_struct(element['address'], 16, EFI_GUID_ID) name = element['protocol_name'] + '_' + \ '{addr:#x}'.format(addr=element['address']) idc.set_name(element['address'], name) empty = False print('[ {ea} ] {name}'.format( ea='{addr:#010x}'.format(addr=element['address']), name=name)) except: continue if empty: print(' * list is empty')
def handle_new(self): new_name = self.new_name_w.text().encode('ascii', 'replace').strip().decode() if not itanium_mangler.check_identifier(new_name): ida_kernwin.warning('The name "%s" is invalid' % new_name) return struct_id = idc.get_struc_id(new_name) if struct_id != idc.BADADDR: if util.ask_yes_no( 'The struct "%s" already exists. Do you want to select it anyways?' % new_name): self.struct_id = struct_id self.accept() return return self.struct_id = idaapi.add_struc(idc.BADADDR, new_name, False) if self.struct_id == idc.BADADDR: ida_kernwin.warning('Creating struct with the name "%s" failed' % new_name) return self.accept()
def get_or_create_struct_id(struct_name, is_union=False): """ @return: struct id or BADADDR if couldn't create struct """ sid = idc.get_struc_id(struct_name) if sid != BADADDR: return sid return idc.add_struc(-1, struct_name, is_union)
def get_type_size(type): sid = idc.get_struc_id(type) if sid != idc.BADADDR: return idc.get_struc_size(sid) try: name, tp, fld = idc.parse_decl(type, 1) if tp: return idc.SizeOf(tp) except: return 0
def get_data_guids(self): """rename GUIDs in idb""" EFI_GUID = "EFI_GUID" EFI_GUID_ID = idc.get_struc_id("EFI_GUID") segments = [".text", ".data"] for segment in segments: seg_start, seg_end = 0, 0 for seg in idautils.Segments(): if idc.get_segm_name(seg) == segment: seg_start = idc.get_segm_start(seg) seg_end = idc.get_segm_end(seg) break ea = seg_start while ea <= seg_end - 15: prot_name = str() if "unk" in idc.get_name(ea, ida_name.GN_VISIBLE): find = False cur_guid = list() cur_guid.append(idc.get_wide_dword(ea)) cur_guid.append(idc.get_wide_word(ea + 4)) cur_guid.append(idc.get_wide_word(ea + 6)) for addr in range(ea + 8, ea + 16, 1): cur_guid.append(idc.get_wide_byte(addr)) if cur_guid == [0] * 11: ea += 1 continue for guid_place in [ "ami_guids", "asrock_guids", "dell_guids", "edk_guids", "edk2_guids", "lenovo_guids", ]: for name in self.Protocols[guid_place]: if self.Protocols[guid_place][name] == cur_guid: prot_name = f"{name}_{ea:016X}" record = { "address": ea, "service": "unknown", "guid": cur_guid, "protocol_name": name, "protocol_place": guid_place, } find = True break if find: break if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name): idc.SetType(ea, EFI_GUID) self.apply_struct(ea, 16, EFI_GUID_ID) idc.set_name(ea, prot_name) self.Protocols["data"].append(record) ea += 1
def get_data_guids(self): ''' rename GUIDs in idb ''' EFI_GUID = 'EFI_GUID *' EFI_GUID_ID = idc.get_struc_id('EFI_GUID') segments = ['.text', '.data'] for segment in segments: seg_start, seg_end = 0, 0 for seg in idautils.Segments(): if idc.get_segm_name(seg) == segment: seg_start = idc.get_segm_start(seg) seg_end = idc.get_segm_end(seg) break ea = seg_start while (ea <= seg_end - 15): prot_name = '' if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1: find = False cur_guid = [] cur_guid.append(idc.get_wide_dword(ea)) cur_guid.append(idc.get_wide_word(ea + 4)) cur_guid.append(idc.get_wide_word(ea + 6)) for addr in range(ea + 8, ea + 16, 1): cur_guid.append(idc.get_wide_byte(addr)) if cur_guid == [0] * 11: ea += 1 continue for guid_place in [ 'ami_guids', 'asrock_guids', 'dell_guids', 'edk_guids', 'edk2_guids', 'lenovo_guids' ]: for name in self.Protocols[guid_place]: if self.Protocols[guid_place][name] == cur_guid: prot_name = name + '_' + \ '{addr:#x}'.format(addr=ea) record = { 'address': ea, 'service': 'unknown', 'guid': cur_guid, 'protocol_name': name, 'protocol_place': guid_place } find = True break if find: break if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name): idc.SetType(ea, EFI_GUID) self.apply_struct(ea, 16, EFI_GUID_ID) idc.set_name(ea, prot_name) self.Protocols['data'].append(record) ea += 1
def __call__(self): sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) if self.smname: mptr = idaapi.get_member_by_name(sptr, self.smname.encode('utf-8')) idaapi.set_member_cmt(mptr, self.cmt.encode('utf-8') if self.cmt else '', self.repeatable_cmt) else: idaapi.set_struc_cmt(sptr.id, self.cmt.encode('utf-8') if self.cmt else '', self.repeatable_cmt)
def get_struc_name(self): x = self.target.operands['x'] m = self.target.operands['m'] xtype = x.type xtype.remove_ptr_or_array() typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '') sid = idc.get_struc_id(typename) member = idc.get_member_name(sid, m) return '%s::%s' % (typename, member)
def __call__(self): mt = idaapi.opinfo_t() if idaapi.isStruct(self.flag): mt.tid = self.extra['id'] if idaapi.isOff0(self.flag) or idaapi.isOff1(self.flag): mt.ri = idaapi.refinfo_t(self.extra['flags'], self.extra['base'], self.extra['target'], self.extra['tdelta']) if idaapi.isASCII(self.flag): mt.strtype = self.extra['strtype'] sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) idaapi.set_member_type(sptr, self.soff, self.flag, mt, self.eoff - self.soff)
def load_struct(self): name = "" while True: name = idaapi.ask_str(name, idaapi.HIST_TYPE, "Enter type:") if name is None: return sid = idc.get_struc_id(name) if sid != idc.BADADDR: break self.default_name = name sid = idc.get_struc_id(name) if sid == idc.BADADDR: print(("Invalid Struct Name: %s" % name)) return tif = get_tinfo(name) sys.modules["__main__"].tif = tif nmembers = tif.get_udt_nmembers() for index in range(nmembers): u = idaapi.udt_member_t() u.offset = index if tif.find_udt_member(u, idaapi.STRMEM_INDEX) != -1: sys.modules["__main__"].udt = u member = Member(u.offset // 8, u.type, None) member.name = u.name # member.cmt = u.cmt # u.cmt doesn't work, so we will do something ugly _typename = tif.get_type_name() name_sid = idc.get_struc_id(_typename) member.cmt = idc.get_member_cmt( name_sid, u.offset // 8, 0) or "imported from {}".format(name) self.add_row(member)
def get_struc_name(self): x = self.target.operands['x'] m = self.target.operands['m'] xtype = x.type xtype.remove_ptr_or_array() typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '') sid = idc.get_struc_id(typename) member = idc.get_member_name(sid, m) return '%s::%s' % (typename, member)
def force_make_struct(ea, struct_name): """@return: True on success, False on failure""" sid = idc.get_struc_id(struct_name) if sid == BADADDR: log.warn("Structure not found: %s", struct_name) return False size = idc.get_struc_size(sid) if not size: log.warn("Structure with zero size: %s", struct_name) return False if not ida_bytes.del_items(ea, ida_bytes.DELIT_SIMPLE, size): log.warn("Failed to delete structure items: %s", struct_name) return False return ida_bytes.create_struct(ea, size, sid)
def make_comments(self): """make comments in idb""" EFI_BOOT_SERVICES_ID = idc.get_struc_id("EFI_BOOT_SERVICES") self.get_boot_services() empty = True for service in self.gBServices: for address in self.gBServices[service]: message = f"EFI_BOOT_SERVICES->{service}" idc.set_cmt(address, message, 0) idc.op_stroff(address, 0, EFI_BOOT_SERVICES_ID, 0) empty = False print(f"[ {address:016X} ] {message}") if empty: print(" * list is empty")
def make_comments(self): """make comments in idb""" EFI_BOOT_SERVICES_ID = idc.get_struc_id('EFI_BOOT_SERVICES') self.get_boot_services() empty = True for service in self.gBServices: for address in self.gBServices[service]: message = 'EFI_BOOT_SERVICES->{0}'.format(service) idc.set_cmt(address, message, 0) idc.op_stroff(address, 0, EFI_BOOT_SERVICES_ID, 0) empty = False print('[ {ea} ] {message}'.format( ea='{addr:#010x}'.format(addr=address), message=message)) if empty: print(' * list is empty')
def struct(self, name, members, location = 0x0): if self.FLAGS > 7: return idc.get_struc_id(name) entry = idc.add_struc(BADADDR, name, False) for (member, comment, size) in members: flags = idaapi.get_flags_by_size(size) if member in ['function', 'offset', 'd_name']: idc.add_struc_member(entry, member, location, flags + FF_0OFF, BADADDR, size, BADADDR, 0, REF_OFF64) else: idc.add_struc_member(entry, member, location, flags, BADADDR, size) idc.set_member_cmt(entry, location, comment, False) location += size return entry
def read_struct(ea, struct=None, sid=None, members=None, asobject=False): """Read a structure from the given address. This function reads the structure at the given address and converts it into a dictionary or accessor object. Arguments: ea: The linear address of the start of the structure. Options: sid: The structure ID of the structure type to read. struct: The name of the structure type to read. members: A list of the names of the member fields to read. If members is None, then all members are read. Default is None. asobject: If True, then the struct is returned as a Python object rather than a dict. One of sid and struct must be specified. """ # Handle sid/struct. if struct is not None: sid2 = idc.get_struc_id(struct) if sid2 == idc.BADADDR: raise ValueError('Invalid struc name {}'.format(struct)) if sid is not None and sid2 != sid: raise ValueError('Invalid arguments: sid={}, struct={}'.format( sid, struct)) sid = sid2 else: if sid is None: raise ValueError('Invalid arguments: sid={}, struct={}'.format( sid, struct)) if idc.get_struc_name(sid) is None: raise ValueError('Invalid struc id {}'.format(sid)) # Iterate through the members and add them to the struct. union = idc.is_union(sid) struct = {} for offset, name, size in idautils.StructMembers(sid): if members is not None and name not in members: continue _read_struct_member(struct, sid, union, ea, offset, name, size, asobject) if asobject: struct = objectview(struct, ea, idc.get_struc_size(sid)) return struct
def make_names(self): """make names in idb""" EFI_GUID = 'EFI_GUID' EFI_GUID_ID = idc.get_struc_id('EFI_GUID') self.get_boot_services() self.get_protocols() self.get_prot_names() data = self.Protocols['all'] empty = True for element in data: try: idc.SetType(element['address'], EFI_GUID) self.apply_struct(element['address'], 16, EFI_GUID_ID) prot_name = element['protocol_name'] addr = element['address'] name = f'{prot_name}_{addr:X}' idc.set_name(element['address'], name) empty = False print(f'[ {addr:016X} ] {name}') except: continue if empty: print(' * list is empty')
def set_struct_member(structname, name, flag_andTypeID, size): id = idc.get_struc_id(str(structname)) offset = -1 flag = flag_andTypeID.get("flag") typeid = flag_andTypeID.get("typeid") nbytes = size try: ok = 0 if not idaapi.get_member_by_name( idaapi.get_struc(idaapi.get_struc_id(str(structname))), str(name)): ok = idc.add_struc_member(id, str(name), offset, flag, typeid, nbytes) if not ok: if not idaapi.get_member_by_name( idaapi.get_struc(idaapi.get_struc_id(str(structname))), str(name)): print("Could not add struct member {name} at {structname}". format(name=name, structname=structname)) except: pass
def make_names(self): """make names in idb""" EFI_GUID = "EFI_GUID" EFI_GUID_ID = idc.get_struc_id("EFI_GUID") self.get_boot_services() self.get_protocols() self.get_prot_names() data = self.Protocols["all"] empty = True for element in data: try: idc.SetType(element["address"], EFI_GUID) self.apply_struct(element["address"], 16, EFI_GUID_ID) prot_name = element["protocol_name"] addr = element["address"] name = f"{prot_name}_{addr:X}" idc.set_name(element["address"], name) empty = False print(f"[ {addr:016X} ] {name}") except: continue if empty: print(" * list is empty")
def write_vtbl_struct(self, vtbl_name, struct_member_names): struct_name = "{0}_struct".format(vtbl_name) sid = idc.get_struc_id(struct_name) if sid == idc.BADADDR: # Doesn't exist sid = idc.add_struc(-1, struct_name, is_union=0) else: # Clear existing member_offset = idc.get_first_member(sid) while member_offset != idc.BADADDR: idc.del_struc_member(sid, member_offset) member_offset = idc.get_first_member(sid) for member_name in struct_member_names: idc.add_struc_member(sid, member_name, offset=-1, flag=idc.FF_DATA | idc.FF_QWORD, typeid=-1, nbytes=8, reftype=idc.REF_OFF64) member_offset = idc.get_last_member(sid) member_id = idc.get_member_id(sid, member_offset) idc.SetType(member_id, "void*")
def register_structs(): str_afu_header = """ struct afu_header { unsigned short magic; unsigned short unk_0x100; unsigned short fw_type; unsigned short fw_version; unsigned int fw_len; unsigned int fw_crc; unsigned short product_id; unsigned short hw_revision_id; }; """ str_afu_sig_header = """ struct afu_sig_header { unsigned int magic; unsigned short unk_0x100; unsigned short unk_0x120; unsigned short digest_type; // guess 1 sha256? unsigned short digest_len; unsigned int digest_offs; unsigned short sig_type; unsigned short sig_len; unsigned int sig_offs; }; """ str_afu_pers_header = """ struct afu_pers_header { unsigned int magic; unsigned short unk_0x100; unsigned char uniqueid[12]; unsigned char reserved[0x1c-0x12]; unsigned int flags; }; """ str_afu_full_header = """ struct afu_full_header { struct afu_header header; unsigned char reserved1[0x20-0x14]; struct afu_sig_header sig_header; unsigned char reserved2[0x40-0x38]; struct afu_pers_header pers_header; unsigned char reserved3[0x7c-0x60]; unsigned int header_crc; }; """ sid = idc.get_struc_id("afu_header") if sid != -1: idc.del_struc(sid) r = idc.SetLocalType(-1, str_afu_header, 0) r = idc.import_type(-1, "afu_header") sid = idc.get_struc_id("afu_sig_header") if sid != -1: idc.del_struc(sid) r = idc.SetLocalType(-1, str_afu_sig_header, 0) r = idc.import_type(-1, "afu_sig_header") sid = idc.get_struc_id("afu_pers_header") if sid != -1: idc.del_struc(sid) r = idc.SetLocalType(-1, str_afu_pers_header, 0) r = idc.import_type(-1, "afu_pers_header") sid = idc.get_struc_id("afu_full_header") if sid != -1: idc.del_struc(sid) r = idc.SetLocalType(-1, str_afu_full_header, 0) r = idc.import_type(-1, "afu_full_header")
def __call__(self): sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) idaapi.del_struc_member(sptr, self.offset)
def __call__(self): sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) idaapi.set_member_name(sptr, self.offset, self.newname.encode('utf-8'))
def __call__(self): sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8'))) idaapi.expand_struc(sptr, self.offset, self.delta)
def get_sptr_by_name(struct_name): sid = idc.get_struc_id(struct_name) return ida_struct.get_struc(sid)
def __call__(self): idc.del_struc(idc.get_struc_id(self.sname.encode('utf-8')))
def run(self): try: logger.debug('Starting up') dlg = StructTyperWidget() dlg.setStructs(loadStructs()) oldTo = idaapi.set_script_timeout(0) res = dlg.exec_() idaapi.set_script_timeout(oldTo) if res == QtWidgets.QDialog.Accepted: regPrefix = dlg.getRegPrefix() sid = None struc = None if dlg.ui.rb_useStackFrame.isChecked(): ea = idc.here() if using_ida7api: sid = idc.get_frame_id(ea) else: sid = idc.GetFrame(ea) struc = idaapi.get_frame(ea) logger.debug('Dialog result: accepted stack frame') if (sid is None) or (sid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError('Failed to get sid for stack frame at 0x%x' % ea) if (struc is None) or (struc == 0) or (struc == idc.BADADDR): raise RuntimeError('Failed to get struc_t for stack frame at 0x%x' % ea) if using_ida7api: pass else: #need the actual pointer value, not the swig wrapped struc_t struc= long(struc.this) else: structName = dlg.getActiveStruct() if structName is None: print("No struct selected. Bailing out") return logger.debug('Dialog result: accepted %s "%s"', type(structName), structName) if using_ida7api: sid = idc.get_struc_id(structName) else: sid = idc.GetStrucIdByName(structName) if (sid is None) or (sid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError('Failed to get sid for %s' % structName) tid = idaapi.get_struc_id(structName) if (tid is None) or (tid == 0) or (tid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError('Failed to get tid_t for %s' % structName) if using_ida7api: struc = idaapi.get_struc(tid) else: struc = g_dll.get_struc(tid) if (struc is None) or (struc == 0) or (struc == idc.BADADDR): raise RuntimeError('Failed to get struc_t for %s' % structName) foundMembers = self.processStruct(regPrefix, struc, sid) if dlg.ui.rb_useStackFrame.isChecked() and (foundMembers != 0): #reanalyze current function if we're analyzing a stack frame & found some func pointers if using_ida7api: funcstart = idc.get_func_attr(idc.here(), idc.FUNCATTR_START) funcend = idc.get_func_attr(idc.here(), idc.FUNCATTR_END) else: funcstart = idc.GetFunctionAttr(idc.here(), idc.FUNCATTR_START) funcend = idc.GetFunctionAttr(idc.here(), idc.FUNCATTR_END) if (funcstart != idc.BADADDR) and (funcend != idc.BADADDR): if using_ida7api: idc.plan_and_wait(funcstart, funcend) else: idc.AnalyzeArea(funcstart, funcend) elif res == QtWidgets.QDialog.Rejected: logger.info('Dialog result: canceled by user') else: logger.debug('Unknown result') raise RuntimeError('Dialog unknown result') except Exception, err: logger.exception("Exception caught: %s", str(err))
def type_to_struct(name): idc.del_struc(idc.get_struc_id(name)) # delete existing struct idc.import_type(-1, name) # -1 = append to end
def run(self): try: logger.debug('Starting up') dlg = StructTyperWidget() dlg.setStructs(loadStructs()) oldTo = idaapi.set_script_timeout(0) res = dlg.exec_() idaapi.set_script_timeout(oldTo) if res == QtWidgets.QDialog.Accepted: regPrefix = dlg.getRegPrefix() sid = None struc = None if dlg.ui.rb_useStackFrame.isChecked(): ea = idc.here() if using_ida7api: sid = idc.get_frame_id(ea) else: sid = idc.GetFrame(ea) struc = idaapi.get_frame(ea) logger.debug('Dialog result: accepted stack frame') if (sid is None) or (sid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError( 'Failed to get sid for stack frame at 0x%x' % ea) if (struc is None) or (struc == 0) or (struc == idc.BADADDR): raise RuntimeError( 'Failed to get struc_t for stack frame at 0x%x' % ea) if using_ida7api: pass else: #need the actual pointer value, not the swig wrapped struc_t struc = long(struc.this) else: structName = dlg.getActiveStruct() if structName is None: print("No struct selected. Bailing out") return logger.debug('Dialog result: accepted %s "%s"', type(structName), structName) if using_ida7api: sid = idc.get_struc_id(structName) else: sid = idc.GetStrucIdByName(structName) if (sid is None) or (sid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError('Failed to get sid for %s' % structName) tid = idaapi.get_struc_id(structName) if (tid is None) or (tid == 0) or (tid == idc.BADADDR): #i should really figure out which is the correct error case raise RuntimeError('Failed to get tid_t for %s' % structName) if using_ida7api: struc = idaapi.get_struc(tid) else: struc = g_dll.get_struc(tid) if (struc is None) or (struc == 0) or (struc == idc.BADADDR): raise RuntimeError('Failed to get struc_t for %s' % structName) foundMembers = self.processStruct(regPrefix, struc, sid) if dlg.ui.rb_useStackFrame.isChecked() and (foundMembers != 0): #reanalyze current function if we're analyzing a stack frame & found some func pointers if using_ida7api: funcstart = idc.get_func_attr(idc.here(), idc.FUNCATTR_START) funcend = idc.get_func_attr(idc.here(), idc.FUNCATTR_END) else: funcstart = idc.GetFunctionAttr( idc.here(), idc.FUNCATTR_START) funcend = idc.GetFunctionAttr(idc.here(), idc.FUNCATTR_END) if (funcstart != idc.BADADDR) and (funcend != idc.BADADDR): if using_ida7api: idc.plan_and_wait(funcstart, funcend) else: idc.AnalyzeArea(funcstart, funcend) elif res == QtWidgets.QDialog.Rejected: logger.info('Dialog result: canceled by user') else: logger.debug('Unknown result') raise RuntimeError('Dialog unknown result') except Exception, err: logger.exception("Exception caught: %s", str(err))
def change_member_name(struct_name, offset, name): return idc.set_member_name(idc.get_struc_id(struct_name), offset, name)
def __call__(self): idaapi.set_struc_name(idc.get_struc_id(self.oldname.encode('utf-8')), self.newname.encode('utf-8'))