def structure_info_create(vtbs):
    for vtb in vtbs:
        vtb_name = "vtb_" + (hex(vtb.get("vtb_start_addr"))[2:-1]).upper()
        # 创建结构体
        udt_data = idaapi.udt_type_data_t()

        # 函数名称记录列表
        func_name_records_list = []

        # 添加结构体的成员
        for mem in vtb.get('vtb_func_lists'):
            # 创建成员
            udt_member = idaapi.udt_member_t()
            udt_member.type = ptr_type("DWORD")
            udt_member.name = name_filter(mem.get('func_name'))
            # 如果名字为空,需要进行特殊的处理
            # MEMORY[xxxx]
            # print udt_member.name
            if udt_member.name == None or udt_member.name == "":
                udt_member.name = "memory_" + (hex(
                    mem.get("func_addr"))[2:]).upper()
            # 防止函数名称重复
            if udt_member.name in func_name_records_list:
                udt_member.name += "1"
            func_name_records_list.append(udt_member.name)
            # print udt_member.name
            # 插入结构体
            udt_data.push_back(udt_member)
        build_structure_in_ida(udt_data, vtb_name)
Exemple #2
0
 def type_equals_to(self, tinfo):
     udt_data = idaapi.udt_type_data_t()
     if tinfo.is_ptr() and tinfo.get_pointed_object().get_udt_details(
             udt_data):
         if udt_data[0].type.is_funcptr():
             return True
     return False
Exemple #3
0
    def find_containing_structures(self, type_library):
        """
        Given the type library creates a list of structures from this library, that contains this structure and
        satisfy offset conditions.
        :param type_library: idaapi.til_t
        :returns: ordinal, offset, member_name, containing structure name
        """

        min_offset = min(self.offsets)
        min_offset = min_offset if min_offset < 0 else 0
        max_offset = max(self.offsets)
        max_offset = max_offset if max_offset > 0 else self.tinfo.get_size()
        # TODO: Check if all offsets are legal

        # Least acceptable size of the containing structure
        min_struct_size = max_offset - min_offset
        result = []
        parent_tinfo = idaapi.tinfo_t()
        udt_data = idaapi.udt_type_data_t()
        target_tinfo = idaapi.tinfo_t()
        if not target_tinfo.get_named_type(type_library, self.tinfo.dstr()):
            print "[Warning] Such type doesn't exist in '{0}' library".format(
                type_library.name)
            return result
        for ordinal in xrange(1, idaapi.get_ordinal_qty(type_library)):
            parent_tinfo.create_typedef(type_library, ordinal)
            if parent_tinfo.get_size() >= min_struct_size:
                for offset, name in find_deep_members(parent_tinfo,
                                                      target_tinfo):
                    # print "[DEBUG] Found {0} at {1} in {2}".format(name, offset, parent_tinfo.dstr())
                    if offset + min_offset >= 0 and offset + max_offset <= parent_tinfo.get_size(
                    ):
                        result.append(
                            (ordinal, offset, name, parent_tinfo.dstr()))
        return result
Exemple #4
0
def get_fields_at_offset(tinfo, offset):
    """
    Given tinfo and offset of the structure or union, returns list of all tinfo at that offset.
    This function helps to find appropriate structures by type of the offset
    """
    result = []
    if offset == 0:
        result.append(tinfo)
    udt_data = idaapi.udt_type_data_t()
    tinfo.get_udt_details(udt_data)
    udt_member = idaapi.udt_member_t()
    udt_member.offset = offset * 8
    idx = tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member)
    if idx != -1:
        while idx < tinfo.get_udt_nmembers(
        ) and udt_data[idx].offset <= offset * 8:
            udt_member = udt_data[idx]
            if udt_member.offset == offset * 8:
                if udt_member.type.is_ptr():
                    result.append(idaapi.get_unk_type(Const.EA_SIZE))
                    result.append(udt_member.type)
                    result.append(idaapi.dummy_ptrtype(Const.EA_SIZE, False))
                elif not udt_member.type.is_udt():
                    result.append(udt_member.type)
            if udt_member.type.is_array():
                if (offset - udt_member.offset / 8
                    ) % udt_member.type.get_array_element().get_size() == 0:
                    result.append(udt_member.type.get_array_element())
            elif udt_member.type.is_udt():
                result.extend(
                    get_fields_at_offset(udt_member.type,
                                         offset - udt_member.offset / 8))
            idx += 1
    return result
 def visit_expr(self, expression):
     if expression.op == idaapi.cot_call and expression.x.op == idaapi.cot_helper and len(
             expression.a) == 3:
         if expression.x.helper == "CONTAINING_RECORD":
             if expression.a[0].op == idaapi.cot_var:
                 idx = expression.a[0].v.idx
                 if expression.a[1].op == idaapi.cot_helper and expression.a[
                         2].op == idaapi.cot_helper:
                     parent_name = expression.a[1].helper
                     member_name = expression.a[2].helper
                     parent_tinfo = idaapi.tinfo_t()
                     if not parent_tinfo.get_named_type(
                             idaapi.cvar.idati, parent_name):
                         return 0
                     udt_data = idaapi.udt_type_data_t()
                     parent_tinfo.get_udt_details(udt_data)
                     udt_member = filter(lambda x: x.name == member_name,
                                         udt_data)
                     if udt_member:
                         tinfo = udt_member[0].type
                         self.result[idx] = NegativeLocalInfo(
                             tinfo, parent_tinfo, udt_member[0].offset // 8,
                             member_name)
                         return 1
     return 0
