Repository: pwndbg/pwndbg

Issue:
pwndbg fails to work with 64bit kernel in qemu
### Description

pwndbg raises when debugging a 64bit stripped kernel.
the error message looks like this:
~~~
pwndbg: loaded 196 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./vmlinux...(no debugging symbols found)...done.
pwndbg> target remote :1234
Remote debugging using :1234
Exception occurred: Error: Cannot access memory at address 0xf81802ff0 (<class 'gdb.MemoryError'>)
For more info invoke `set exception-verbose on` and rerun the command
or debug it by yourself with `set exception-debugger on`
Exception occurred: Error: Cannot access memory at address 0xf81802ff0 (<class 'gdb.MemoryError'>)
For more info invoke `set exception-verbose on` and rerun the command
or debug it by yourself with `set exception-debugger on`
Python Exception <class 'gdb.MemoryError'> Cannot access memory at address 0xf81802ff0: 
^CPython Exception <class 'KeyboardInterrupt'> : 
^CPython Exception <class 'KeyboardInterrupt'> Quit: 
^CPython Exception <class 'KeyboardInterrupt'> Quit: 
0xffffffff8111c398 in ?? ()
^CPython Exception <class 'KeyboardInterrupt'> Quit: 
pwndbg> vmmap
^CPython Exception <class 'KeyboardInterrupt'> Quit: 
Error occurred in Python command: Quit
^CPython Exception <class 'KeyboardInterrupt'> Quit:
~~~

### Steps to reproduce
0. download the kernel/initfs from https://github.com/mephi42/ctf/blob/master/2021.04.09-Midnight_Sun_CTF_2021_Quals/brohammer/brohammer.tar.gz
1. launch the kernel with command 
~~~
qemu-system-x86_64 \
    -m 1024M \
    -kernel ./vmlinuz \
    -initrd ./rootfs.img \
    -nographic \
    -monitor /dev/null \
    -append "nokaslr root=/dev/ram rw console=ttyS0 oops=panic paneic=1 quiet" \
    -s
~~~
2. extract the vmlinuz to vmlinux
3. run gdb with pwndbg and execute `target remote :1234`

### My setup
I'm using commit 87da998fcefe8cba85f51dba0056b923483c6c1c, which is the latest commit rn.
gdb version:
~~~
pwndbg> show version
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
pwndbg> py import sys; print(sys.version)
3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0]

~~~



Discussion:
executing `set architecture i386:x86-64` doesn't help
btw, it also prints error messages like this:
~~~
ERROR: Could not find ELF base!
ERROR: Could not find ELF base!
ERROR: Could not find ELF base!
ERROR: Could not find ELF base!
ERROR: Could not find ELF base!
0xffffffff8111c398 in ?? ()
ERROR: Could not find ELF base!
ERROR: Could not find ELF base!
~~~
There are a few things that adds to kernel debugging not working nicely in all cases. Those are more or less:
1. Looking for [ELF AUXV](http://articles.manugarg.com/aboutelfauxiliaryvectors.html) which may go through stack borders. This is totally irrelevant for kernel targets as there shouldn't be AUXV (afaik) and yet, going through stack pages may be slow (especially if we determine the wrong address as stack): https://github.com/pwndbg/pwndbg/blob/05036defa01d4d47bfad56867f53470a29fcdc89/pwndbg/auxv.py#L104-L106
2. Exploration of registers on stop. I think this was added for targets where we could not determine the memory layout right away e.g. from `/proc/$pid/maps`, so embedded or kernels. But honestly, this is not great **and I think we can remove it or better, move to a separate command especially now that we have [`vmmap add/clear/save/load` commands](https://github.com/pwndbg/pwndbg/blob/05036defa01d4d47bfad56867f53470a29fcdc89/pwndbg/commands/vmmap.py#L81-L116) and for kernels, we can do `monitor info-mem`.  https://github.com/pwndbg/pwndbg/blob/05036defa01d4d47bfad56867f53470a29fcdc89/pwndbg/vmmap.py#L78-L118
3. The execution of `monitor info-mem` on each stop. This does not break debugging of kernel targets but for x64 kernels there may be a lot of pages and the command+its parsing may be slow. We do this on each stop (via `@pwndbg.memoize.reset_on_stop`) to be correct but it may be better to call it once or once in a while and cache the result and e.g. tell the user to re-trigger this when needed (maybe on things like `search` etc): https://github.com/pwndbg/pwndbg/blob/05036defa01d4d47bfad56867f53470a29fcdc89/pwndbg/vmmap.py#L224-L267


Also, I am attaching an ugly workaround patch that disables all the redundant stuff and only uses the `monitor info-mem` 
[kernel.patch.txt](https://github.com/pwndbg/pwndbg/files/6376801/kernel.patch.txt) qemu command to determine memory pages. I hope it will help to develop a proper way to handle kernel debugging.

@Kyle-Kyle I assigned you to this since you started working on it :)
Sounds like there was not enough support for kernel debugging. Ok. Challenge accepted.
I am a beginner and I am experiencing the same problem.
I tried to run gdb with pwndbg and execute `target remote :1234` before starting qemu. after doing this I managed to debug but it still prints error messages :
```
ERROR: Could not find ELF base!
```
Sometimes this method doesn't work and I need to try a few more times.
Hope this solves your problem for now. 
Sorry, I don't know much about debugging and my English is terrible.
@Niebelungen-D yeah, this error needs to be fixed. We must not try to find ELF base on qemu kernel targets and we must not have this failure on normal binaries (I've seen this may happen on some recent Linuxes for userspace binaries).

For now, please use the kernel patch I linked above if you want to have an improved kernel debugging experience.
with a little fix. I think pwndbg works on Linux kernel now.

Resolving patch:
diff --git a/pwndbg/elf.py b/pwndbg/elf.py
--- a/pwndbg/elf.py
+++ b/pwndbg/elf.py
@@ -236,7 +236,7 @@ def get_ehdr(pointer):
     """
 
     # This just does not work :(
-    if pwndbg.qemu.is_usermode():
+    if pwndbg.qemu.is_qemu():
         return None, None
 
     vmmap = pwndbg.vmmap.find(pointer)


Test patch: