示例#1
0
 def get_field_classname(self, idx):
     print("get_field_classname: addr = 0x%08X" %
           (self.ClassTypesTab + 2 + 4 * idx))
     addr = self.ClassTypesTab + 2 + 4 * idx
     print("get_field_classname: ClsAddr = 0x%08X" %
           ida_bytes.get_wide_dword(addr))
     return get_class_name(
         ida_bytes.get_wide_dword(ida_bytes.get_wide_dword(addr)))
示例#2
0
    def value(self):
        """
            Property which return the value corresponding to the data of a
            numberable elements. This property works only if the
            :meth:`~BipData.is_numerable` and :meth:`~BipData.has_data`
            properties returned True. For getting value of an element which
            is not numerable use the :meth:`~BipElt.bytes` property.

            This property is link to the type defined or guessed by IDA and
            it is a good idea to assure you have the proper type before using
            it.

            :return: An integer representing the value of the data or ``None``
                if the data element is not numerable or do not have data.
        """
        if not self.has_data:
            return None
        elif self.is_unknown or self.is_byte:
            return ida_bytes.get_wide_byte(self.ea)
        elif self.is_word:
            return ida_bytes.get_wide_word(self.ea)
        elif self.is_dword:
            return ida_bytes.get_wide_dword(self.ea)
        elif self.is_qword:
            return ida_bytes.get_qword(self.ea)
        else:
            return None
示例#3
0
    def get_mem_string(cls, addr):
        """
        获取内存中的字符串
        """

        addr_t = addr
        dref = idautils.DataRefsFrom(addr_t)
        strs = [cls.strings[x] for x in dref if x in cls.strings]

        # 处理几种特殊情况
        # LDR R1, =sub_xxxx
        # LDR R1, =loc_xxxx
        if idc.print_operand(addr, 1)[:5] in ['=sub_', '=loc_']:
            return []

        # LDR R1, =unk_53B4B6
        # .rodata:0053B4B6 http:
        # .rodata:0053B4BB //%s%s
        if strs != [] and strs[0].find('%') == -1:
            strs = []
            dref = idautils.DataRefsFrom(addr_t)
            for x in dref:
                segname = ida_segment.get_segm_name(ida_segment.getseg(x))
                if segname not in ['.text', '.bss']:
                    strs.append(cls.get_string_from_mem(x))

        # LDR R1, =(aFailedToGetAnI+0x22)
        # LDR R2, =(aSS - 0xCFA4)
        # ADD R2, PC, R2
        if strs == []:
            dref = idautils.DataRefsFrom(addr_t)
            for x in dref:
                segname = ida_segment.get_segm_name(ida_segment.getseg(x))
                if segname not in ['.text', '.bss']:
                    strs.append(cls.get_string_from_mem(x))
                elif len(list(idautils.DataRefsFrom(x))) == 0:
                    reg_t = idc.print_operand(addr_t, 0)
                    num1 = ida_bytes.get_wide_dword(x)
                    while get_mnem(addr_t) != 'ADD' or (idc.print_operand(addr_t, 0) != reg_t and idc.print_operand(addr_t, 1) != 'PC'):
                        addr_t = ida_bytes.next_head(addr_t, ida_idaapi.BADADDR)
                    num2 = addr_t + 8
                    addr_t = num1 + num2
                    strs.append(cls.get_string_from_mem(addr_t))

        # MOVW R1, #0x87B4
        # MOVT.W R1, #0x52
        if strs == [] and get_mnem(addr_t) == 'MOVW':
            reg_t = idc.print_operand(addr_t, 0)
            num1 = int(idc.print_operand(addr_t, 1).split('#')[1], 16)
            while get_mnem(addr_t) not in ['MOVTGT', 'MOVTLE', 'MOVT'] or idc.print_operand(addr_t, 0) != reg_t:
                addr_t = ida_bytes.next_head(addr_t, ida_idaapi.BADADDR)
            num2 = int(idc.print_operand(addr_t, 1).split('#')[1], 16)
            addr_t = (num2<<16) + num1
            strs.append(cls.get_string_from_mem(addr_t))

        return strs
