Repository: pwndbg/pwndbg

Issue:
Context fails when a particular value is present in any register
### Description
If a particular value is present in any register ctx throws
```
Cannot access memory at address 0x7ffffffff000
```
It seems to happen at 128TB split but curiously only with unaligned addresses that would cause a qword read to cross 128TB,
so 128TB-{1..7} throws but neither does 128TB-8 or 128TB

Full backtrace
```
Traceback (most recent call last):
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 130, in __call__
    return self.function(*args, **kwargs)
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 221, in _OnlyWhenRunning
    return function(*a, **kw)
  File "/opt/pwndbg/pwndbg/commands/context.py", line 269, in context
    result[target].extend(func(target=out,
  File "/opt/pwndbg/pwndbg/commands/context.py", line 350, in context_regs
    regs = get_regs()
  File "/opt/pwndbg/pwndbg/commands/context.py", line 405, in get_regs
    desc = pwndbg.chain.format(value)
  File "/opt/pwndbg/pwndbg/chain.py", line 112, in format
    enhanced = pwndbg.enhance.enhance(chain[-1], code=code)
  File "/opt/pwndbg/pwndbg/enhance.py", line 109, in enhance
    intval  = int(pwndbg.memory.poi(pwndbg.typeinfo.pvoid, value))
gdb.MemoryError: Cannot access memory at address 0x7ffffffff000
```
### Steps to reproduce

```asm
.globl _start
_start:
    mov $0x7fffffffeff8, %rdx # no err
    mov $0x7fffffffeffa, %rdx # err
    mov $0x7fffffffefff, %rdx # err
    mov $0x7ffffffff000, %rdx # no err
    int3
```
```sh
as test.s -o test.o ; ld -e _start test.o -o test
```

### My setup

<!--
Show us your gdb/python/pwndbg/OS/IDA Pro version (depending on your case).

NOTE: We are currently supporting only Ubuntu installations.
It is known that pwndbg is not fully working e.g. on Arch Linux (the heap stuff is not working there).
If you would like to change this situation - help us improving pwndbg and supporting other distros!

This can be displayed in pwndbg through `version` command.

If it is somehow unavailable, use:
* `show version` - for gdb
* `py import sys; print(sys.version)` - for python
* pwndbg version/git commit id
-->

Platform: Linux-5.13.9_1-x86_64-with-glibc2.32
Gdb:      10.2
Python:   3.9.6 (default, Jul  6 2021, 18:29:50)  [GCC 10.2.1 20201203]
Pwndbg:   1.1.0 build: b9e7bf1
Capstone: 4.0.1024
Unicorn:  1.0.3
This GDB was configured as follows:
   configure --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/usr/share/gdb (relocatable)
             --with-jit-reader-dir=/usr/lib64/gdb (relocatable)
             --without-libunwind-ia64
             --with-lzma
             --without-babeltrace
             --without-intel-pt
             --without-mpfr
             --without-xxhash
             --with-python=/usr (relocatable)
             --with-python-libdir=/usr/lib (relocatable)
             --with-debuginfod
             --without-guile
             --disable-source-highlight
             --with-separate-debug-dir=/usr/lib64/debug (relocatable)
             --with-system-gdbinit=/etc/gdb/gdbinit




Discussion:
Hah, nice catch! It seems that when we see if a given value is a pointer, we don't take into account the "end address".

To understand this better (for others) let's see the `vmmap` of a process created from your example:
```
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
          0x400000           0x402000 r-xp     2000 0      /home/dc/playground/pwndbg-946/test
    0x7ffff7ffb000     0x7ffff7ffe000 r--p     3000 0      [vvar]
    0x7ffff7ffe000     0x7ffff7fff000 r-xp     1000 0      [vdso]
    0x7ffffffde000     0x7ffffffff000 rwxp    21000 0      [stack]
0xffffffffff600000 0xffffffffff601000 --xp     1000 0      [vsyscall]
```

For me, the bug triggers for the `rdx` register:
```
pwndbg> i r rdx
rdx            0x7fffffffeffa      140737488351226
```

And this fails bcoz when we try to read a pointer at `0x7fffffffeffa` to enhance the display, reading 8B from it leads to going past the `[stack]` page:
```
pwndbg> p/x 0x7fffffffeffa+8
$3 = 0x7ffffffff002
```
(the `0x7ffffffff002` is past the `0x7ffffffde000     0x7ffffffff000 rwxp    21000 0      [stack]` page)

Resolving patch:
diff --git a/pwndbg/enhance.py b/pwndbg/enhance.py
--- a/pwndbg/enhance.py
+++ b/pwndbg/enhance.py
@@ -106,6 +106,10 @@ def enhance(value, code = True):
     if szval:
         szval = E.string(repr(szval))
 
+    # Fix for case we can't read the end address anyway (#946)
+    if value + pwndbg.arch.ptrsize > page.end:
+        return E.integer(int_str(value))
+
     intval  = int(pwndbg.memory.poi(pwndbg.typeinfo.pvoid, value))
     intval0 = intval
     if 0 <= intval < 10:


Test patch: