NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
49.06k stars 5.65k forks source link

Debuffer-agent-gdb Python module file commands.py crashes in put_bytes if a memory address is not readable. #6647

Closed lexknuther closed 1 week ago

lexknuther commented 1 week ago

Describe the bug The put_bytes function in command.py doesn't wrap inf.read_memory in a try/except block. As a result, any area of memory that can't be read results in a debugger crash. I discovered this will testing a simple binary for the STM3210E-EVAL board. Wrapping the call in a try/except block and returning an equivalent number of zeros bypasses the problem; however, there should probably be some application level signaling that marks the memory as unreadable.

To Reproduce Steps to reproduce the behavior:

  1. Create a simple elf binary using STM32Cube IDE using the attached main.c file.
  2. Load the binary onto a STM3210E-EVAL board.
  3. Launch ST_LINK-gdbserver as your gdbserver
  4. Debugger -> Configure and Launch using ... -> remote gdb
  5. Enter 61234 as the port number and click 'Launch.'
  6. The debugger errors out with

. Traceback (most recent call last): File "/home/brandon-enochs/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src/ghidragdb/hooks.py", line 161, in _func return func(*args, **kwargs) File "/home/brandon-enochs/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src/ghidragdb/hooks.py", line 311, in on_stop state.record("Stopped") File "/home/brandon-enochs/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src/ghidragdb/hooks.py", line 97, in record commands.putmem("$sp", "1", from_tty=False) File "/home/brandon-enochs/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src/ghidragdb/commands.py", line 516, in putmem return put_bytes(start, end, pages, is_mi, from_tty) File "/home/brandon-enochs/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src/ghidragdb/commands.py", line 481, in put_bytes buf = bytes(inf.read_memory(start, end - start)) gdb.MemoryError: Cannot access memory at address 0x20018000 Python Exception <class 'gdb.MemoryError'>: Cannot access memory at address 0x20018000

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

Attachments main.c

Environment (please complete the following information):

Additional context

Add any other context about the problem here.

d-millar commented 1 week ago

@lexknuther Yep, we can try-except that. Hadn't occurred to me at least that the stack pointer would be inaccessible. That may cause other problems. I'd be interested in knowing if commenting that line out gets you further and is just the beginning of more badness.

lexknuther commented 1 week ago

Yeah, I'm still working on the root cause.

nsadeveloper789 commented 1 week ago

I remember doing this for LLDB, but I guess we never did the same for GDB. I concur that somewhere in commands.py we should add the try-catch (as opposed to hooks.py). I'll have to review what we did for the others before I commit to that, though. We do have a mechanism for signalling the app, so that it doesn't try (repeatedly) to re-read the same spot of memory in error. Generally, in the except clause, we do a putmem-state [range] error, which will paint the region red in the dynamic listing and prevent future attempts to read it automatically. I'll put an internal ticket in for this.