示例#4
0
def get_call_args_arm(ea, count_max=10):
    """
    获得函数调用参数(当前仅支持4个参数)
    """

    args = {}

    mnem = ida_ua.ua_mnem(ea)
    if mnem != "BL" and mnem != "SVC" and mnem != "BLNE" and mnem != "BLHI" and mnem != "BLEQ":
        print(
            "Error: not a BL or SVC or BLNE or BLHI or BLEQ instruction at 0x%x"
            % ea)
        return None

    arg_inst_arm_mov = [
        "MOV     R0,", "MOV     R1,", "MOV     R2,", "MOV     R3,"
    ]
    arg_inst_arm_adr = [
        "ADR     R0,", "ADR     R1,", "ADR     R2,", "ADR     R3,"
    ]
    arg_inst_arm_ldr = [
        "LDR     R0,", "LDR     R1,", "LDR     R2,", "LDR     R3,"
    ]
    arg_inst_arm_adr2 = [
        "ADREQ   R0,", "ADREQ   R1,", "ADDEQ   R2,", "ADREQ   R3,"
    ]
    arg_inst_arm_mov2 = [
        "MOVEQ   R0,", "MOVEQ   R1,", "MOVEQ   R2,", "MOVEQ   R3,"
    ]
    arg_inst_arm_adr3 = [
        "ADRNE   R0,", "ADRNE   R1,", "ADDNE   R2,", "ADRNE   R3,"
    ]

    ea = ida_bytes.prev_head(ea, 0)
    count = 0
    while count <= count_max:
        disasm_line = idc.generate_disasm_line(ea, 0)
        for i in range(len(arg_inst_arm_mov)):
            #print("'%s'" % arg_inst_arm_mov[i])
            # 假设最接近调用的指令是赋值指令,忽略其他情况(如碰到另一个MOV reg)
            inst_list = [
                arg_inst_arm_mov[i], arg_inst_arm_mov2[i], arg_inst_arm_adr[i],
                arg_inst_arm_adr2[i], arg_inst_arm_adr3[i]
            ]
            if any(inst in disasm_line for inst in inst_list):
                if i not in args.keys():
                    args[i] = idc.get_operand_value(ea, 1)
                    print("Found argument %d: 0x%x" % (i, args[i]))
            elif arg_inst_arm_ldr[i] in disasm_line:
                if i not in args.keys():
                    addr = idc.get_operand_value(ea, 1)
                    args[i] = ida_bytes.get_wide_dword(addr)
                    print("Found argument %d: 0x%x" % (i, args[i]))
        ea = ida_bytes.prev_head(ea, 0)
        count += 1
    return args
示例#5
0
文件: ana_emu_out.py 项目: ylkcy/src
 def ev_ana_insn(self, insn):
     t_reg = ida_idp.str2reg("T")
     t = ida_segregs.get_sreg(insn.ea, t_reg)
     if t==0 and ida_bytes.get_wide_dword(insn.ea) == 0xE7F001F2:
         insn.itype = ITYPE_BUGINSN
         insn.size = 4
     elif t!=0 and ida_bytes.get_wide_word(insn.ea) == 0xde02:
         insn.itype = ITYPE_BUGINSN
         insn.size = 2
     return insn.size
示例#6
0
    def _init_func_thunk_ctrl_flow(self):
        """Initializes the control flow redirections and targets
        using function thunks"""

        # We only support the ELF format for now
        inf = ida_idaapi.get_inf_structure()
        if inf.filetype != ida_ida.f_ELF:
            return

        # List the function thunks first
        input_file_path = ida_nalt.get_input_file_path()
        image_parser = create_elf_image_parser(input_file_path)
        function_thunk_list = image_parser.get_function_thunk_list()

        # Go through each function thunk, and look at its cross references; there
        # should always be only one user, which is the wrapper around the imported
        # function
        is_32_bit = image_parser.get_image_bitness() == 32

        for function_thunk in function_thunk_list:
            thunk_va = function_thunk.start

            redirection_dest = (ida_bytes.get_wide_dword(thunk_va) if is_32_bit
                                else ida_bytes.get_qword(thunk_va))

            caller_address = ida_xref.get_first_cref_to(redirection_dest)
            if caller_address == ida_idaapi.BADADDR:
                continue

            redirection_source = idc.get_func_attr(caller_address,
                                                   idc.FUNCATTR_START)
            caller_function_name = ida_funcs.get_func_name(redirection_source)

            if function_thunk.name in caller_function_name:
                print(
                    "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}"
                    .format(
                        redirection_source,
                        function_thunk.name,
                        function_thunk.start,
                        redirection_dest,
                    ))

                self.add_control_flow_redirection(redirection_source,
                                                  redirection_dest)

            print(
                "anvill: Adding target list {:x} -> [{:x}, complete=True] for {}"
                .format(caller_address, redirection_dest, function_thunk.name))

            self.set_control_flow_targets(caller_address, [redirection_dest],
                                          True)
示例#7
0
 def parse(self, addr):
     print("ClassRTTI: parse addr 0x%08X" % addr)
     self.addr = addr
     if get_field_table_addr(addr):
         self.FieldTable = FieldTable().parse(get_field_table_addr(addr))
     self.ClassName = get_class_name(addr)
     self.InstanceSize = get_instance_size(addr)
     self.ParentAddr = get_parent_addr(addr)
     print("ClassRTTI: parse addr 0x%08X" % addr)
     if self.ParentAddr:
         self.Parent = ClassRTTI().parse(
             ida_bytes.get_wide_dword(self.ParentAddr))
     return self