Exemple #6
0
 def type(self):
     self.ti = idaapi.tinfo_t()
     self.sti = idaapi.udt_type_data_t()
     if idaapi.guess_tinfo(self.id, self.ti) != idaapi.GUESS_FUNC_OK:
         print "[-] can't guess `%s` type" % self.name
         return
     return Type(self.ti)
Exemple #7
0
    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
Exemple #8
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 get_members_ordinals(tinfo):
     ordinals = []
     if tinfo.is_udt():
         udt_data = idaapi.udt_type_data_t()
         tinfo.get_udt_details(udt_data)
         for udt_member in udt_data:
             ordinal = StructureGraph.get_ordinal(udt_member.type)
             if ordinal:
                 ordinals.append(ordinal)
     return ordinals
Exemple #10
0
 def update_local_type(self):
     if self.modified:
         for vtable in list(self.vtables.values()):
             vtable.update_local_type()
         udt_data = idaapi.udt_type_data_t()
         tinfo = idaapi.tinfo_t()
         self.tinfo.get_udt_details(udt_data)
         tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
         tinfo.set_numbered_type(idaapi.cvar.idati, self.ordinal, idaapi.NTF_REPLACE, self.name)
         self.modified = False
    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
        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, cdecl,
                               "The following new type will be created")

        if cdecl:
            structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl,
                                                   idaapi.PT_TYP)[0]
            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_scanned_variables(origin):
                        scanned_var.apply_type(ptr_tinfo)
                    return tinfo
            else:
                print "[ERROR] Structure {0} probably already exist".format(
                    structure_name)
        return None
    def create_tinfo(self):
        # print "(Virtual table) at address: 0x{0:08X} name: {1}".format(self.address, self.name)
        udt_data = idaapi.udt_type_data_t()
        for function in self.virtual_functions:
            udt_data.push_back(function.get_udt_member())

        final_tinfo = idaapi.tinfo_t()
        if final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT):
            # print "\n\t(Final structure)\n" + idaapi.print_tinfo('\t', 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE
            #                                                      | idaapi.PRTYPE_SEMI, final_tinfo, self.name, None)
            return final_tinfo
        print "[ERROR] Virtual table creation failed"
def find_deep_members(parent_tinfo, target_tinfo):
    udt_data = idaapi.udt_type_data_t()
    parent_tinfo.get_udt_details(udt_data)
    result = []
    for udt_member in udt_data:
        if udt_member.type.equals_to(target_tinfo):
            result.append((udt_member.offset / 8, udt_member.name))
        elif udt_member.type.is_udt():
            for offset, name in find_deep_members(udt_member.type, target_tinfo):
                final_name = udt_member.name + '.' + name if udt_member.name else name
                result.append((udt_member.offset / 8 + offset, final_name))
    return result
Exemple #14
0
 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
Exemple #15
0
 def update(self):
     if self.modified:
         vtable_tinfo = idaapi.tinfo_t()
         udt_data = idaapi.udt_type_data_t()
         vtable_tinfo.get_numbered_type(idaapi.cvar.idati, self.ordinal)
         vtable_tinfo.get_udt_details(udt_data)
         self.tinfo = vtable_tinfo
         self.name = vtable_tinfo.dstr()
         self.modified = False
         if len(self.virtual_functions) == len(udt_data):
             for current_function, other_function in zip(self.virtual_functions, udt_data):
                 current_function.update(other_function.name, other_function.type)
         else:
             print("[ERROR] Something have been modified in Local types. Please refresh this view")
Exemple #16
0
    def tinfo(self):
        udt = idaapi.udt_type_data_t()
        for m in self.members:
            new_member = idaapi.udt_member_t()
            new_member.name = m.name
            new_member.type = m.tinfo
            new_member.size = m.size
            new_member.offset = m.offset

            udt.push_back(new_member)

        final_tinfo = idaapi.tinfo_t()
        if final_tinfo.create_udt(udt, idaapi.BTF_STRUCT):
            return final_tinfo
