예제 #1
0
def telescope(address=None, count=telescope_lines, to_string=False):
    """
    Recursively dereferences pointers starting at the specified address
    ($sp by default)
    """
    address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask
    count   = int(count) & pwndbg.arch.ptrmask
    delimiter = T.delimiter(offset_delimiter)
    separator = T.separator(offset_separator)

    # Allow invocation of "hexdump 20" to dump 20 bytes at the stack pointer
    if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(address):
        count   = address
        address = pwndbg.regs.sp

    # Allow invocation of "hexdump a b" to dump all bytes from A to B
    if int(address) < int(count):
        count -= address

    reg_values = collections.defaultdict(lambda: [])
    for reg in pwndbg.regs.common:
        reg_values[pwndbg.regs[reg]].append(reg)
    # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)
    ptrsize    = pwndbg.typeinfo.ptrsize

    start = address
    stop  = address + (count*ptrsize)
    step  = ptrsize

    # Find all registers which show up in the trace
    regs = {}
    for i in range(start, stop, step):
        values = list(reg_values[i])

        for width in range(1, pwndbg.arch.ptrsize):
            values.extend('%s-%i' % (r,width) for r in reg_values[i+width])

        regs[i] = ' '.join(values)

    # Find the longest set of register information
    if regs:
        longest_regs = max(map(len, regs.values())) + 1
    else:
        longest_regs = 0

    # Print everything out
    result = []
    last   = None
    skip   = False
    for i,addr in enumerate(range(start, stop, step)):
        if not pwndbg.memory.peek(addr):
            result.append("<Could not read memory at %#x>" % addr)
            break

        # Collapse repeating values.
        value = pwndbg.memory.pvoid(addr)
        if last == value:
            if not skip:
                result.append(T.repeating_marker('%s' % repeating_maker))
                skip = True
            continue
        last = value
        skip = False

        line = ' '.join((T.offset("%02x%s%04x%s" % (i, delimiter, addr-start, separator)),
                         T.register(regs[addr].ljust(longest_regs)),
                         pwndbg.chain.format(addr)))
        result.append(line)

    if not to_string:
        print('\n'.join(result))

    return result
예제 #2
0
def telescope(address=None, count=telescope_lines, to_string=False):
    """
    Recursively dereferences pointers starting at the specified address
    ($sp by default)
    """
    address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask
    count = int(count) & pwndbg.arch.ptrmask
    delimiter = T.delimiter(offset_delimiter)
    separator = T.separator(offset_separator)

    # Allow invocation of "hexdump 20" to dump 20 bytes at the stack pointer
    if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(
            address):
        count = address
        address = pwndbg.regs.sp

    # Allow invocation of "hexdump a b" to dump all bytes from A to B
    if int(address) < int(count):
        count -= address

    reg_values = collections.defaultdict(lambda: [])
    for reg in pwndbg.regs.common:
        reg_values[pwndbg.regs[reg]].append(reg)
    # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)
    ptrsize = pwndbg.typeinfo.ptrsize

    start = address
    stop = address + (count * ptrsize)
    step = ptrsize

    # Find all registers which show up in the trace
    regs = {}
    for i in range(start, stop, step):
        values = list(reg_values[i])

        for width in range(1, pwndbg.arch.ptrsize):
            values.extend('%s-%i' % (r, width) for r in reg_values[i + width])

        regs[i] = ' '.join(values)

    # Find the longest set of register information
    if regs:
        longest_regs = max(map(len, regs.values())) + 1
    else:
        longest_regs = 0

    # Print everything out
    result = []
    last = None
    skip = False
    for i, addr in enumerate(range(start, stop, step)):
        if not pwndbg.memory.peek(addr):
            result.append("<Could not read memory at %#x>" % addr)
            break

        # Collapse repeating values.
        value = pwndbg.memory.pvoid(addr)
        if last == value:
            if not skip:
                result.append(T.repeating_marker('%s' % repeating_maker))
                skip = True
            continue
        last = value
        skip = False

        line = ' '.join((T.offset("%02x%s%04x%s" %
                                  (i, delimiter, addr - start, separator)),
                         T.register(regs[addr].ljust(longest_regs)),
                         pwndbg.chain.format(addr)))
        result.append(line)

    if not to_string:
        print('\n'.join(result))

    return result
예제 #3
0
def telescope(address=None,
              count=telescope_lines,
              to_string=False,
              reverse=False):
    """
    Recursively dereferences pointers starting at the specified address
    ($sp by default)
    """
    ptrsize = pwndbg.typeinfo.ptrsize
    if telescope.repeat:
        address = telescope.last_address + ptrsize
        telescope.offset += 1
    else:
        telescope.offset = 0

    address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask
    count = max(int(count), 1) & pwndbg.arch.ptrmask
    delimiter = T.delimiter(offset_delimiter)
    separator = T.separator(offset_separator)

    # Allow invocation of telescope -r to dump previous addresses
    if reverse:
        address -= (count - 1) * ptrsize

    # Allow invocation of "telescope 20" to dump 20 bytes at the stack pointer
    if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(
            address):
        count = address
        address = pwndbg.regs.sp

    # Allow invocation of "telescope a b" to dump all bytes from A to B
    if int(address) <= int(count):
        # adjust count if it is an address. use ceil division as count is number of
        # ptrsize values and we don't want to strip out a value if dest is unaligned
        count -= address
        count = max(math.ceil(count / ptrsize), 1)

    reg_values = collections.defaultdict(lambda: [])
    for reg in pwndbg.regs.common:
        reg_values[pwndbg.regs[reg]].append(reg)
    # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)

    start = address
    stop = address + (count * ptrsize)
    step = ptrsize

    # Find all registers which show up in the trace
    regs = {}
    for i in range(start, stop, step):
        values = list(reg_values[i])

        for width in range(1, pwndbg.arch.ptrsize):
            values.extend("%s-%i" % (r, width) for r in reg_values[i + width])

        regs[i] = " ".join(values)

    # Find the longest set of register information
    if regs:
        longest_regs = max(map(len, regs.values()))
    else:
        longest_regs = 0

    # Print everything out
    result = []
    last = None
    collapse_buffer = []
    skipped_padding = (2 + len(offset_delimiter) + 4 + len(offset_separator) +
                       1 + longest_regs + 1 - len(repeating_marker))

    # Collapse repeating values exceeding minimum delta.
    def collapse_repeating_values():
        # The first line was already printed, hence increment by 1
        if collapse_buffer and len(
                collapse_buffer) + 1 >= skip_repeating_values_minimum:
            result.append(
                T.repeating_marker("%s%s%i skipped" %
                                   (repeating_marker, " " * skipped_padding,
                                    len(collapse_buffer))))
        else:
            result.extend(collapse_buffer)
        collapse_buffer.clear()

    for i, addr in enumerate(range(start, stop, step)):
        if not pwndbg.memory.peek(addr):
            collapse_repeating_values()
            result.append("<Could not read memory at %#x>" % addr)
            break

        line = " ".join((
            T.offset("%02x%s%04x%s" % (
                i + telescope.offset,
                delimiter,
                addr - start + (telescope.offset * ptrsize),
                separator,
            )),
            T.register(regs[addr].ljust(longest_regs)),
            pwndbg.chain.format(addr),
        ))

        # Buffer repeating values.
        if skip_repeating_values:
            value = pwndbg.memory.pvoid(addr)
            if last == value:
                collapse_buffer.append(line)
                continue
            collapse_repeating_values()
            last = value

        result.append(line)

    collapse_repeating_values()
    telescope.offset += i
    telescope.last_address = addr

    if not to_string:
        print("\n".join(result))

    return result