예제 #1
0
 def implement(self):
     ida_struct.set_struc_name(self._id, self._name)
 def __call__(self):
     struc = ida_struct.get_struc_id(Event.encode(self.oldname))
     ida_struct.set_struc_name(struc, Event.encode(self.newname))
예제 #3
0
 def __call__(self):
     struc = ida_struct.get_struc_id(self.oldname)
     ida_struct.set_struc_name(struc, self.newname)
예제 #4
0
파일: llvm.py 프로젝트: akiym/idawasm2
    def analyze_function_frame(self, function: Function) -> None:
        """
        inspect the given function to determine the frame layout and set references appropriately.

        args:
          function (Function): function instance.
        """
        # given a function prologue like the following:
        #
        #     23 80 80 80 80 00       get_global          $global0
        #     21 04                   set_local           $local4
        #     41 20                   i32.const           0x20
        #     21 05                   set_local           $local5
        #     20 04                   get_local           $local4
        #     20 05                   get_local           $local5
        #     6B                      i32.sub
        #     21 06                   set_local           $local6
        #
        # recognize that the function frame is 0x20 bytes.

        if not self.has_llvm_prologue(function):
            return

        bc = self.get_prologue_bc(function['offset'])
        if len(bc) == 0:
            return

        global_frame_pointer = bc[0].imm.global_index
        frame_size = bc[2].imm.value
        local_frame_pointer = bc[7].imm.local_index

        # add a frame structure to the function
        f = ida_funcs.get_func(function['offset'])
        ida_frame.add_frame(f, 0x0, 0x0, frame_size)
        ida_struct.set_struc_name(f.frame, 'frame%d' % function['index'])

        # ensure global variable $frame_stack is named appropriately
        ida_name.set_name(self.proc.globals[global_frame_pointer]['offset'],
                          '$frame_stack')

        # re-map local variable to $frame_pointer
        ida_frame.add_regvar(f, function['offset'],
                             function['offset'] + function['size'],
                             '$local%d' % local_frame_pointer,
                             '$frame_pointer', '')

        # define the frame structure layout by scanning for references within this function
        frame_references = self.find_function_frame_references(
            function, local_frame_pointer)
        for frame_offset, refs in frame_references.items():

            member_name = 'field_%x' % frame_offset
            for ref in refs:
                if 'parameter' in ref:
                    member_name = 'param%d' % (ref['parameter'])

            # pick largest element size for the element type
            flags = 0
            size = 0
            for ref in refs:
                fl = {
                    'i8': ida_bytes.FF_BYTE | ida_bytes.FF_DATA,
                    'i16': ida_bytes.FF_WORD | ida_bytes.FF_DATA,
                    'i32': ida_bytes.FF_DWORD | ida_bytes.FF_DATA,
                    'i64': ida_bytes.FF_QWORD | ida_bytes.FF_DATA,
                    'f32': ida_bytes.FF_FLOAT | ida_bytes.FF_DATA,
                    'f64': ida_bytes.FF_DOUBLE | ida_bytes.FF_DATA,
                }[ref['element_size']]

                s = {
                    'i8': 1,
                    'i16': 2,
                    'i32': 4,
                    'i64': 8,
                    'f32': 4,
                    'f64': 8,
                }[ref['element_size']]

                # by luck, FF_BYTE < FF_WORD < FF_DWORD < FF_QWORD,
                # so we can order flag values.
                if fl > flags:
                    flags = fl
                    size = s

            logger.debug('adding frame member %s to function %d', member_name,
                         function['index'])
            ida_struct.add_struc_member(ida_struct.get_struc(f.frame),
                                        member_name, frame_offset,
                                        flags & 0xFFFFFFFF, None, size)

        # mark struct references
        for refs in frame_references.values():
            for ref in refs:
                # set type of operand 0 to function frame structure offset
                # ref: https://github.com/idapython/src/blob/a3855ab969fd16758b3de007525feeba3a920344/tools/inject_pydoc/bytes.py#L5
                insn = ida_ua.insn_t()
                if not ida_ua.decode_insn(insn, ref['offset']):
                    continue

                path = ida_pro.tid_array(1)
                path[0] = f.frame
                ida_bytes.op_stroff(insn, 0, path.cast(), 1, 0)
예제 #5
0
def install_vtables_union(class_name, class_vtable_member=None, vtable_member_tinfo=None, offset=0):
    # pylint: disable=too-many-locals
    # TODO: this function is too big and must be refactored
    log.debug(
        "install_vtables_union(%s, %s, %s)",
        class_name,
        class_vtable_member,
        str(vtable_member_tinfo),
    )
    if class_vtable_member and vtable_member_tinfo:
        old_vtable_sptr = utils.extract_struct_from_tinfo(vtable_member_tinfo)
        old_vtable_class_name = ida_struct.get_struc_name(old_vtable_sptr.id)
    else:
        old_vtable_class_name = get_class_vtable_struct_name(class_name, offset)
        old_vtable_sptr = utils.get_sptr_by_name(old_vtable_class_name)
    vtables_union_name = old_vtable_class_name
    if old_vtable_sptr and not ida_struct.set_struc_name(
        old_vtable_sptr.id, old_vtable_class_name + "_orig"
    ):
        # FIXME: why log exception?
        log.exception(
            "Failed changing %s->%s_orig",
            old_vtable_class_name,
            old_vtable_class_name,
        )
        # FIXME: why -1 and not None?
        return -1
    vtables_union_id = utils.get_or_create_struct_id(vtables_union_name, True)
    vtable_member_tinfo = utils.get_typeinf(old_vtable_class_name + "_orig")
    if vtables_union_id == BADADDR:
        log.exception(
            "Cannot create union vtable for %s()%s",
            class_name,
            vtables_union_name,
        )
        # FIXME: why -1 and not None?
        return -1

    vtables_union = ida_struct.get_struc(vtables_union_id)
    if not vtables_union:
        log.exception("Could retrieve vtables union for %s", class_name)
        # FIXME: return -1?
    if vtable_member_tinfo is not None:
        vtables_union_vtable_field_name = get_class_vtables_field_name(class_name)
    else:
        vtables_union_vtable_field_name = get_interface_empty_vtable_name()
    utils.add_to_struct(vtables_union, vtables_union_vtable_field_name, vtable_member_tinfo)
    parent_struct = utils.get_sptr_by_name(class_name)
    flag = idaapi.FF_STRUCT
    mt = idaapi.opinfo_t()
    mt.tid = vtables_union_id
    struct_size = ida_struct.get_struc_size(vtables_union_id)
    vtables_union_ptr_type = utils.get_typeinf_ptr(vtables_union_name)
    if class_vtable_member:
        member_ptr = class_vtable_member
    else:
        # FIXME: add_struc_member returns error code, not member id
        member_id = ida_struct.add_struc_member(
            parent_struct,
            get_class_vtable_field_name(class_name),
            offset,
            flag,
            mt,
            struct_size,
        )
        # FIXME: get_member_by_id returns tuple, not member ptr
        member_ptr = ida_struct.get_member_by_id(member_id)
    ida_struct.set_member_tinfo(
        parent_struct,
        member_ptr,
        0,
        vtables_union_ptr_type,
        idaapi.TINFO_DEFINITE,
    )
    # FIXME: might be None! Is this OK, considering we return -1 everywhere else?
    return vtables_union
예제 #6
0
 def implement(self):
     sturc_id = ida_struct.get_struc_id(str(self._id))
     ida_struct.set_struc_name(sturc_id, self._name)
예제 #7
0
def install_vtables_union(
    class_name, class_vtable_member=None, vtable_member_tinfo=None, offset=0
):
    logging.debug(
        "install_vtables_union(%s, %s, %s)",
        class_name,
        class_vtable_member,
        str(vtable_member_tinfo),
    )
    if class_vtable_member and vtable_member_tinfo:
        old_vtable_sptr = utils.extract_struct_from_tinfo(vtable_member_tinfo)
        old_vtable_class_name = ida_struct.get_struc_name(old_vtable_sptr.id)
    else:
        old_vtable_class_name = get_class_vtable_struct_name(class_name, offset)
        old_vtable_sptr = utils.get_sptr_by_name(old_vtable_class_name)
    vtables_union_name = old_vtable_class_name
    if old_vtable_sptr and not ida_struct.set_struc_name(
        old_vtable_sptr.id, old_vtable_class_name + "_orig"
    ):
        logging.exception(
            f"Failed changing {old_vtable_class_name}->"
            f"{old_vtable_class_name+'orig'}"
        )
        return -1
    vtables_union_id = utils.get_or_create_struct_id(vtables_union_name, True)
    vtable_member_tinfo = utils.get_typeinf(old_vtable_class_name + "_orig")
    if vtables_union_id == BADADDR:
        logging.exception(
            f"Cannot create union vtable for {class_name}(){vtables_union_name}"
        )
        return -1

    vtables_union = ida_struct.get_struc(vtables_union_id)
    if not vtables_union:
        logging.exception(f"Could retrieve vtables union for {class_name}")
    if vtable_member_tinfo is not None:
        vtables_union_vtable_field_name = get_class_vtables_field_name(class_name)
    else:
        vtables_union_vtable_field_name = get_interface_empty_vtable_name()
    utils.add_to_struct(
        vtables_union, vtables_union_vtable_field_name, vtable_member_tinfo
    )
    parent_struct = utils.get_sptr_by_name(class_name)
    flag = idaapi.FF_STRUCT
    mt = idaapi.opinfo_t()
    mt.tid = vtables_union_id
    struct_size = ida_struct.get_struc_size(vtables_union_id)
    vtables_union_ptr_type = utils.get_typeinf_ptr(vtables_union_name)
    if class_vtable_member:
        member_ptr = class_vtable_member
    else:
        member_id = ida_struct.add_struc_member(
            parent_struct,
            get_class_vtable_field_name(class_name),
            offset,
            flag,
            mt,
            struct_size,
        )
        member_ptr = ida_struct.get_member_by_id(member_id)
    ida_struct.set_member_tinfo(
        parent_struct, member_ptr, 0, vtables_union_ptr_type, idaapi.TINFO_DEFINITE
    )
    return vtables_union