示例#8
0
    def _init_ctrl_flow_redirections(self):
        """Initializes the control flow redirections using function thunks"""

        # We only support the ELF format for now
        inf = ida_idaapi.get_inf_structure()
        if inf.filetype != ida_ida.f_ELF:
            return

        # List the function thunks first
        input_file_path = ida_nalt.get_input_file_path()
        image_parser = create_elf_image_parser(input_file_path)
        function_thunk_list = image_parser.get_function_thunk_list()

        # Go through each function thunk, and look at its cross references; there
        # should always be only one user, which is the wrapper around the imported
        # function
        #
        # Note that the __libc_start_main # thunk does not need redirection since
        # it's called directly without any wrapper function from the module entry
        # point
        is_32_bit = image_parser.get_image_bitness() == 32

        for function_thunk in function_thunk_list:
            if function_thunk.name == "__libc_start_main":
                continue

            thunk_va = ida_nalt.get_imagebase() + function_thunk.start

            redirection_dest = (
                ida_bytes.get_wide_dword(thunk_va)
                if is_32_bit
                else ida_bytes.get_qword(thunk_va)
            )

            caller_address = ida_xref.get_first_cref_to(redirection_dest)
            if caller_address == ida_idaapi.BADADDR:
                continue

            redirection_source = idc.get_func_attr(caller_address, idc.FUNCATTR_START)

            print(
                "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}".format(
                    redirection_source,
                    function_thunk.name,
                    function_thunk.start,
                    redirection_dest,
                )
            )

            self.add_control_flow_redirection(redirection_source, redirection_dest)
示例#9
0
    def get_dword(ea=None, original=False):
        """
            Static method allowing to get the value of one dword at an address.

            :param ea: The address at which recuperating the value. If
                ``None`` the screen address is used.
            :param original: If True the value recuperated will be the
                original one (before a patch). Default: False.
            :return: An integer corresponding to the value at the address.
        """
        if ea is None:
            ea = ida_kernwin.get_screen_ea()
        if original:
            return ida_bytes.get_original_dword(ea)
        else:
            return ida_bytes.get_wide_dword(ea)
示例#10
0
    def decode_msr_mrs(self, insn):
        x = ida_bytes.get_wide_dword(insn.ea)
        op0 = 2 + ((x >> 19) & 1)
        if insn.itype == ida_allins.ARM_msr:
            i, xt = 0, insn.ops[4].reg
        else:
            xt, i = insn.ops[0].reg, 1
        op1 = insn.ops[i].value
        crn = insn.ops[i + 1].reg
        crm = insn.ops[i + 2].reg
        op2 = insn.ops[i + 3].value

        ops = [op0, op1, crn, crm, op2]
        gp_reg = ida_idp.ph.regnames[xt]
        cp_reg = self.find_reg_enc("MSR|MRS", ops)
        return cp_reg, gp_reg
示例#11
0
 def parse(self, addr):
     print("FieldTableEntryEx:parse addr = 0x%08X" % addr.get_curr_addr())
     if type(addr) is byte_reader:
         reader = addr
     else:
         reader = byte_reader(addr)
     self.Flags = reader.get_byte()
     tp_ref = reader.get_dword()
     if tp_ref:
         self.TypeRef = TypeInfo().parse(ida_bytes.get_wide_dword(tp_ref))
     self.Offset = reader.get_dword()
     self.Name = reader.get_delphi_string()
     self.AtrrDataLen = reader.get_word()
     if self.AtrrDataLen > 2:
         self.AtrrData = reader.get_bytes(self.AtrrDataLen - 2)
     return self
示例#12
0
    def get_ptr(ea=None):
        """
            Recuperate the value of a pointer at an address. This will handle
            automatically the correct size of the pointer.
    
            :param int ea: the address at which get the pointer value. If
                ``None`` the screen address is used.
            :return: the pointer value
        """
        if ea is None:
            ea = ida_kernwin.get_screen_ea()

        info = ida_idaapi.get_inf_structure()
        if info.is_64bit():
            return ida_bytes.get_qword(ea)
        elif info.is_32bit():
            return ida_bytes.get_wide_dword(ea)
        else:
            return ida_bytes.get_wide_word(ea)
示例#13
0
def get_instance_size(cls_addr):
    return ida_bytes.get_wide_dword(cls_addr + vmtInstanceSize)
