def makeInterface(self, offset): idc.SetType(offset, "interfaceType") ifaceid = ida_struct.get_struc_id("interfaceType") meth_offs = idc.get_member_offset(ifaceid, "methods") slice_id = ida_struct.get_struc_id("slice") size_off = idc.get_member_offset(slice_id, "len") size = self.stepper.ptr(offset + meth_offs + size_off) if size != 0: addr = self.getPtr(slice_id, offset + meth_offs, "data") idc.SetType(addr, "imethod") sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod")) self.make_arr(addr, size, sz, "imethod") names = self.processIMethods(addr, size) # For now only for go1.7 if names is None: return name = self.getName(offset) while name[0] == "*": name = name[1:] name = Utils.relaxName(name) name = "user_interface_" + name # TODO: this is for go1.7 need additional check for other versions fields = [("inter", "void *"), ("type", "void *"), ("link", "void *"), ("bad", "__int32"), ("unused", "__int32")] for i in names: fields.append((i, "void *")) itype = [(name, fields)] self.settings.structCreator.createTypes(itype)
def set_ida_struct(struct: Struct, controller) -> bool: # first, delete any struct by the same name if it exists sid = ida_struct.get_struc_id(struct.name) if sid != 0xffffffffffffffff: sptr = ida_struct.get_struc(sid) ida_struct.del_struc(sptr) # now make a struct header ida_struct.add_struc(ida_idaapi.BADADDR, struct.name, False) sid = ida_struct.get_struc_id(struct.name) sptr = ida_struct.get_struc(sid) # expand the struct to the desired size # XXX: do not increment API here, why? Not sure, but you cant do it here. ida_struct.expand_struc(sptr, 0, struct.size) # add every member of the struct for off, member in struct.struct_members.items(): # convert to ida's flag system mflag = convert_size_to_flag(member.size) # create the new member ida_struct.add_struc_member( sptr, member.member_name, member.offset, mflag, None, member.size, ) return True
def createUserTypeStruct(self, addr, name, size, self_size): fields = [] sid = ida_struct.get_struc_id("structField") sz = ida_struct.get_struc_size(sid) sid_type = ida_struct.get_struc_id("type") fields = [] curr_offset = 0 idc.set_cmt(addr, name, 0) for i in range(size): fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name")) type_addr = self.getPtr(sid, addr+i*sz, "typ") typename = self.getType(type_addr) size = self.getPtr(sid_type, type_addr, "size") if fieldname == "" or fieldname is None: fieldname = "unused_"+Utils.id_generator() offset = self.getStructFieldOffset(sid, addr+i*sz) print(f"Get offset: {offset:x}") if offset != curr_offset: print("Offset missmatch.Got %d expected %d. Adding padding..." % (curr_offset, offset)) if offset < curr_offset: raise("Too many bytes already") while offset != curr_offset: fields.append(("padding", "char")) curr_offset += 1 curr_offset += size if size != 0: offset_kind = idc.get_member_offset(sid_type, "kind") kind_of_type = self.getKindEnumName(type_addr) print(kind_of_type) if kind_of_type == "STRUCT_": #Disabled for now name_type = self.getName(type_addr) while name_type[0] == "*": name_type = name_type[1:] name_type = Utils.relaxName(name_type) name_type = "ut_" + name_type #print("setting type %s" % name_type) fields.append((fieldname, name_type)) elif kind_of_type == "STRING": fields.append((fieldname, "string")) elif kind_of_type == "SLICE": fields.append((fieldname, "slice")) elif kind_of_type == "INTERFACE": fields.append((fieldname, "__iface")) else: fields.append((fieldname, "char [%d]" % size)) if curr_offset != self_size: print("%x: Structure size mismatch: %x" % (addr, curr_offset)) if self_size < curr_offset: raise("Too many bytes already") while self_size != curr_offset: fields.append(("padding", "char")) curr_offset += 1 new_type = [(name, fields)] self.settings.structCreator.createTypes(new_type) new_type_sid = ida_struct.get_struc_id(name) sz = ida_struct.get_struc_size(new_type_sid) if sz != self_size: print("%x" % addr ) raise("Error at creating structure")
def get_type(): #without this line, waiting a few seconds for user input will cause the 'Please wait...' msgbox to jump and make the system freeze. orig_timeout = idaapi.set_script_timeout(0x7fffffff) struc_type = ida_kernwin.choose_struc('Choose type') idaapi.set_script_timeout(orig_timeout) if struc_type is None: return None #print struc_type type_name = ida_struct.get_struc_name(struc_type.id) return type_name print type(a) type_name = AskStr('', 'Type for %s' % get_reg_full_name(ea, reg)) if type_name is None: print 'Escaped' return None if ida_struct.get_struc_id(type_name) == 0xffffffff: print 'Not a type' return None return type_name
def _on_optypechanged(self, ea, n, op, extra): if op == 'hex': ida_bytes.op_hex(ea, n) if op == 'bin': ida_bytes.op_bin(ea, n) if op == 'dec': ida_bytes.op_dec(ea, n) if op == 'chr': ida_bytes.op_chr(ea, n) if op == 'oct': ida_bytes.op_oct(ea, n) if op == 'stkvar': ida_bytes.op_stkvar(ea, n) if op == 'enum': enum_id = ida_enum.get_enum(str(extra['ename'])) ida_bytes.op_enum(ea, n, enum_id, extra['serial']) if op == 'struct': path_length = len(extra['spath']) path = ida_pro.tid_array(path_length) for i in range(path_length): sname = str(extra['spath'][i]) path[i] = ida_struct.get_struc_id(sname) insn = ida_ua.insn_t() ida_ua.decode_insn(insn, ea) ida_bytes.op_stroff(insn, n, path.cast(), path_length, extra['delta'])
def createStruct(self, name): sid = ida_struct.get_struc_id(name) if sid != -1: idc.del_struc(sid) sid = idc.add_struc(-1, name, 0) self.types_id["name"] = sid return sid
def set_all_structures(dictionary, overwrite=False, conflicts=None, retry_len=-1): retry = {} for name, new_struct_def in dictionary.iteritems(): cur_sid = ida_struct.get_struc_id(name) if cur_sid != idc.BADADDR: # A structure exists with this name cur_struct = ida_struct.get_struc(cur_sid) cur_struct_size = ida_struct.get_struc_size(cur_sid) cur_struct_def = psida_common.get_struct_def(cur_struct.ordinal) if cur_struct_def == new_struct_def: #Skip if they're the same continue else: # Otherwise create a conflict conflicts[name] = (cur_struct.ordinal, cur_struct_size, new_struct_def) continue success = psida_common.create_struct(name, new_struct_def) if not success: retry[name] = new_struct_def if retry and retry_len != len(retry.keys()): print "Retrying structures: {}".format(retry.keys()) set_all_structures(retry, overwrite, conflicts, retry_len=len(retry.keys()))
def makeArrType(self, offset): idc.SetType(offset, "arrayType") sid = ida_struct.get_struc_id("arrayType") addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) addr = self.getPtr(sid, offset, "slice") self.handle_offset(addr)
def processIMethods(self, offst, size): sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod")) comm = [] for i in xrange(size): comm.append(self.processIMethod(offst + i * sz)) idc.set_cmt(offst, "\n".join(comm), 0) return comm
def __call__(self): if self.op == "hex": ida_bytes.op_hex(self.ea, self.n) if self.op == "bin": ida_bytes.op_bin(self.ea, self.n) if self.op == "dec": ida_bytes.op_dec(self.ea, self.n) if self.op == "chr": ida_bytes.op_chr(self.ea, self.n) if self.op == "oct": ida_bytes.op_oct(self.ea, self.n) if self.op == "offset": ida_idc.op_plain_offset(self.ea, self.n, 0) if self.op == "enum": id = ida_enum.get_enum(self.extra["ename"]) ida_bytes.op_enum(self.ea, self.n, id, self.extra["serial"]) if self.op == "struct": path_len = len(self.extra["spath"]) path = ida_pro.tid_array(path_len) for i in range(path_len): sname = self.extra["spath"][i] path[i] = ida_struct.get_struc_id(sname) insn = ida_ua.insn_t() ida_ua.decode_insn(insn, self.ea) ida_bytes.op_stroff(insn, self.n, path.cast(), path_len, self.extra["delta"]) if self.op == "stkvar": ida_bytes.op_stkvar(self.ea, self.n)
def __call__(self): if self.op == 'hex': ida_bytes.op_hex(self.ea, self.n) if self.op == 'bin': ida_bytes.op_bin(self.ea, self.n) if self.op == 'dec': ida_bytes.op_dec(self.ea, self.n) if self.op == 'chr': ida_bytes.op_chr(self.ea, self.n) if self.op == 'oct': ida_bytes.op_oct(self.ea, self.n) if self.op == 'enum': id = ida_enum.get_enum(Event.encode(self.extra['ename'])) ida_bytes.op_enum(self.ea, self.n, id, self.extra['serial']) if self.op == 'struct': path_len = len(self.extra['spath']) path = ida_pro.tid_array(path_len) for i in xrange(path_len): sname = Event.encode(self.extra['spath'][i]) path[i] = ida_struct.get_struc_id(sname) insn = ida_ua.insn_t() ida_ua.decode_insn(insn, self.ea) ida_bytes.op_stroff(insn, self.n, path.cast(), path_len, self.extra['delta']) if self.op == 'stkvar': ida_bytes.op_stkvar(self.ea, self.n)
def handle_offset(self, offset): #Check if we already parse this if offset in self.type_addr: return print ("Processing: %x" % offset) self.type_addr.append(offset) #Set type and get name idc.SetType(offset, "type") name = self.getName(offset) idc.set_cmt(offset, name, 0) #get kind name kind_name = self.getKindEnumName(offset) print (kind_name) if name[0] == "*" and kind_name != "PTR": name = name[1:] name = Utils.relaxName(name) Utils.rename(offset, name) self.betterTypePlease(offset) sid = ida_struct.get_struc_id("type") addr = self.getPtrToThis(sid, offset) if addr != 0: addr = self.getOffset(addr) self.handle_offset(addr) return if kind_name != "FUNC": self.processUncommon(sid, offset)
def getName(self, offset): sid = ida_struct.get_struc_id("type") string_addr = offset + idc.get_member_offset(sid, "string") ptr = self.stepper.ptr(string_addr) idc.SetType(ptr, "string") name = self.stepper.ptr(ptr) return idc.GetString(name)
def getKindEnumName(self, addr): try: struc_id = ida_struct.get_struc_id("type") offset_kind = idc.get_member_offset(struc_id, "kind") kind = idc.get_wide_byte(addr + offset_kind) & 0x1F return self.settings.typer.standardEnums[0][1][kind] except IndexError as e: pass
def parseFuncType(self, offset): return sid = ida_struct.get_struc_id("funcType") in_size = idc.Word(offset + idc.get_member_offset(sid, "incount")) out_size = idc.Word(offset + idc.get_member_offset(sid, "outcount")) sz = ida_struct.get_struc_size(sid) for i in xrange(in_size + out_size): idc.SetType(offset + sz + i * self.stepper.size, "type *")
def getType(self, addr): print ("%x" % addr) sid = ida_struct.get_struc_id("type") name = self.getName(addr) if self.getKindEnumName(addr) != "PTR": while name[0] == "*": name = name[1:] return name
def apply_struct_offset(inst, operand_no, struct_name): if not import_type(struct_name): print "ERROR: Can't import '{}'".format(struct_name) return path_len = 1 path = ida_pro.tid_array(path_len) path[0] = ida_struct.get_struc_id(struct_name) ida_bytes.op_stroff(inst, operand_no, path.cast(), path_len, 0)
def get_member_substruct(member): member_type = get_member_tinfo(member) if member_type is not None and member_type.is_struct(): current_struct_id = ida_struct.get_struc_id(member_type.get_type_name()) return ida_struct.get_struc(current_struct_id) elif member.flag & idaapi.FF_STRUCT == idaapi.FF_STRUCT: return ida_struct.get_sptr(member) return None
def __call__(self): mt = ida_nalt.opinfo_t() if ida_bytes.is_struct(self.flag): mt.tid = ida_struct.get_struc_id(self.extra["struc_name"]) if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag): mt.ri = ida_nalt.refinfo_t() mt.ri.init( self.extra["flags"], self.extra["base"], self.extra["target"], self.extra["tdelta"], ) if ida_bytes.is_strlit(self.flag): mt.strtype = self.extra["strtype"] struc = ida_struct.get_struc_id(self.sname) sptr = ida_struct.get_struc(struc) ida_struct.set_member_type(sptr, self.soff, self.flag, mt, self.eoff - self.soff)
def __call__(self): struc = ida_struct.get_struc_id(self.sname) sptr = ida_struct.get_struc(struc) cmt = self.cmt if self.cmt else "" if self.smname: mptr = ida_struct.get_member_by_name(sptr, self.smname) ida_struct.set_member_cmt(mptr, cmt, self.repeatable_cmt) else: ida_struct.set_struc_cmt(sptr.id, cmt, self.repeatable_cmt)
def processStructField(self, addr, index): offset = addr + index sid = ida_struct.get_struc_id("structField") ptr = self.getPtr(sid, offset, "Name") ln = idc.get_wide_byte(ptr + 2) fieldName = self.get_str(ptr + 3, ln) Utils.rename(ptr, fieldName) ptr = self.getPtr(sid, offset, "typ") self.handle_offset(ptr)
def makeMap(self, offset): idc.SetType(offset, "mapType") sid = ida_struct.get_struc_id("mapType") addr = self.getPtr(sid, offset, "key") self.handle_offset(addr) addr = self.getPtr(sid, offset, "elem") self.handle_offset(addr) addr = self.getPtr(sid, offset, "bucket") self.handle_offset(addr)
def processStructField(self, addr, index): offset = addr + index sid = ida_struct.get_struc_id("structField") ptr = self.getPtr(sid, offset, "Name") if ptr != 0: idc.SetType(ptr, "string") fieldName = idc.GetString(self.stepper.ptr(ptr)) Utils.rename(ptr, fieldName) ptr = self.getPtr(sid, offset, "typ") self.handle_offset(ptr)
def __call__(self): struc = ida_struct.get_struc_id(Event.encode(self.sname)) sptr = ida_struct.get_struc(struc) cmt = Event.encode(self.cmt if self.cmt else '') if self.smname: mptr = ida_struct.get_member_by_name(sptr, Event.encode(self.smname)) ida_struct.set_member_cmt(mptr, cmt, self.repeatable_cmt) else: ida_struct.set_struc_cmt(sptr.id, cmt, self.repeatable_cmt)
def get_struc_from_tinfo(struct_tif): if not struct_tif: return None if not is_struct_or_union(struct_tif): return None struct_id = ida_struct.get_struc_id(struct_tif.get_type_name()) if struct_id == BADADDR: return None struct = ida_struct.get_struc(struct_id) return struct
def get_struc_from_tinfo(struct_tinfo): if ida_hexrays.init_hexrays_plugin() and ( not (struct_tinfo.is_struct() or struct_tinfo.is_union())): return None struct_id = ida_struct.get_struc_id(struct_tinfo.get_type_name()) if struct_id == BADADDR: return None struct = ida_struct.get_struc(struct_id) return struct
def typeset_reg_for_address(ea, reg, type_name): opnds = sark.Line(ea).insn.operands for i in range(len(opnds)): if ('[%s]' % get_reg_user_name(ea, reg) in opnds[i].text) or ('[%s,' % get_reg_user_name(ea, reg) in opnds[i].text): str_id = ida_struct.get_struc_id(type_name) idc.op_stroff(ea, i, str_id, 0) ida_nalt.set_aflags(ea, ida_nalt.get_aflags(ea) | ida_nalt.AFL_ZSTROFF)
def get_guid_tid(): tid = ida_struct.get_struc_id('GUID') if tid == idaapi.BADADDR: print("[*] create GUID struct") tid = ida_struct.add_struc(0xffffffff, 'GUID', 0) sptr = ida_struct.get_struc(tid) ida_struct.add_struc_member(sptr, 'Data1', 0x0, 0x20000000, None, 4) ida_struct.add_struc_member(sptr, 'Data2', 0x4, 0x10000000, None, 2) ida_struct.add_struc_member(sptr, 'Data3', 0x6, 0x10000000, None, 2) ida_struct.add_struc_member(sptr, 'Data4', 0x8, 0x00000000, None, 8) return tid
def find_or_create_struct(name): sid = ida_struct.get_struc_id(name) if sid == idc.BADADDR: sid = idc.add_struc(-1, name, 0) print("added struct \"{0}\", id: {1}".format(name, sid)) else: print("struct \"{0}\" already exists, id: ".format(name, sid)) add_struct_to_idb(name) return sid
def add_packed_type (name, decl, unique = False): if ida_struct.get_struc_id (name) != BADADDR: if unique: raise RuntimeError ("struct %s already exists" % (name)) else: idc_parse_types (""" #pragma pack (push, 1) struct %s { %s }; #pragma pack (pop, 1)""" % (name, decl), 0) import_type (cvar.idati, -1, name) print "## DECLARED ", name return name