like-dbg
like-dbg copied to clipboard
WIP: support pwndbg as a GDB extension
NOT MERGABLE YET
I'm currently running into a
pwndbg: loaded 196 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
The target architecture is set to "i386:x86-64:intel".
Reading symbols from /io/vmlinux...
add symbol table from file "/io/vmlinux"
Reading symbols from /io/vmlinux...
Breakpoint 1 at 0xffffffff82cff9b4: file init/main.c, line 849.
The program is not being run.
loading vmlinux
Remote debugging using :1234
0x000000000000fff0 in exception_stacks ()
------- tip of the day (disable with set show-tips off) -------
GDB's follow-fork-mode parameter can be used to set whether to trace parent or child after fork() calls
Exception occurred: Error: invalid literal for int() with base 10: '' (<class 'ValueError'>)
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 'ValueError'> invalid literal for int() with base 10: '':
pwndbg> set exception-verbose on
Set whether to print a full stacktrace for exceptions raised in Pwndbg commands to True
Traceback (most recent call last):
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/home/user/pwndbg/pwndbg/symbol.py", line 96, in autofetch
for mapping in pwndbg.vmmap.get():
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 62, in get
pages.extend(kernel_vmmap_via_page_tables())
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 358, in kernel_vmmap_via_page_tables
p.lazy_init()
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 162, in lazy_init
pid = int(proc.read().strip(), 10)
ValueError: invalid literal for int() with base 10: ''
If that is an issue, you can report it on https://github.com/pwndbg/pwndbg/issues
(Please don't forget to search if it hasn't been reported before)
To generate the report and open a browser, you may run `bugreport --run-browser`
PS: Pull requests are welcome
Traceback (most recent call last):
File "/home/user/pwndbg/pwndbg/gdblib/prompt.py", line 47, in initial_hook
prompt_hook(*a)
File "/home/user/pwndbg/pwndbg/gdblib/prompt.py", line 57, in prompt_hook
pwndbg.gdblib.events.after_reload(start=cur is None)
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 234, in after_reload
f()
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 169, in caller
raise e
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/home/user/pwndbg/pwndbg/symbol.py", line 96, in autofetch
for mapping in pwndbg.vmmap.get():
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 62, in get
pages.extend(kernel_vmmap_via_page_tables())
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 358, in kernel_vmmap_via_page_tables
p.lazy_init()
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 162, in lazy_init
pid = int(proc.read().strip(), 10)
ValueError: invalid literal for int() with base 10: ''
The latest change (which made sense in the first place) shifts the error in a different direction:
pwndbg: loaded 196 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
The target architecture is set to "i386:x86-64:intel".
Reading symbols from /io/vmlinux...
add symbol table from file "/io/vmlinux"
Reading symbols from /io/vmlinux...
Remote debugging using :1234
0x000000000000fff0 in exception_stacks ()
Breakpoint 1 at 0xffffffff82cff9b4: file init/main.c, line 849.
Continuing.
Exception occurred: Error: invalid literal for int() with base 10: '' (<class 'ValueError'>)
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 'ValueError'> invalid literal for int() with base 10: '':
Breakpoint 1, start_kernel () at init/main.c:849
849 {
loading vmlinux
------- tip of the day (disable with set show-tips off) -------
Use GDB's pi command to run an interactive Python console where you can use Pwndbg APIs like pwndbg.gdblib.memory.read(addr, len), pwndbg.gdblib.memory.write(addr, data), pwndbg.gdb.vmmap.get() and so on!
Exception occurred: Error: invalid literal for int() with base 10: '' (<class 'ValueError'>)
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 'ValueError'> invalid literal for int() with base 10: '':
After hitting continue
in pwndbg
the kernel boots but gdb is still broken:
^C
Program received signal SIGINT, Interrupt.
default_idle () at arch/x86/kernel/process.c:689
689 }
Exception occurred: Error: invalid literal for int() with base 10: '' (<class 'ValueError'>)
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 'ValueError'> invalid literal for int() with base 10: '':
pwndbg> set exception-verbose on
Set whether to print a full stacktrace for exceptions raised in Pwndbg commands to True
Traceback (most recent call last):
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/home/user/pwndbg/pwndbg/symbol.py", line 96, in autofetch
for mapping in pwndbg.vmmap.get():
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 62, in get
pages.extend(kernel_vmmap_via_page_tables())
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 358, in kernel_vmmap_via_page_tables
p.lazy_init()
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 162, in lazy_init
pid = int(proc.read().strip(), 10)
ValueError: invalid literal for int() with base 10: ''
If that is an issue, you can report it on https://github.com/pwndbg/pwndbg/issues
(Please don't forget to search if it hasn't been reported before)
To generate the report and open a browser, you may run `bugreport --run-browser`
PS: Pull requests are welcome
Traceback (most recent call last):
File "/home/user/pwndbg/pwndbg/gdblib/prompt.py", line 47, in initial_hook
prompt_hook(*a)
File "/home/user/pwndbg/pwndbg/gdblib/prompt.py", line 57, in prompt_hook
pwndbg.gdblib.events.after_reload(start=cur is None)
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 234, in after_reload
f()
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 169, in caller
raise e
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/home/user/pwndbg/pwndbg/symbol.py", line 96, in autofetch
for mapping in pwndbg.vmmap.get():
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 62, in get
pages.extend(kernel_vmmap_via_page_tables())
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 358, in kernel_vmmap_via_page_tables
p.lazy_init()
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 162, in lazy_init
pid = int(proc.read().strip(), 10)
ValueError: invalid literal for int() with base 10: ''
We spoke about this on Discord, but I will document this here as well.
This fails because gdb-pt-dump
that Pwndbg rely on looks for the qemu-system
process PID in here: https://github.com/martinradev/gdb-pt-dump/blob/f25898adc61d60e5f30c6452b15700bbf1bd630c/pt.py#L161-L162
And you launch the two - qemu-system (the linux vm) - and the GDB - in two separate containers. As a result, they end up in two different PID Linux namespaces and so they cannot see each other's PIDs/processes.
Running the containers with --pid=host
would mitigate this issue but then we end up with permission errors:
pwndbg> set exception-verbose on
Set whether to print a full stacktrace for exceptions raised in Pwndbg commands to True
Traceback (most recent call last):
File "/home/user/pwndbg/pwndbg/gdblib/events.py", line 164, in caller
func()
File "/home/user/pwndbg/pwndbg/symbol.py", line 96, in autofetch
for mapping in pwndbg.vmmap.get():
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 62, in get
pages.extend(kernel_vmmap_via_page_tables())
File "/home/user/pwndbg/pwndbg/lib/memoize.py", line 49, in __call__
value = self.func(*args, **kwargs)
File "/home/user/pwndbg/pwndbg/vmmap.py", line 358, in kernel_vmmap_via_page_tables
p.lazy_init()
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 164, in lazy_init
self.phys_mem = VMPhysMem(pid)
File "/home/user/pwndbg/gdb-pt-dump/pt.py", line 18, in __init__
self.file = os.open(f"/proc/{pid}/mem", os.O_RDONLY)
PermissionError: [Errno 13] Permission denied: '/proc/72600/mem'
That's likely because of AppArmor profile blocking write access to /proc/$pid/*
files. Fwiw this policy can be seen here: https://github.com/moby/moby/blob/924edb948c2731df3b77697a8fcc85da3f6eef57/profiles/apparmor/template.go#L37-L38
So now running the container additionally with --security-opt apparmor=unconfined
(basically: disabling AppArmor) should probably fix this.
But this isn't really a great solution. We don't want people to do all this.
A potential solution could be using set kernel-vmmap-via-page-tables off
but this will make Pwndbg to fetch memory map information from QEMU's GDB stub and its monitor info mem
command. This... should work, but may be painfully slow, as QEMU renders LOTS of those memory map information (I think it does not merge them) and also it is not super accurate as iirc they don't show whether a page is writable or executable (I don't remember which one, I think exec).
Added -ex 'set kernel-vmmap-via-page-tables off' -ex 'set exception-verbose on'
for debugging purposes to the GDB invocation, leaving us with the follow command:
gdb-multiarch -q /io/vmlinux -iex 'set architecture i386:x86-64:intel' -ex 'add-symbol-file /io/vmlinux' -ex 'set kernel-vmmap-via-page-tables off' -ex 'set exception-verbose on' -ex 'target remote :1234' -ex 'break start_kernel' -ex continue -ex lx-symbols
This seems to run "fine", as in it does not fully crash. However, there's still the problem that the add-symbol-file
fails for some reason. While pwndbg
itself is still causing exceptions as seen here:
Single-stepping through the instructions was not painfully slow for me.
Neither solution, hacking more flags into the the docker run
command, nor bypassing an intended pwndbg
feature seem like a good idea just to make this work.
Holding off a merge until a clean solution is found.