You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are two bugs regarding displaying of registers:
Wrong registers read
Improper caching
Wrong registers read
We read registers from newest_frame instead of selected_frame - as a result, we display registers not from the current frame. This happens only for GDB>=7.9 as can be seen below.
To see this - break somewhere in a deep call, then do up 2, then display context regs and compare IP/PC with info reg pc.
I have fixed the 1st issue locally but apparently the context display wasn't right. When I did pi pwndbg.memoize.memoize.caching = False and then context regs it has been fixed.
So I investigated this and found out that we have two (or more?) methods to fetch registers:
It turns out, that some registers are fetched via __getitem__ and cached and this bites us here: it seems the context register values are fetched, cached and not invalidated this way.
So to fix that, we need to add @pwndbg.memoize.reset_on_prompt to __getitem__.
One could ask if we should have both methods at the first place - or - why do we have both of them? I don't know. We should probably remove one of them and refactor other places to use just the other one. But this can be done in the future. If someone is willing to refactor this, please do so :).
The text was updated successfully, but these errors were encountered:
TLDR:
1. We read registers from `newest_frame` instead of `selected_frame` for GDB>=7.9.
2. We have two ways to fetch registers - `regs.__getitem__` and
`regs.__getattr__` - one of them didn't invalidate cache and so after
fixing 1st, we still shown the old register after switching frames.
It looks like __getitem__ functions as a wrapper for __getattr__ when you ask for a string (e.g.) "rax". Otherwise it uses arch_to_regs. Do you know why getitem uses arch_to_regs whereas getattr uses get_register()?
There are two bugs regarding displaying of registers:
Wrong registers read
We read registers from
newest_frame
instead ofselected_frame
- as a result, we display registers not from the current frame. This happens only for GDB>=7.9 as can be seen below.To see this - break somewhere in a deep call, then do
up 2
, then displaycontext regs
and compare IP/PC withinfo reg pc
.Code responsible for the issue:
pwndbg/pwndbg/regs.py
Lines 246 to 252 in a729a82
Some example:
Improper caching
I have fixed the 1st issue locally but apparently the context display wasn't right. When I did
pi pwndbg.memoize.memoize.caching = False
and thencontext regs
it has been fixed.So I investigated this and found out that we have two (or more?) methods to fetch registers:
__getattr__
__getitem__
This can be seen here:
pwndbg/pwndbg/regs.py
Lines 269 to 306 in a729a82
Not that far ago, we had some problems with caching and we added the
@pwndbg.memoize.reset_on_prompt
cache invalidation for__getattr__
.It turns out, that some registers are fetched via
__getitem__
and cached and this bites us here: it seems the context register values are fetched, cached and not invalidated this way.So to fix that, we need to add
@pwndbg.memoize.reset_on_prompt
to__getitem__
.One could ask if we should have both methods at the first place - or - why do we have both of them? I don't know. We should probably remove one of them and refactor other places to use just the other one. But this can be done in the future. If someone is willing to refactor this, please do so :).
The text was updated successfully, but these errors were encountered: