ghidra
ghidra copied to clipboard
Breakpoints are incorrectly placed for i386 and x86_64 targets in qemu+gdb debugger
Describe the bug When using the qemu+gdb debugger profile for i386 and x86_64 targets, breakpoints are not placed correctly. For example, in a hello world dynamic binary that I just built for i386, attempting to place a breakpoint on main places one at 0x119d but the actual placement of main is 0x4000119d.
The python plugin to gdb is correctly querying the sections, and what it receives is:
(gdb) maintenance info sections -all-objects
Exec file: `/home/electricworry/projects/debugger/i386', file type elf32-i386.
[0] 0x0194->0x01a7 at 0x00000194: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x01a8->0x01cc at 0x000001a8: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
[2] 0x01cc->0x01ec at 0x000001cc: .note.ABI-tag ALLOC LOAD READONLY DATA HAS_CONTENTS
[3] 0x01ec->0x020c at 0x000001ec: .gnu.hash ALLOC LOAD READONLY DATA HAS_CONTENTS
[4] 0x020c->0x028c at 0x0000020c: .dynsym ALLOC LOAD READONLY DATA HAS_CONTENTS
[5] 0x028c->0x0332 at 0x0000028c: .dynstr ALLOC LOAD READONLY DATA HAS_CONTENTS
[6] 0x0332->0x0342 at 0x00000332: .gnu.version ALLOC LOAD READONLY DATA HAS_CONTENTS
[7] 0x0344->0x0384 at 0x00000344: .gnu.version_r ALLOC LOAD READONLY DATA HAS_CONTENTS
[8] 0x0384->0x03c4 at 0x00000384: .rel.dyn ALLOC LOAD READONLY DATA HAS_CONTENTS
[9] 0x03c4->0x03d4 at 0x000003c4: .rel.plt ALLOC LOAD READONLY DATA HAS_CONTENTS
[10] 0x1000->0x1024 at 0x00001000: .init ALLOC LOAD READONLY CODE HAS_CONTENTS
[11] 0x1030->0x1060 at 0x00001030: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS
[12] 0x1060->0x1068 at 0x00001060: .plt.got ALLOC LOAD READONLY CODE HAS_CONTENTS
[13] 0x40001070->0x400011dd at 0x00001070: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
[14] 0x11e0->0x11f8 at 0x000011e0: .fini ALLOC LOAD READONLY CODE HAS_CONTENTS
[15] 0x2000->0x2016 at 0x00002000: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS
[16] 0x2018->0x204c at 0x00002018: .eh_frame_hdr ALLOC LOAD READONLY DATA HAS_CONTENTS
[17] 0x204c->0x20fc at 0x0000204c: .eh_frame ALLOC LOAD READONLY DATA HAS_CONTENTS
[18] 0x3ed8->0x3edc at 0x00002ed8: .init_array ALLOC LOAD DATA HAS_CONTENTS
[19] 0x3edc->0x3ee0 at 0x00002edc: .fini_array ALLOC LOAD DATA HAS_CONTENTS
[20] 0x3ee0->0x3fd8 at 0x00002ee0: .dynamic ALLOC LOAD DATA HAS_CONTENTS
[21] 0x3fd8->0x4000 at 0x00002fd8: .got ALLOC LOAD DATA HAS_CONTENTS
[22] 0x40004000->0x40004008 at 0x00003000: .data ALLOC LOAD DATA HAS_CONTENTS
[23] 0x40004008->0x4000400c at 0x00003008: .bss ALLOC
[24] 0x0000->0x002b at 0x00003008: .comment READONLY HAS_CONTENTS
This information gets as far as the "Map sections" view in Modules:
However, breakpoints are not being placed correctly:
To Reproduce Steps to reproduce the behavior:
- Make a dynamic hello world:
gcc -m32 -x c -o i386 - <<EOF
#include <stdio.h>
int main (int argc, char *argv[])
{
printf("hello, world!\n");
return 0;
}
EOF
- Import i386 to Ghidra project
- Open i386 in the Debugger tool
- Parameters:
- Image: path to i386
- Arguments: NONE
- QEMU command qemu-i386
- QEMU Port: 12345
- Extra qemu arguments: NONE
- gdb command: gdb-multiarch
- Wait for module mapping to complete
- In Modules window, right-click on i386 and select 'Refresh all modules and all sections'
- Again, right-click on i386 and select 'Map sections'. Confirm that the .text section is has a dynamic base much higher than the other sections, e.g. 40001070
- Place cursor on main and press 'k' to create a new breakpoint
- Observe in Breakpoints window that the breakpoint is not placed in the .text section. Furthermore, in the gdb terminal, confirm that the breakpoint doesn't match the location of main:
(gdb) info break
Num Type Disp Enb Address What
1 catchpoint keep y syscalls "break, brk, mmap, munmap, mprotect, msync, mlock, munlock, mlockall, munlockall, mremap, mmap2, mincore, madvise, remap_fil
e_pages, mbind, get_mempolicy, set_mempolicy, migrate_pages, move_pages"
silent
hooks-ghidra event-memory
cont
2 breakpoint keep y 0x0000119d
(gdb) print main
$1 = {<text variable, no debug info>} 0x4000119d <main>
Expected behavior I would hope that the translation from binary offset to process memory location would take into account the placement of .text and place the breakpoint at the correct address.
Environment (please complete the following information):
- OS: Ubuntu 22.04.3
- Java Version: OpenJDK 21.0.3
- Ghidra Version: 11.1.1
- Ghidra Origin: official GitHub distro