We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add support for telescope to show lower addresses instead of higher addresses
I often need to see a few 8 byte values above (and including) a particular address. For example, if I have a heap chunk at `0x557bb502e2e0`, this is how telescope currently works:
```
pwndbg> telescope 0x557bb502e2e0
00:0000│  0x557bb502e2e0 ◂— 0x0
01:0008│  0x557bb502e2e8 ◂— 0x21 /* '!' */
02:0010│  0x557bb502e2f0 ◂— 0x20 /* ' ' */
03:0018│  0x557bb502e2f8 ◂— 0x1
04:0020│  0x557bb502e300 —▸ 0x557bb502e310 ◂— 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
05:0028│  0x557bb502e308 ◂— 0x31 /* '1' */
06:0030│  0x557bb502e310 ◂— 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
07:0038│  0x557bb502e318 ◂— 'BBBBBBBBBBBBBBBBBBBBBBBB'
```
Now I may have expected that an overflow should have overwritten the first few pointers of this heap chunk, but for some reason it didn't, and I suspect I'm a few bytes off, maybe some small multiple of 8. I'd like to check right above this chunk (lower addresses), so currently I can do something like this (or similarly with `x/xg`):
```
pwndbg> telescope 0x557bb502e2e0-0x8*4 5
00:0000│ rax rdi 0x557bb502e2c0 ◂— 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
... ↓            3 skipped
04:0020│         0x557bb502e2e0 ◂— 0x0
```

This works, but I think it's a verbose and inconvenient way to do it. If I want to look farther back, I need to change both the `4` and the `5` to make it do the right thing, as opposed to changing just one number.

