def fillStruct(self, sid, data): for i in data: new_type = None # (i1, i2, i3) = self.stepper.parseField(i[1]) name = i[1] if name[0] == "*": name = name[1:] if i[1] != "uintptr": i1, i2, i3 = (idc.FF_BYTE | idc.FF_DATA, -1, 1) else: i1, i2, i3 = self.uintptr if name == i[1]: new_type = i[1] else: new_type = name + " *" res = idc.add_struc_member(sid, i[0], -1, i1, i2, i3) use_name = i[0] if res == -1: # Bad name # print "Bad name %s for struct member" % i[0] use_name = i[0] + "_autogen_" + id_generator() idc.add_struc_member(sid, use_name, -1, i1, i2, i3) if new_type is not None: offset = idc.get_member_offset(sid, use_name) # print "Setting %s as %s" % (i[0], new_type) idc.SetType(idc.get_member_id(sid, offset), new_type)
def struct_add_ptr(sid, name, offset, count=1, type=None): """Add a pointer to a structure. If sid is a union, offset must be -1. """ ptr_flag = idc.FF_DATA | word_flag(WORD_SIZE) | ida_bytes.off_flag() ret = idc.add_struc_member(sid, name, offset, ptr_flag, 0, WORD_SIZE) if ret == 0 and type is not None: if offset == -1: offset = struct_member_offset(sid, name) assert offset is not None mid = idc.get_member_id(sid, offset) idc.SetType(mid, type) return ret
def get_variable_name(self, ea_or_stack_tuple): """ Returns the name of the variable for the given ea or stack tuple. :param ea_or_stack_tuple: ea address or tuple containing: (frame_id, stack_offset) :return: string of name or None """ if isinstance(ea_or_stack_tuple, tuple): frame_id, stack_offset = ea_or_stack_tuple member_id = idc.get_member_id(frame_id, stack_offset) return ida_struct.get_member_fullname(member_id) else: ea = ea_or_stack_tuple name = idc.get_name(ea) if name: return name _, original_location = self.get_original_location(ea) if original_location: return self.get_variable_name(original_location)
def _propagate_virtual_method_type_for_method(classinfo, class_vindex, vmethod): """Propagate the type of a class's virtual method to the vtable struct.""" if not idau.is_function_start(vmethod): _log(2, 'Not a function start: {:x}', vmethod) return False vmethod_type = idc.guess_type(vmethod) if not vmethod_type: _log(2, 'No guessed type: {:x}', vmethod) return False vmethod_ptr_type = symbol.convert_function_type_to_function_pointer_type(vmethod_type) if not vmethod_ptr_type: _log(2, 'Could not convert to function pointer type: {:x}', vmethod) return False vmethods_sid = idau.struct_open(classinfo.classname + '::vmethods') vmethod_offset = class_vindex * idau.WORD_SIZE vmethod_mid = idc.get_member_id(vmethods_sid, vmethod_offset) if not bool(idc.SetType(vmethod_mid, vmethod_ptr_type)): _log(2, 'Could not set vmethod field type: {:x}, {}, {}', vmethod, classinfo.classname, class_vindex) return False return True
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 mid(self): return get_member_id(self._sid, self._offset)
def construct_class(name): sid = idc.add_struc(-1, name, 0) idc.add_struc_member(sid, "IOUserClient", 0, idc.FF_DATA, -1, 0x1000) idc.SetType(idc.get_member_id(sid, 0), "IOUserClient IOUserClient") idc.add_struc_member(sid, "clientData", -1, idc.FF_DATA, -1, 0x1000) classMap[name] = sid