Exemple #17
0
    def __init__(self, ti):
        self.ti = ti
        self.extra = None
        if self.ti.is_func():
            self.extra = idaapi.func_type_data_t()
            if not self.ti.get_func_details(self.extra):
                print "[-] can't get function's type details"
                return

        elif self.ti.is_struct():
            self.extra = idaapi.udt_type_data_t()
            if not self.ti.get_udt_details(self.extra):
                print "[-] can't get struct's type details"
                return
Exemple #18
0
 def update_local_type(self):
     if self.modified:
         final_tinfo = idaapi.tinfo_t()
         udt_data = idaapi.udt_type_data_t()
         self.tinfo.get_udt_details(udt_data)
         if len(udt_data) == len(self.virtual_functions):
             for udt_member, virtual_function in zip(udt_data, self.virtual_functions):
                 udt_member.name = virtual_function.name
                 udt_member.type = virtual_function.tinfo
                 virtual_function.commit()
             final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
             final_tinfo.set_numbered_type(idaapi.cvar.idati, self.ordinal, idaapi.NTF_REPLACE, self.name)
             self.modified = False
         else:
             print("[ERROR] Something have been modified in Local types. Please refresh this view")
Exemple #19
0
 def create_class(ordinal):
     tinfo = idaapi.tinfo_t()
     tinfo.get_numbered_type(idaapi.cvar.idati, ordinal)
     vtables = {}
     if tinfo.is_struct():
         udt_data = idaapi.udt_type_data_t()
         tinfo.get_udt_details(udt_data)
         for field_udt in udt_data:
             if field_udt.type.is_ptr():
                 possible_vtable = field_udt.type.get_pointed_object()
                 if possible_vtable.is_struct():
                     v_udt_data = idaapi.udt_type_data_t()
                     possible_vtable.get_udt_details(v_udt_data)
                     for possible_func_udt in v_udt_data:
                         if not possible_func_udt.type.is_funcptr():
                             break
                     else:
                         vtables[field_udt.offset // 8] = possible_vtable
     if vtables:
         class_ = Class(tinfo.dstr(), tinfo, ordinal)
         for offset, vtable_tinfo in vtables.items():
             vtables[offset] = VirtualTable.create(vtable_tinfo, class_)
         class_.vtables = vtables
         return class_
Exemple #20
0
    def unpack_substructure(self, indices):

        if indices is None or len(indices) != 1:
            return

        item = self.items[indices[0].row()]
        if item.tinfo is not None and item.tinfo.is_udt():

            self.remove_items(indices)
            offset = item.offset
            udt_data = idaapi.udt_type_data_t()
            if item.tinfo.get_udt_details(udt_data):
                for udt_item in udt_data:
                    member = Member(offset + udt_item.offset / 8, udt_item.type, None)
                    member.name = udt_item.name
                    self.add_row(member)
Exemple #21
0
    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
Exemple #22
0
    def create_tinfo(self):
        # print "(Virtual table) at address: 0x{0:08X} name: {1}".format(self.address, self.name)
        udt_data = idaapi.udt_type_data_t()
        for function in self.virtual_functions:
            udt_data.push_back(function.get_udt_member())

        for duplicates in Helper.search_duplicate_fields(udt_data):
            first_entry_idx = duplicates.pop(0)
            print "[Warning] Found duplicate virtual functions", udt_data[first_entry_idx].name
            for num, dup in enumerate(duplicates):
                udt_data[dup].name = "duplicate_{0}_{1}".format(first_entry_idx, num + 1)
                tinfo = idaapi.tinfo_t()
                tinfo.create_ptr(Const.DUMMY_FUNC)
                udt_data[dup].type = tinfo

        final_tinfo = idaapi.tinfo_t()
        if final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT):
            # print "\n\t(Final structure)\n" + idaapi.print_tinfo('\t', 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE
            #                                                      | idaapi.PRTYPE_SEMI, final_tinfo, self.name, None)
            return final_tinfo
        print "[ERROR] Virtual table creation failed"
Exemple #23
0
    def __init__(self, type):

        self.logger = logging.getLogger(__name__)

        self.name = ""
        self.size = 0
        self.element_num = 0
        self.is_union = False

        self.elements = []

        self.type_info = type
        self.udt_type_data = idaapi.udt_type_data_t()


        try:
            if self.getStructData():
                self.getElements()

        except Exception as ex:
            self.logger.exception("Error while extracting Struct data: %s",
                          idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '', ''), ex)
            return False
Exemple #24
0
    def __init__(self, type):

        self.logger = logging.getLogger(__name__)

        self.name = ""
        self.size = 0
        self.element_num = 0
        self.is_union = False

        self.elements = []

        self.type_info = type
        self.udt_type_data = idaapi.udt_type_data_t()

        try:
            if self.getStructData():
                self.getElements()

        except Exception as ex:
            self.logger.exception(
                "Error while extracting Struct data: %s",
                idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, type, '',
                                   ''), ex)
            return False
