Add support for telescope to show previous addresses #1047 (#1094)

* Added -r argument to telescope command (#1047)

* Added tests for telescope command (#1047)
This commit is contained in:
NT Sleep 2022-08-24 00:31:20 +02:00 committed by GitHub
parent 890e314f2f
commit 5d358585b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 3 deletions

View File

@ -36,14 +36,18 @@ parser = argparse.ArgumentParser(description="""
""")
parser.add_argument("address", nargs="?", default=None, type=int, help="The address to telescope at.")
parser.add_argument("count", nargs="?", default=telescope_lines, type=int, help="The number of lines to show.")
parser.add_argument("-r", "--reverse", dest="reverse", action='store_true', default=False,
help='Show <count> previous addresses instead of next ones')
@pwndbg.commands.ArgparsedCommand(parser)
@pwndbg.commands.OnlyWhenRunning
def telescope(address=None, count=telescope_lines, to_string=False):
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
ptrsize = pwndbg.typeinfo.ptrsize
if telescope.repeat:
address = telescope.last_address + ptrsize
telescope.offset += 1
@ -51,10 +55,14 @@ def telescope(address=None, count=telescope_lines, to_string=False):
telescope.offset = 0
address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask
count = max(int(count), 1) & 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

View File

@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct A {
void* func_ptr;
void* stack_ptr;
void* heap_ptr;
char buf[16];
char gap[128];
};
void break_here() {}
int main() {
struct A a = {};
a.func_ptr = (void*)main;
a.stack_ptr = (void*) &a;
a.heap_ptr = malloc(10);
strcpy(a.buf, "aaa");
break_here();
}

View File

@ -0,0 +1,59 @@
import gdb
import tests
TELESCOPE_BINARY = tests.binaries.get('telescope_binary.out')
def test_command_telescope(start_binary):
"""
Tests simple telescope
"""
start_binary(TELESCOPE_BINARY)
gdb.execute('break break_here')
gdb.execute('run')
gdb.execute('up')
expected_str = gdb.execute('print a', to_string=True)
expected_lines = expected_str.split('\n')
result_str = gdb.execute('telescope &a', to_string=True)
result_lines = result_str.split('\n')
for i in range(4):
expected_addr = expected_lines[i+1].split(' ')[4].strip(',"')
assert expected_addr in result_lines[i]
def test_command_telescope_reverse(start_binary):
"""
Tests reversed telescope
"""
start_binary(TELESCOPE_BINARY)
gdb.execute('break break_here')
gdb.execute('run')
gdb.execute('up')
expected_str = gdb.execute('print a', to_string=True)
expected_lines = expected_str.split('\n')
result_str = gdb.execute('telescope ((uint8_t*)&a)+0x38 -r', to_string=True)
result_lines = result_str.split('\n')
for i in range(4):
expected_addr = expected_lines[i+1].split(' ')[4].strip(',"')
assert expected_addr in result_lines[i]
def test_command_telescope_n_records(start_binary):
"""
Tests telescope defined number of records
"""
start_binary(TELESCOPE_BINARY)
n = 3
gdb.execute('entry')
result_str = gdb.execute('telescope $rsp {}'.format(n), to_string=True)
assert len(result_str.strip('\n').split('\n')) == n