Repository: pwndbg/pwndbg

Issue:
bp breaks on pie binaries before run
<!--
Before reporting a new issue, make sure that we do not have any duplicates already open.
If there is one it might be good to take part in the discussion there.

Please make sure you have checked that the issue persists on LATEST pwndbg version.

Below is a template for BUG REPORTS.
Don't include it if this is a FEATURE REQUEST.
-->


### Description
In the windbg commands while setting a breakpoint using `bp` the address is converted to int

https://github.com/pwndbg/pwndbg/blob/ca17c6dbb0d1bc40ef060331aa48dad0675c5df9/pwndbg/commands/windbg.py#L297

using `pwndbg.inthook.xint`. This verifies if the argument is actually an address but in case of pie binaries it could be possible that the address is loaded later and then the argument is casted to `uint32_t`
### Steps to reproduce
```sh
[/tmp] tail hello.c                                                                                                                                                                  
#include <stdio.h>

int main(int argc, char **argv) {
    puts("Hello World");
    return 0;
}
[/tmp] make hello                                                                                                                                                                    17:41:43 
cc     hello.c   -o hello
[/tmp] gdb -q hello                                                                                                                                                                  17:41:47 
pwndbg: loaded 177 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from hello...(no debugging symbols found)...done.
pwndbg> bp 0x00005555555546b0
Breakpoint 1 at 0x555546b0
pwndbg> bl
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000555546b0 
pwndbg> r
Starting program: /tmp/hello 
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x555546b0

```

### My setup
```sh
[pwndbg] git --no-pager log -1 --stat                                                                                                                                      18:07:21  ☁  dev ☀
commit ca17c6dbb0d1bc40ef060331aa48dad0675c5df9
Author: Alisson Bezerra <alissonb@outlook.com>
Date:   Tue Apr 9 05:54:00 2019 -0300

    Add xuntil command (#604)

 pwndbg/commands/peda.py | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
[pwndbg] lsb_release -a                                                                                                                                                    18:08:01  ☁  dev ☀
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 9.8 (stretch)
Release:	9.8
Codename:	stretch
[pwndbg] gdb -q                                                                                                                                                            18:10:56  ☁  dev ☀
pwndbg: loaded 178 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
pwndbg> show version
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 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.5.3 (default, Sep 27 2018, 17:25:39) 
[GCC 6.3.0 20170516]
pwndbg> 

```
<!--
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
-->


Discussion:
Thanks for reporting this. Woa, this is an interesting bug.

Would you mind working on a fix for this?
Sure Yea. I'll try to send a PR.
As I was looking at some other unrelated things, I stumbled across this as well. 

To debug this a bit more, I added the following right before [pwndbg/inthook.py:42](https://github.com/pwndbg/pwndbg/blob/93aabaa5fb9aa806eab8cd5017739673500c1cac/pwndbg/inthook.py#L42)
```
print("sizeof(long): " + str(pwndbg.typeinfo.long.sizeof))
print("sizeof(int64) : " + str(pwndbg.typeinfo.int64.sizeof))
print("sizeof(void *): " + str(pwndbg.typeinfo.pvoid.sizeof))
print("Arch: " + pwndbg.arch.current)
```
Here is the output I got:
```
$gdb binary
pwndbg> bp 0x555555554200
sizeof(long): 4
sizeof(int64) : 8
sizeof(void *): 4
Arch: i386
Breakpoint 1 at 0x55554200
pwndbg> start
[Error removed for brevity]
sizeof(long): 8
sizeof(int64) : 8
sizeof(void *): 8
Arch: x86-64
```

To me, it appears that prior to running the binary, pwndbg has the wrong typeinfo. It seems to be using assuming that the binary is 32 bit. After running the binary, the typeinfo seems to be correct. 

I realize this information comes from gdb.lookup_type, which makes this quite strange.
It's especially strange given that gdb doesn't seem to predefine types like int given that gdb.lookup_type doesn't return anything rust/golang binaries that don't have those types (This is from what I recall reading, I can't seem to find anything about it now). 

One potential solution to this would just be cast to int64 instead of long if the binary is 64 bit, or potentially always, unless it ends up breaking something. 

It also looks like the arch for pwndbg doesn't get changed until the binary is started. It just stays at the default. 
The only actual way I could figure out to get if the binary was 64 bit or not was by running `info target` and parsing that. 
Sorry to be replying again, but I found something new.
I'm still not sure why gdb.lookup_type behaves the way it does.
Even still, we can fix this by generating correct typeinfo when the binary is loaded. The reason we currently do not get correct typeinfo is that the [update method in typeinfo.py](https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/typeinfo.py#L46) only listens for the start and stop events. I believe a way to fix this would be to have the `update` method listen for `@pwndbg.events.new_objfile` to get correct type information.
It doesn't seem like this could break anything, but I would rather have someone with more knowledge of the type system give input.
> Sorry to be replying again, but I found something new.
Don't be sorry for replying! That's great that you contribute!

Can it be a bug withing gdb itself? I sometimes stumbled upon certain things not working properly or working a bit differently e.g. for PIE binaries or remote debugging. It could have been a GDB issue or this typeinfo thing...

Regarding the potential fix, I think it is okay if we just subscribe to one more event.
> Don't be sorry for replying! That's great that you contribute!

Thanks. I'm new to contributing on github so just trying to feel out the etiquette. 
> Can it be a bug withing gdb itself? I sometimes stumbled upon certain things not working properly or working a bit differently e.g. for PIE binaries or remote debugging. It could have been a GDB issue or this typeinfo thing...

This behavior doesn't actually appear unique to PIE binaries, it's just that no one tries breaking on high addresses for non-pie binaries. 

> Regarding the potential fix, I think it is okay if we just subscribe to one more event.

I'll open a pull request.

Resolving patch:
diff --git a/pwndbg/typeinfo.py b/pwndbg/typeinfo.py
--- a/pwndbg/typeinfo.py
+++ b/pwndbg/typeinfo.py
@@ -43,6 +43,7 @@ def lookup_types(*types):
     raise exc
 
 
+@pwndbg.events.new_objfile
 @pwndbg.events.start
 @pwndbg.events.stop
 def update():


Test patch: