Пример #1
0
def get_symbol_address(symbol):
    """
    for a given Maple symbol, returns its address in hex string via gdb p command,
    or None if not found
    """

    cmd = 'p ' + symbol
    try:
        result = m_util.gdb_exec_to_str(cmd)
    except:
        return None

    match_pattern = '<' + symbol + '>'

    if result.find(match_pattern) is -1:
        return None
    else:
        x = result.split()
        pattern_index = x.index(match_pattern)
        return x[pattern_index - 1]
Пример #2
0
    def __init__(self):
        gdb.Command.__init__(self, "msrcpath", gdb.COMMAND_FILES,
                             gdb.COMPLETE_NONE)

        global maple_source_path_list

        # add current working directory at the top
        line = m_util.gdb_exec_to_str('pwd')
        if line:
            s = line.split()
            line = s[2][:-1] if len(s) is 3 else None
            if line:
                maple_source_path_list.append(
                    os.path.expandvars(os.path.expanduser(line)))
        '''
        if len(maple_source_path_list) == 1:
            gdb_print("Maple application source code search path only has one path as following:")
            gdb_print("  ", maple_source_path_list[0])
            gdb_print("Please add more search paths using msrcpath -add <path> command")
        '''

        m_util.gdb_exec('alias msp = msrcpath')
Пример #3
0
def get_symbol_name_by_current_func_args():
    """
    get the 'func' symbol name and its address in currect frame stack
    """

    cmd = 'p func'
    try:
        result = m_util.gdb_exec_to_str(cmd)
    except:
        return None, None
    if m_debug.Debug: m_debug.dbg_print("result=", result)


    if 'header = ' in result and '_mirbin_info>' in result:
        s = result.split('header = ')
        address = s[1].split()[0]
        name = s[1].split()[1].split('>')[0][1:]
        caller = result.split('caller = ')[1].split(',')[0]
        if m_debug.Debug: m_debug.dbg_print("address=", address, "name=", name, "caller=", caller)
        return address, name
    else:
        return None, None
Пример #4
0
    def print_array_class_values(self, addr):
        """ display 10 items if length is less than 10, or first 7 and last three if length is over 11 """

        item_num = self.get_array_length(addr)

        if item_num > 10:
            item_list = [
                0, 1, 2, 3, 4, 5, 6, item_num - 3, item_num - 2, item_num - 1
            ]
        else:
            item_list = [i for i in range(item_num)]

        steps = 0
        show_snip = True
        for i in item_list:
            obj_addr = addr + 4 + 8 * i  # class reference is a pointer, 8 bytes
            cmd = 'x/1gx ' + hex(obj_addr)
            if m_debug.Debug: m_debug.dbg_print("cmd=", cmd)
            try:
                buffer = m_util.gdb_exec_to_str(cmd)
            except:
                buf = '  [{}] {}'.format(i, 'no-data')
                gdb_print(buf)
                steps += 1
                continue

            steps += 1
            v = buffer.split(':')[1].strip()
            v = hex(int(v, 16))  #remove leading 0s. e.g. 0x000123 to 0x123
            buf = '  [{}] {}'.format(i, v)
            gdb_print(buf)

            if item_num > 10 and steps > 6 and show_snip == True:
                gdb_print("  ...")
                show_snip = False

        return
Пример #5
0
    def stop(self):
        """
        provide stop control logic here.
        note, user will add one or more Maple symbol into mbp_table, only those qualified
        ones in mbp_table will be admitted to make breakpoint stop

        return True: to stop
               False: to bypass
        """

        # if the Maple breakpoint was created before .so is loaded, when the breakpoint is hit,
        # plt will be not disable. So we disable it
        buf = m_util.gdb_exec_to_str("info b")
        if not is_maple_invoke_bp_plt_disabled(buf):
            disable_maple_invoke_bp_plt(buf)
            return False

        # if the Maple breakpoint was created before .so is loaded, bp_addr, bp_info (location)
        # if not available. But once hit, address and loc start to be available.
        if not self.bp_info or not self.bp_addr:
            self.bp_addr, self.bp_info = get_maple_invoke_bp_stop_addr(buf)

        # determine whether need to look up pending symbol's address. If the number of loaded libraries
        # is not eaual to the one saved, then libs might have been loaded or unloaded, so we try to update
        if len(gdb.objfiles()) != self.load_objfiles:
            self.load_objfiles = len(gdb.objfiles())
            pending_addr_symbol_list = self.get_pending_addr_symbol_list()
            if len(pending_addr_symbol_list) > 0:
                for sym in pending_addr_symbol_list:
                    self.update_pending_addr_symbol(sym)

        # NOTE!!! here we are getting the current stack's mir_header's address
        args_addr = m_symbol.get_symbol_addr_by_current_frame_args()
        if not args_addr or not args_addr in self.mbp_addr_sym_table:
            return False

        # mir_header address matches one breakpoint address list
        table_args_addr = self.mbp_addr_sym_table[args_addr]
        args_symbol = table_args_addr['mir_symbol']
        match_pattern = table_args_addr['symbol']

        # it is possible that match pattern is in mbp_addr_sym_table for address check,
        # but the self.mbp_addr_sym_table[args_addr]['symbol'] could have been cleared
        # in self.mbp_table by user's mb -clear command
        if not match_pattern in self.mbp_table:
            return False

        # Maple symbol for the breakpoint is disabled
        table_match_pattern = self.mbp_table[match_pattern]
        if table_match_pattern['disabled'] is True:
            return False

        if table_match_pattern['ignore_count'] > 0:
            table_match_pattern['ignore_count'] -= 1
            return False

        table_match_pattern['hit_count'] += 1

        # update the Maple gdb runtime metadata store.
        m_datastore.mgdb_rdata.update_gdb_runtime_data()
        # update the Maple frame change count
        m_datastore.mgdb_rdata.update_frame_change_counter()
        return True
Пример #6
0
    def get_value_from_memory(self, addr, offset, length):
        """
        params:
          addr: int
          offset: int
          length: int

        returns:
          value in string
        """

        if m_debug.Debug:
            m_debug.dbg_print("addr=", addr, " offset=", offset, " length=",
                              length)
        hex_string = None
        doulbe_string = None
        long_string = None
        int_string = None
        float_string = None
        word_string = None
        short_string = None
        byte_string = None
        ret = None
        if length == 8:  # 8 byte, could be a long, a 8 byte address ptr, or a double
            cmd = 'x/1gx ' + hex(addr + offset)  # cmd to get 8 byte address
            try:
                hex_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            hex_string = hex_string.split(':')[1]
            hex_string = hex(int(hex_string, 16))

            cmd = 'x/1gf ' + hex(
                addr + offset)  # cmd to get 8 byte double value
            try:
                double_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            double_string = double_string.split()[1]

            cmd = 'x/1dg ' + hex(addr + offset)  # cmd to get 8 byte long value
            try:
                long_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            long_string = long_string.split()[1]

            ret = 'hex:' + hex_string + ',long:' + long_string + ',double:' + double_string
            if m_debug.Debug: m_debug.dbg_print("ret=", ret)
            return ret
        elif length == 4:  # 4 byte,could be int, float, hex
            cmd = 'x/1xw ' + hex(
                addr + offset)  # cmd to get 4 byte hex address
            try:
                hex_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            hex_string = hex_string.split()[1]

            cmd = 'x/1dw ' + hex(addr + offset)  # cmd to get 4 byte int
            try:
                int_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            int_string = int_string.split()[1]

            cmd = 'x/1fw ' + hex(addr + offset)  # cmd to get 4 byte float
            try:
                float_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            float_string = float_string.split()[1]

            ret = 'hex:' + hex_string + ',int:' + int_string + ',float:' + float_string
            if m_debug.Debug: m_debug.dbg_print("ret=", ret)
            return ret
        elif length == 2:  # 2 byte, could be short, hex, 2 character
            cmd = 'x/1xh ' + hex(
                addr + offset)  # cmd to get 2 byte hex address
            try:
                hex_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            hex_string = hex_string.split()[1]

            cmd = 'x/1dh ' + hex(addr + offset)  # cmd to get 2 byte short int
            try:
                short_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            short_string = short_string.split()[1]

            cmd = 'x/2b ' + hex(addr + offset)  # cmd to get 2 byte characters
            try:
                byte_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            byte_string = byte_string.split(':')[1].strip()

            ret = 'hex:' + hex_string + ',short:' + short_string + ',byte:' + byte_string
            if m_debug.Debug: m_debug.dbg_print("ret=", ret)
            return ret
        elif length == 1:  # 1 byte. could be hex, c
            cmd = 'x/1xb ' + hex(addr + offset)  # cmd to get 1 byte hex
            try:
                hex_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            hex_string = hex_string.split()[1]

            cmd = 'x/1cb ' + hex(addr + offset)  # cmd to get 1 byte characters
            try:
                byte_string = m_util.gdb_exec_to_str(cmd)
            except:
                if m_debug.Debug: m_debug.dbg_print()
                return None
            byte_string = byte_string.split(':')[1].strip()

            ret = 'hex:' + hex_string + ',byte:' + byte_string
            if m_debug.Debug: m_debug.dbg_print("ret=", ret)
            return ret
        else:
            if m_debug.Debug: m_debug.dbg_print()
            return None
Пример #7
0
def get_maple_caller_argument_value(arg_idx, arg_num, mtype):
    """
    for a given Maple caller's arg_idx, arg_num and type,
    get its value from caller's operand_stack

    params:
      arg_idx: the argument index in a Maple method.
               e.g. method1(int a, long b, string c), for
               argument "a", its arg index is 0, c is 2.
      arg_num: number of argument a method has
      mtype  : a string. definition in m_asm.py
               for "a", it could be 'i32', 'i64'
    returns:
       the argument value in string.
    """

    if m_debug.Debug: m_debug.dbg_print("pass in arg_idx=", arg_idx, "arg_num=", arg_num, "mtype=", mtype)

    # get the caller.sp first
    try:
        buffer = m_util.gdb_exec_to_str('p caller.sp')
    except:
        return None

    if 'No symbol "caller" in current context.' in buffer:
        return None
    if ' = ' in buffer:
        sp = int(buffer.split(' = ')[-1])
    else:
        return None

    if  arg_idx > sp: #sp must be >= num of args
        return None
    if m_debug.Debug: m_debug.dbg_print("sp=", sp)

    # get the caller.operand_stack length
    try:
        buffer = m_util.gdb_exec_to_str('p caller.operand_stack.size()')
    except:
        return None

    if buffer[0] != '$':
        return None
    if ' = ' in buffer:
        try:
            length = int(buffer.split(' = ')[1])
        except:
            return None
    else:
        return None
    if m_debug.Debug: m_debug.dbg_print("length=", length)

    if length < arg_idx:
        return None

    # get the caller.operand_stack[arg_idx]
    idx = sp - arg_num + arg_idx + 1
    try:
        buffer = m_util.gdb_exec_to_str('p caller.operand_stack[' + str(idx) + ']')
    except:
        return None

    vline = buffer.split('x = ')[1][1:].split('}')[0]
    v = vline.split(mtype+' = ')[1].split(',')[0] if mtype in vline else None
    return v