示例#14
0
    def var_len_args_run_info(self, args_rule, args):
        """
        获取变长参数函数的寄存器信息
        """

        run_info = {}
        fmt_t = ''

        for idx in range(len(args_rule) - 1):
            str_reg = 'R%s' % idx
            arg_t = args_rule[idx]
            if arg_t == 'none':  # 跳过无关参数
                continue
            elif arg_t == 'int':
                run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                FELogger.console('%s: %s' %
                                 (str_reg, hexstr(args[str_reg].ival)))
            elif arg_t == 'str':
                arg_v = args[str_reg].ival
                if arg_v != 0:
                    str_t = FEStrMgr.get_string_from_mem(arg_v)
                else:
                    str_t = ''
                run_info[str_reg] = [hexstr(arg_v), repr(str_t)]
                FELogger.console('%s: %s => %s' %
                                 (str_reg, hexstr(arg_v), repr(str_t)))
            elif arg_t == 'fmt':
                arg_v = args[str_reg].ival
                fmt_t = FEStrMgr.get_string_from_mem(arg_v)
                run_info[str_reg] = [hexstr(arg_v), repr(fmt_t)]
                FELogger.console('%s: %s => %s' %
                                 (str_reg, hexstr(arg_v), repr(fmt_t)))
            else:
                run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                FELogger.console('%s: %s' %
                                 (str_reg, hexstr(args[str_reg].ival)))

        # 判断是否包含格式字符串
        if fmt_t != '':
            fmt_list = FEStrMgr.parse_format_string(str_t)
            args_num = len(fmt_list) + idx + 1
            # 判断变长参数总个数
            if idx + 1 == args_num:
                pass
            # n<=4 寄存器
            elif idx + 1 < args_num and args_num <= 4:
                for jdx in range(len(fmt_list)):
                    str_reg = 'R%s' % (idx + jdx + 1)
                    if 's' in fmt_list[jdx]:
                        arg_v = args[str_reg].ival
                        str_t = FEStrMgr.get_string_from_mem(arg_v)
                        run_info[str_reg] = [hexstr(arg_v), repr(str_t)]
                        FELogger.console('%s: %s => %s' %
                                         (str_reg, hexstr(arg_v), repr(str_t)))
                    else:
                        run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                        FELogger.console('%s: %s' %
                                         (str_reg, hexstr(args[str_reg].ival)))
            # n>4 寄存器+栈
            else:
                stack_num = args_num - 4
                sp_addr = args[arm_regset.stack].ival
                for jdx in range(4 - idx - 1):
                    str_reg = 'R%s' % (idx + jdx + 1)
                    if 's' in fmt_list[jdx]:
                        arg_v = args[str_reg].ival
                        str_t = FEStrMgr.get_string_from_mem(arg_v)
                        run_info[str_reg] = [hexstr(arg_v), repr(str_t)]
                        FELogger.console('%s: %s => %s' %
                                         (str_reg, hexstr(arg_v), repr(str_t)))
                    else:
                        run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                        FELogger.console('%s: %s' %
                                         (str_reg, hexstr(args[str_reg].ival)))

                run_info[arm_regset.stack] = []
                for kdx in range(stack_num):
                    stack_v = ida_bytes.get_wide_dword(sp_addr)
                    if 's' in fmt_list[jdx + kdx + 1]:
                        if stack_v == 0:
                            str_t = ''
                        else:
                            str_t = FEStrMgr.get_string_from_mem(stack_v)
                        run_info[arm_regset.stack].append(
                            [hexstr(sp_addr),
                             hexstr(stack_v),
                             repr(str_t)])
                        FELogger.console(
                            'stack: %s - %s => %s' %
                            (hexstr(sp_addr), hexstr(stack_v), repr(str_t)))
                    else:
                        run_info[arm_regset.stack].append(
                            [hexstr(sp_addr),
                             hexstr(stack_v), None])
                        FELogger.console('stack: %s - %s' %
                                         (hexstr(sp_addr), hexstr(stack_v)))
                    sp_addr += 4
        else:
            pass

        return run_info
示例#15
0
def get_class_name(cls_addr):
    class_name = ida_bytes.get_strlit_contents(
        ida_bytes.get_wide_dword(cls_addr + vmtClassName), ida_idaapi.BADADDR,
        ida_nalt.STRTYPE_PASCAL)
    return class_name
示例#16
0
def parse_borland_class_rtti(addr):
    class_name = ida_bytes.get_strlit_contents(
        ida_bytes.get_wide_dword(addr + vmtClassName), ida_idaapi.BADADDR,
        ida_nalt.STRTYPE_PASCAL)
    print("Class name: %s" % class_name.decode())
    ft = FieldTable().parse(get_field_table_addr(addr))
示例#17
0
def get_field_table_addr(cls_addr):
    return ida_bytes.get_wide_dword(cls_addr + vmtFieldTable)
示例#18
0
def get_parent_addr(cls_addr):
    return ida_bytes.get_wide_dword(cls_addr + vmtParent)
示例#19
0
 def get_dword(self, pos=None):
     if pos is None:
         pos = self.pos
         self.pos += 4
     return ida_bytes.get_wide_dword(self.addr + pos)