It'd be nice to either have a flag `telescope -r` or a new command `rtelescope` that take an address and an optional count and prints the values at lower memory addresses. The example above would just be `telescope -r 0x557bb502e2e0 5`, which is much easier.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwndbg/commands/telescope.py`
Content:
```
1 """
2 Prints out pointer chains starting at some address in memory.
3 
4 Generally used to print out the stack or register values.
5 """
6 
7 import argparse
8 import collections
9 import math
10 
11 import pwndbg.arch
12 import pwndbg.chain
13 import pwndbg.color.telescope as T
14 import pwndbg.color.theme as theme
15 import pwndbg.commands
16 import pwndbg.config
17 import pwndbg.memory
18 import pwndbg.regs
19 import pwndbg.typeinfo
20 
21 telescope_lines = pwndbg.config.Parameter('telescope-lines', 8, 'number of lines to printed by the telescope command')
22 skip_repeating_values = pwndbg.config.Parameter('telescope-skip-repeating-val', True,
23                                                 'whether to skip repeating values of the telescope command')
24 skip_repeating_values_minimum = pwndbg.config.Parameter('telescope-skip-repeating-val-minimum', 3,
25                                                         'minimum amount of repeated values before skipping lines')
26 
27 offset_separator = theme.Parameter('telescope-offset-separator', '│', 'offset separator of the telescope command')
28 offset_delimiter = theme.Parameter('telescope-offset-delimiter', ':', 'offset delimiter of the telescope command')
29 repeating_marker = theme.Parameter('telescope-repeating-marker', '... ↓',
30                                    'repeating values marker of the telescope command')
31 
32 
33 parser = argparse.ArgumentParser(description="""
34     Recursively dereferences pointers starting at the specified address
35     ($sp by default)
36     """)
37 parser.add_argument("address", nargs="?", default=None, type=int, help="The address to telescope at.")
38 parser.add_argument("count", nargs="?", default=telescope_lines, type=int, help="The number of lines to show.")
39 @pwndbg.commands.ArgparsedCommand(parser)
40 @pwndbg.commands.OnlyWhenRunning
41 def telescope(address=None, count=telescope_lines, to_string=False):
42     """
43     Recursively dereferences pointers starting at the specified address
44     ($sp by default)
45     """
46     ptrsize   = pwndbg.typeinfo.ptrsize
47     if telescope.repeat:
48         address = telescope.last_address + ptrsize
49         telescope.offset += 1
50     else:
51         telescope.offset = 0
52 
53     address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask
54     count   = max(int(count), 1) & pwndbg.arch.ptrmask
55     delimiter = T.delimiter(offset_delimiter)
56     separator = T.separator(offset_separator)
57 
58     # Allow invocation of "telescope 20" to dump 20 bytes at the stack pointer
59     if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(address):
60         count   = address
61         address = pwndbg.regs.sp
62 
63     # Allow invocation of "telescope a b" to dump all bytes from A to B
64     if int(address) <= int(count):
65         # adjust count if it is an address. use ceil division as count is number of
66         # ptrsize values and we don't want to strip out a value if dest is unaligned
67         count -= address
68         count = max(math.ceil(count / ptrsize), 1)
69 
70     reg_values = collections.defaultdict(lambda: [])
71     for reg in pwndbg.regs.common:
72         reg_values[pwndbg.regs[reg]].append(reg)
73     # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)
74 
75     start = address
76     stop  = address + (count*ptrsize)
77     step  = ptrsize
78 
79     # Find all registers which show up in the trace
80     regs = {}
81     for i in range(start, stop, step):
82         values = list(reg_values[i])
83 
84         for width in range(1, pwndbg.arch.ptrsize):
85             values.extend('%s-%i' % (r,width) for r in reg_values[i+width])
86 
87         regs[i] = ' '.join(values)
88 
89     # Find the longest set of register information
90     if regs:
91         longest_regs = max(map(len, regs.values()))
92     else:
93         longest_regs = 0
94 
95     # Print everything out
96     result = []
97     last = None
98     collapse_buffer = []
99     skipped_padding = 2 + len(offset_delimiter) + 4 + len(offset_separator) + 1 + longest_regs + 1 - len(repeating_marker)
100 
101     # Collapse repeating values exceeding minimum delta.
102     def collapse_repeating_values():
103         # The first line was already printed, hence increment by 1
104         if collapse_buffer and len(collapse_buffer) + 1 >= skip_repeating_values_minimum:
105             result.append(T.repeating_marker('%s%s%i skipped' % (repeating_marker, ' ' * skipped_padding, len(collapse_buffer))))
106         else:
107             result.extend(collapse_buffer)
108         collapse_buffer.clear()
109 
110     for i, addr in enumerate(range(start, stop, step)):
111         if not pwndbg.memory.peek(addr):
112             collapse_repeating_values()
113             result.append("<Could not read memory at %#x>" % addr)
114             break
115 
116         line = ' '.join((T.offset("%02x%s%04x%s" % (i + telescope.offset, delimiter,
117                                                     addr - start + (telescope.offset * ptrsize), separator)),
118                          T.register(regs[addr].ljust(longest_regs)),
119                          pwndbg.chain.format(addr)))
120 
121         # Buffer repeating values.
122         if skip_repeating_values:
123             value = pwndbg.memory.pvoid(addr)
124             if last == value:
125                 collapse_buffer.append(line)
126                 continue
127             collapse_repeating_values()
128             last = value
129 
130         result.append(line)
131 
132     collapse_repeating_values()
133     telescope.offset += i
134     telescope.last_address = addr
135 
136     if not to_string:
137         print('\n'.join(result))
138 
139     return result
140 
141 
142 parser = argparse.ArgumentParser(description='dereferences on stack data with specified count and offset.')
143 parser.add_argument('count', nargs='?', default=8, type=int,
144                     help='number of element to dump')
145 parser.add_argument('offset', nargs='?', default=0, type=int,
146                     help='Element offset from $sp (support negative offset)')
147 
148 
149 @pwndbg.commands.ArgparsedCommand(parser)
150 @pwndbg.commands.OnlyWhenRunning
151 def stack(count, offset):
152     ptrsize = pwndbg.typeinfo.ptrsize
153     telescope.repeat = stack.repeat
154     telescope(address=pwndbg.regs.sp + offset * ptrsize, count=count)
155 
156 
157 telescope.last_address = 0
158 telescope.offset = 0
159
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwndbg/commands/telescope.py b/pwndbg/commands/telescope.py
--- a/pwndbg/commands/telescope.py
+++ b/pwndbg/commands/telescope.py
@@ -36,14 +36,18 @@
     """)
 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 @@
         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

{"golden_diff": "diff --git a/pwndbg/commands/telescope.py b/pwndbg/commands/telescope.py\n--- a/pwndbg/commands/telescope.py\n+++ b/pwndbg/commands/telescope.py\n@@ -36,14 +36,18 @@\n     \"\"\")\n parser.add_argument(\"address\", nargs=\"?\", default=None, type=int, help=\"The address to telescope at.\")\n parser.add_argument(\"count\", nargs=\"?\", default=telescope_lines, type=int, help=\"The number of lines to show.\")\n+parser.add_argument(\"-r\", \"--reverse\", dest=\"reverse\", action='store_true', default=False,\n+                    help='Show <count> previous addresses instead of next ones')\n+\n+\n @pwndbg.commands.ArgparsedCommand(parser)\n @pwndbg.commands.OnlyWhenRunning\n-def telescope(address=None, count=telescope_lines, to_string=False):\n+def telescope(address=None, count=telescope_lines, to_string=False, reverse=False):\n     \"\"\"\n     Recursively dereferences pointers starting at the specified address\n     ($sp by default)\n     \"\"\"\n-    ptrsize   = pwndbg.typeinfo.ptrsize\n+    ptrsize = pwndbg.typeinfo.ptrsize\n     if telescope.repeat:\n         address = telescope.last_address + ptrsize\n         telescope.offset += 1\n@@ -51,10 +55,14 @@\n         telescope.offset = 0\n \n     address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask\n-    count   = max(int(count), 1) & pwndbg.arch.ptrmask\n+    count = max(int(count), 1) & pwndbg.arch.ptrmask\n     delimiter = T.delimiter(offset_delimiter)\n     separator = T.separator(offset_separator)\n \n+    # Allow invocation of telescope -r to dump previous addresses\n+    if reverse:\n+        address -= (count - 1) * ptrsize\n+\n     # Allow invocation of \"telescope 20\" to dump 20 bytes at the stack pointer\n     if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(address):\n         count   = address\n", "issue": "Add support for telescope to show lower addresses instead of higher addresses\nI often need to see a few 8 byte values above (and including) a particular address. For example, if I have a heap chunk at `0x557bb502e2e0`, this is how telescope currently works:\r\n```\r\npwndbg> telescope 0x557bb502e2e0\r\n00:0000\u2502  0x557bb502e2e0 \u25c2\u2014 0x0\r\n01:0008\u2502  0x557bb502e2e8 \u25c2\u2014 0x21 /* '!' */\r\n02:0010\u2502  0x557bb502e2f0 \u25c2\u2014 0x20 /* ' ' */\r\n03:0018\u2502  0x557bb502e2f8 \u25c2\u2014 0x1\r\n04:0020\u2502  0x557bb502e300 \u2014\u25b8 0x557bb502e310 \u25c2\u2014 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'\r\n05:0028\u2502  0x557bb502e308 \u25c2\u2014 0x31 /* '1' */\r\n06:0030\u2502  0x557bb502e310 \u25c2\u2014 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'\r\n07:0038\u2502  0x557bb502e318 \u25c2\u2014 'BBBBBBBBBBBBBBBBBBBBBBBB'\r\n```\r\nNow I may have expected that an overflow should have overwritten the first few pointers of this heap chunk, but for some reason it didn't, and I suspect I'm a few bytes off, maybe some small multiple of 8. I'd like to check right above this chunk (lower addresses), so currently I can do something like this (or similarly with `x/xg`):\r\n```\r\npwndbg> telescope 0x557bb502e2e0-0x8*4 5\r\n00:0000\u2502 rax rdi 0x557bb502e2c0 \u25c2\u2014 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'\r\n... \u2193            3 skipped\r\n04:0020\u2502         0x557bb502e2e0 \u25c2\u2014 0x0\r\n```\r\n\r\nThis works, but I think it's a verbose and inconvenient way to do it. If I want to look farther back, I need to change both the `4` and the `5` to make it do the right thing, as opposed to changing just one number.\r\n\r\nIt'd be nice to either have a flag `telescope -r` or a new command `rtelescope` that take an address and an optional count and prints the values at lower memory addresses. The example above would just be `telescope -r 0x557bb502e2e0 5`, which is much easier.\n", "before_files": [{"content": "\"\"\"\nPrints out pointer chains starting at some address in memory.\n\nGenerally used to print out the stack or register values.\n\"\"\"\n\nimport argparse\nimport collections\nimport math\n\nimport pwndbg.arch\nimport pwndbg.chain\nimport pwndbg.color.telescope as T\nimport pwndbg.color.theme as theme\nimport pwndbg.commands\nimport pwndbg.config\nimport pwndbg.memory\nimport pwndbg.regs\nimport pwndbg.typeinfo\n\ntelescope_lines = pwndbg.config.Parameter('telescope-lines', 8, 'number of lines to printed by the telescope command')\nskip_repeating_values = pwndbg.config.Parameter('telescope-skip-repeating-val', True,\n                                                'whether to skip repeating values of the telescope command')\nskip_repeating_values_minimum = pwndbg.config.Parameter('telescope-skip-repeating-val-minimum', 3,\n                                                        'minimum amount of repeated values before skipping lines')\n\noffset_separator = theme.Parameter('telescope-offset-separator', '\u2502', 'offset separator of the telescope command')\noffset_delimiter = theme.Parameter('telescope-offset-delimiter', ':', 'offset delimiter of the telescope command')\nrepeating_marker = theme.Parameter('telescope-repeating-marker', '... \u2193',\n                                   'repeating values marker of the telescope command')\n\n\nparser = argparse.ArgumentParser(description=\"\"\"\n    Recursively dereferences pointers starting at the specified address\n    ($sp by default)\n    \"\"\")\nparser.add_argument(\"address\", nargs=\"?\", default=None, type=int, help=\"The address to telescope at.\")\nparser.add_argument(\"count\", nargs=\"?\", default=telescope_lines, type=int, help=\"The number of lines to show.\")\n@pwndbg.commands.ArgparsedCommand(parser)\n@pwndbg.commands.OnlyWhenRunning\ndef telescope(address=None, count=telescope_lines, to_string=False):\n    \"\"\"\n    Recursively dereferences pointers starting at the specified address\n    ($sp by default)\n    \"\"\"\n    ptrsize   = pwndbg.typeinfo.ptrsize\n    if telescope.repeat:\n        address = telescope.last_address + ptrsize\n        telescope.offset += 1\n    else:\n        telescope.offset = 0\n\n    address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask\n    count   = max(int(count), 1) & pwndbg.arch.ptrmask\n    delimiter = T.delimiter(offset_delimiter)\n    separator = T.separator(offset_separator)\n\n    # Allow invocation of \"telescope 20\" to dump 20 bytes at the stack pointer\n    if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(address):\n        count   = address\n        address = pwndbg.regs.sp\n\n    # Allow invocation of \"telescope a b\" to dump all bytes from A to B\n    if int(address) <= int(count):\n        # adjust count if it is an address. use ceil division as count is number of\n        # ptrsize values and we don't want to strip out a value if dest is unaligned\n        count -= address\n        count = max(math.ceil(count / ptrsize), 1)\n\n    reg_values = collections.defaultdict(lambda: [])\n    for reg in pwndbg.regs.common:\n        reg_values[pwndbg.regs[reg]].append(reg)\n    # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)\n\n    start = address\n    stop  = address + (count*ptrsize)\n    step  = ptrsize\n\n    # Find all registers which show up in the trace\n    regs = {}\n    for i in range(start, stop, step):\n        values = list(reg_values[i])\n\n        for width in range(1, pwndbg.arch.ptrsize):\n            values.extend('%s-%i' % (r,width) for r in reg_values[i+width])\n\n        regs[i] = ' '.join(values)\n\n    # Find the longest set of register information\n    if regs:\n        longest_regs = max(map(len, regs.values()))\n    else:\n        longest_regs = 0\n\n    # Print everything out\n    result = []\n    last = None\n    collapse_buffer = []\n    skipped_padding = 2 + len(offset_delimiter) + 4 + len(offset_separator) + 1 + longest_regs + 1 - len(repeating_marker)\n\n    # Collapse repeating values exceeding minimum delta.\n    def collapse_repeating_values():\n        # The first line was already printed, hence increment by 1\n        if collapse_buffer and len(collapse_buffer) + 1 >= skip_repeating_values_minimum:\n            result.append(T.repeating_marker('%s%s%i skipped' % (repeating_marker, ' ' * skipped_padding, len(collapse_buffer))))\n        else:\n            result.extend(collapse_buffer)\n        collapse_buffer.clear()\n\n    for i, addr in enumerate(range(start, stop, step)):\n        if not pwndbg.memory.peek(addr):\n            collapse_repeating_values()\n            result.append(\"<Could not read memory at %#x>\" % addr)\n            break\n\n        line = ' '.join((T.offset(\"%02x%s%04x%s\" % (i + telescope.offset, delimiter,\n                                                    addr - start + (telescope.offset * ptrsize), separator)),\n                         T.register(regs[addr].ljust(longest_regs)),\n                         pwndbg.chain.format(addr)))\n\n        # Buffer repeating values.\n        if skip_repeating_values:\n            value = pwndbg.memory.pvoid(addr)\n            if last == value:\n                collapse_buffer.append(line)\n                continue\n            collapse_repeating_values()\n            last = value\n\n        result.append(line)\n\n    collapse_repeating_values()\n    telescope.offset += i\n    telescope.last_address = addr\n\n    if not to_string:\n        print('\\n'.join(result))\n\n    return result\n\n\nparser = argparse.ArgumentParser(description='dereferences on stack data with specified count and offset.')\nparser.add_argument('count', nargs='?', default=8, type=int,\n                    help='number of element to dump')\nparser.add_argument('offset', nargs='?', default=0, type=int,\n                    help='Element offset from $sp (support negative offset)')\n\n\n@pwndbg.commands.ArgparsedCommand(parser)\n@pwndbg.commands.OnlyWhenRunning\ndef stack(count, offset):\n    ptrsize = pwndbg.typeinfo.ptrsize\n    telescope.repeat = stack.repeat\n    telescope(address=pwndbg.regs.sp + offset * ptrsize, count=count)\n\n\ntelescope.last_address = 0\ntelescope.offset = 0\n", "path": "pwndbg/commands/telescope.py"}], "after_files": [{"content": "\"\"\"\nPrints out pointer chains starting at some address in memory.\n\nGenerally used to print out the stack or register values.\n\"\"\"\n\nimport argparse\nimport collections\nimport math\n\nimport pwndbg.arch\nimport pwndbg.chain\nimport pwndbg.color.telescope as T\nimport pwndbg.color.theme as theme\nimport pwndbg.commands\nimport pwndbg.config\nimport pwndbg.memory\nimport pwndbg.regs\nimport pwndbg.typeinfo\n\ntelescope_lines = pwndbg.config.Parameter('telescope-lines', 8, 'number of lines to printed by the telescope command')\nskip_repeating_values = pwndbg.config.Parameter('telescope-skip-repeating-val', True,\n                                                'whether to skip repeating values of the telescope command')\nskip_repeating_values_minimum = pwndbg.config.Parameter('telescope-skip-repeating-val-minimum', 3,\n                                                        'minimum amount of repeated values before skipping lines')\n\noffset_separator = theme.Parameter('telescope-offset-separator', '\u2502', 'offset separator of the telescope command')\noffset_delimiter = theme.Parameter('telescope-offset-delimiter', ':', 'offset delimiter of the telescope command')\nrepeating_marker = theme.Parameter('telescope-repeating-marker', '... \u2193',\n                                   'repeating values marker of the telescope command')\n\n\nparser = argparse.ArgumentParser(description=\"\"\"\n    Recursively dereferences pointers starting at the specified address\n    ($sp by default)\n    \"\"\")\nparser.add_argument(\"address\", nargs=\"?\", default=None, type=int, help=\"The address to telescope at.\")\nparser.add_argument(\"count\", nargs=\"?\", default=telescope_lines, type=int, help=\"The number of lines to show.\")\nparser.add_argument(\"-r\", \"--reverse\", dest=\"reverse\", action='store_true', default=False,\n                    help='Show <count> previous addresses instead of next ones')\n\n\n@pwndbg.commands.ArgparsedCommand(parser)\n@pwndbg.commands.OnlyWhenRunning\ndef telescope(address=None, count=telescope_lines, to_string=False, reverse=False):\n    \"\"\"\n    Recursively dereferences pointers starting at the specified address\n    ($sp by default)\n    \"\"\"\n    ptrsize = pwndbg.typeinfo.ptrsize\n    if telescope.repeat:\n        address = telescope.last_address + ptrsize\n        telescope.offset += 1\n    else:\n        telescope.offset = 0\n\n    address = int(address if address else pwndbg.regs.sp) & pwndbg.arch.ptrmask\n    count = max(int(count), 1) & pwndbg.arch.ptrmask\n    delimiter = T.delimiter(offset_delimiter)\n    separator = T.separator(offset_separator)\n\n    # Allow invocation of telescope -r to dump previous addresses\n    if reverse:\n        address -= (count - 1) * ptrsize\n\n    # Allow invocation of \"telescope 20\" to dump 20 bytes at the stack pointer\n    if address < pwndbg.memory.MMAP_MIN_ADDR and not pwndbg.memory.peek(address):\n        count   = address\n        address = pwndbg.regs.sp\n\n    # Allow invocation of \"telescope a b\" to dump all bytes from A to B\n    if int(address) <= int(count):\n        # adjust count if it is an address. use ceil division as count is number of\n        # ptrsize values and we don't want to strip out a value if dest is unaligned\n        count -= address\n        count = max(math.ceil(count / ptrsize), 1)\n\n    reg_values = collections.defaultdict(lambda: [])\n    for reg in pwndbg.regs.common:\n        reg_values[pwndbg.regs[reg]].append(reg)\n    # address    = pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, address)\n\n    start = address\n    stop  = address + (count*ptrsize)\n    step  = ptrsize\n\n    # Find all registers which show up in the trace\n    regs = {}\n    for i in range(start, stop, step):\n        values = list(reg_values[i])\n\n        for width in range(1, pwndbg.arch.ptrsize):\n            values.extend('%s-%i' % (r,width) for r in reg_values[i+width])\n\n        regs[i] = ' '.join(values)\n\n    # Find the longest set of register information\n    if regs:\n        longest_regs = max(map(len, regs.values()))\n    else:\n        longest_regs = 0\n\n    # Print everything out\n    result = []\n    last = None\n    collapse_buffer = []\n    skipped_padding = 2 + len(offset_delimiter) + 4 + len(offset_separator) + 1 + longest_regs + 1 - len(repeating_marker)\n\n    # Collapse repeating values exceeding minimum delta.\n    def collapse_repeating_values():\n        # The first line was already printed, hence increment by 1\n        if collapse_buffer and len(collapse_buffer) + 1 >= skip_repeating_values_minimum:\n            result.append(T.repeating_marker('%s%s%i skipped' % (repeating_marker, ' ' * skipped_padding, len(collapse_buffer))))\n        else:\n            result.extend(collapse_buffer)\n        collapse_buffer.clear()\n\n    for i, addr in enumerate(range(start, stop, step)):\n        if not pwndbg.memory.peek(addr):\n            collapse_repeating_values()\n            result.append(\"<Could not read memory at %#x>\" % addr)\n            break\n\n        line = ' '.join((T.offset(\"%02x%s%04x%s\" % (i + telescope.offset, delimiter,\n                                                    addr - start + (telescope.offset * ptrsize), separator)),\n                         T.register(regs[addr].ljust(longest_regs)),\n                         pwndbg.chain.format(addr)))\n\n        # Buffer repeating values.\n        if skip_repeating_values:\n            value = pwndbg.memory.pvoid(addr)\n            if last == value:\n                collapse_buffer.append(line)\n                continue\n            collapse_repeating_values()\n            last = value\n\n        result.append(line)\n\n    collapse_repeating_values()\n    telescope.offset += i\n    telescope.last_address = addr\n\n    if not to_string:\n        print('\\n'.join(result))\n\n    return result\n\n\nparser = argparse.ArgumentParser(description='dereferences on stack data with specified count and offset.')\nparser.add_argument('count', nargs='?', default=8, type=int,\n                    help='number of element to dump')\nparser.add_argument('offset', nargs='?', default=0, type=int,\n                    help='Element offset from $sp (support negative offset)')\n\n\n@pwndbg.commands.ArgparsedCommand(parser)\n@pwndbg.commands.OnlyWhenRunning\ndef stack(count, offset):\n    ptrsize = pwndbg.typeinfo.ptrsize\n    telescope.repeat = stack.repeat\n    telescope(address=pwndbg.regs.sp + offset * ptrsize, count=count)\n\n\ntelescope.last_address = 0\ntelescope.offset = 0\n", "path": "pwndbg/commands/telescope.py"}]}