Exemple #25
0
    def activate(self, ctx):
        hx_view = idaapi.get_widget_vdui(ctx.widget)
        if not self.check(hx_view):
            return

        item = hx_view.item.it.to_specific_type
        parent = hx_view.cfunc.body.find_parent_of(item).to_specific_type
        if parent.op != idaapi.cot_idx or parent.y.op != idaapi.cot_num:
            idx = 0
        else:
            idx = parent.y.numval()

        struct_tinfo = item.x.type
        struct_tinfo.remove_ptr_or_array()

        offset = item.m
        ordinal = struct_tinfo.get_ordinal()
        struct_name = struct_tinfo.dstr()

        if (offset + idx) % 2:
            default_field_type = "_BYTE"
        elif (offset + idx) % 4:
            default_field_type = "_WORD"
        elif (offset + idx) % 8:
            default_field_type = "_DWORD"
        else:
            default_field_type = "_QWORD" if const.EA64 else "_DWORD"

        declaration = idaapi.ask_text(
            0x10000, "{0} field_{1:X}".format(default_field_type, offset + idx), "Enter new structure member:"
        )
        if declaration is None:
            return

        result = self.parse_declaration(declaration)
        if result is None:
            logger.warn("Bad member declaration")
            return

        field_tinfo, field_name = result
        field_size = field_tinfo.get_size()
        udt_data = idaapi.udt_type_data_t()
        udt_member = idaapi.udt_member_t()

        struct_tinfo.get_udt_details(udt_data)
        udt_member.offset = offset * 8
        struct_tinfo.find_udt_member(udt_member, idaapi.STRMEM_OFFSET)
        gap_size = udt_member.size // 8

        gap_leftover = gap_size - idx - field_size

        if gap_leftover < 0:
            logger.error("Too big size for the field. Type with maximum {0} bytes can be used".format(gap_size - idx))
            return

        iterator = udt_data.find(udt_member)
        iterator = udt_data.erase(iterator)

        if gap_leftover > 0:
            udt_data.insert(iterator, helper.create_padding_udt_member(offset + idx + field_size, gap_leftover))

        udt_member = idaapi.udt_member_t()
        udt_member.offset = offset * 8 + idx
        udt_member.name = field_name
        udt_member.type = field_tinfo
        udt_member.size = field_size

        iterator = udt_data.insert(iterator, udt_member)

        if idx > 0:
            udt_data.insert(iterator, helper.create_padding_udt_member(offset, idx))

        struct_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
        struct_tinfo.set_numbered_type(idaapi.cvar.idati, ordinal, idaapi.BTF_STRUCT, struct_name)
        hx_view.refresh_view(True)
Exemple #26
0
    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)
Exemple #27
0
    def activate(self, ctx):
        hx_view = idaapi.get_tform_vdui(ctx.widget)
        result = self.check(hx_view.cfunc, hx_view.item)
        if result is None:
            return

        struct_tinfo, offset, idx = result
        ordinal = struct_tinfo.get_ordinal()
        struct_name = struct_tinfo.dstr()

        if (offset + idx) % 2:
            default_field_type = "_BYTE"
        elif (offset + idx) % 4:
            default_field_type = "_WORD"
        else:
            default_field_type = "_DWORD"

        declaration = idaapi.asktext(
            0x10000, "{0} field_{1:X}".format(default_field_type, offset + idx), "Enter new structure member:"
        )
        if declaration is None:
            return

        result = self.__parse_declaration(declaration)
        if result is None:
            return

        field_tinfo, field_name = result
        field_size = field_tinfo.get_size()
        udt_data = idaapi.udt_type_data_t()
        udt_member = idaapi.udt_member_t()

        struct_tinfo.get_udt_details(udt_data)
        udt_member.offset = offset * 8
        struct_tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member)
        gap_size = udt_member.size // 8

        gap_leftover = gap_size - idx - field_size

        if gap_leftover < 0:
            print "[ERROR] Too big size for the field. Type with maximum {0} bytes can be used".format(gap_size - idx)
            return

        iterator = udt_data.find(udt_member)
        iterator = udt_data.erase(iterator)

        if gap_leftover > 0:
            udt_data.insert(iterator, TemporaryStructureModel.get_padding_member(offset + idx + field_size, gap_leftover))

        udt_member = idaapi.udt_member_t()
        udt_member.offset = offset * 8 + idx
        udt_member.name = field_name
        udt_member.type = field_tinfo
        udt_member.size = field_size

        iterator = udt_data.insert(iterator, udt_member)

        if idx > 0:
            udt_data.insert(iterator, TemporaryStructureModel.get_padding_member(offset, idx))

        struct_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT)
        struct_tinfo.set_numbered_type(idaapi.cvar.idati, ordinal, idaapi.BTF_STRUCT, struct_name)
        hx_view.refresh_view(True)