mirror of https://github.com/pwndbg/pwndbg.git
Fix pwndbg.disasm.near with disabled caching (#465)
Before this changes `context_disasm` produced different display based on memoization settings.
The bug can be seen below:
```
[dc@dc:pwndbg|dev $%]$ gdb ~/test/a.out
pwndbg: loaded 166 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from /home/dc/test/a.out...(no debugging symbols found)...done.
pwndbg> set context-sections disasm
Set which context sections are displayed (controls order) to 'disasm'
pwndbg> entry
Temporary breakpoint 1 at 0x400080
Temporary breakpoint 1, 0x0000000000400080 in _start ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
Breakpoint *0x400080
pwndbg> python import pwndbg; pwndbg.memoize.memoize.caching=False
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
↓
► 0x400080 <_start> jmp _start <0x400080>
Breakpoint *0x400080
pwndbg>
```
The tested binary can be reproduced with this assembly code:
```asm
global _start
_start:
jmp $
```
Compiled as `nasm -f elf64 code.asm && ld code.o`.
---
About the bug:
The check for multiple identical loops or rets is done using `set(insns[-3:])`. Before this hapens the `insns` is filled with the results of `one(address)`. This calls `get_one_instruction(address)` which is cached until `reset_on_cont`. As a result, when caching is enabled the `get_one_instruction` returns the same `capstone.CsInsn` instances for given address. When it is disabled, we return other instances which are identical.
The problem was that `set(insns[-3:])` creates a set based on `capstone.CsInsn` instances and not on the instruction addresses.
The fix changes this behavior so that we compare last 3 instruction addresses.
pull/466/head
parent
7d77bf7004
commit
812186aeef
Loading…
Reference in new issue