Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error editing memory of trace in emulator #7413

Open
hexagonal-sun opened this issue Jan 24, 2025 · 6 comments
Open

Error editing memory of trace in emulator #7413

hexagonal-sun opened this issue Jan 24, 2025 · 6 comments
Assignees
Labels
Feature: Debugger Status: Internal This is being tracked internally by the Ghidra team

Comments

@hexagonal-sun
Copy link

Describe the bug
When I try to modify the memory of a trace that I've taken in gdb in the emulator, I get an error. Backtrace:

Cannot invoke "ghidra.app.services.DebuggerTraceManagerService.resolveView(ghidra.trace.model.program.TraceProgramView)" because "this.this$0.traceManager" is null
java.lang.NullPointerException: Cannot invoke "ghidra.app.services.DebuggerTraceManagerService.resolveView(ghidra.trace.model.program.TraceProgramView)" because "this.this$0.traceManager" is null
	at ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin$FollowsViewStateEditor.getCoordinates(DebuggerControlServicePlugin.java:133)
	at ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin$AbstractStateEditor.setVariable(DebuggerControlServicePlugin.java:72)
	at ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin$FollowsViewStateEditor.setVariable(DebuggerControlServicePlugin.java:118)
	at ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin$FollowsViewStateEditor.putByte(DebuggerControlServicePlugin.java:160)
	at ghidra.trace.database.program.AbstractDBTraceProgramViewMemory.setByte(AbstractDBTraceProgramViewMemory.java:343)
	at ghidra.app.plugin.core.byteviewer.MemoryByteBlock.setByte(MemoryByteBlock.java:110)
	at ghidra.app.plugin.core.format.HexFormatModel.replaceValue(HexFormatModel.java:283)
	at ghidra.app.plugin.core.byteviewer.ByteViewerComponent.keyPressed(ByteViewerComponent.java:296)
	at docking.widgets.fieldpanel.FieldPanel$CursorHandler.notifyInputListeners(FieldPanel.java:2494)
	at docking.widgets.fieldpanel.FieldPanel$FieldPanelKeyAdapter.keyPressed(FieldPanel.java:1787)
	at java.desktop/java.awt.Component.processKeyEvent(Component.java:6579)
	at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2911)
	at java.desktop/java.awt.Component.processEvent(Component.java:6398)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1942)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1146)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4877)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

---------------------------------------------------
Build Date: 2024-Nov-05 1643 EST
Ghidra Version: 11.2.1
Java Home: /nix/store/j3m8b0ddrb0jp0y8d3a31l2lw810y6wv-openjdk-23.0.1+11/lib/openjdk
JVM Version: N/A 23.0.1
OS: Linux 6.13.0 amd64

To Reproduce
Steps to reproduce the behavior:

  1. Open a program in the debugger.
  2. Run the program via gdb, set a breakpoint and continue.
  3. Once breakpoint has been hit, kill the program and close the tool to create a trace.
  4. Open the program in the emulator
  5. Open the trace just created
  6. Jump to the breakpoint snapshot.
  7. Goto Window -> Byte Viewer -> Memory Auto PC
  8. Attempt to modify a byte in the memory window.
  9. Error should be shown.

Expected behavior
The memory should be editable, or if editing the memory of traces isn't supported, a more appropriate error should be shown.

Environment (please complete the following information):
Build Date: 2024-Nov-05 1643 EST
Ghidra Version: 11.2.1
Java Home: /nix/store/j3m8b0ddrb0jp0y8d3a31l2lw810y6wv-openjdk-23.0.1+11/lib/openjdk
JVM Version: N/A 23.0.1
OS: Linux 6.13.0 amd64 (NixOS)

@d-millar
Copy link
Collaborator

@hexagonal-sun Just tried your suggestion in the current build and seemed to have worked, so possibly it has been fixed or possibly I'm doing slightly different than you did. My steps:

  1. Open a program in the debugger. (I used "gedit".)
  2. Run the program via gdb, set a breakpoint and continue. (I put the breakpoint in "main".)
  3. Once breakpoint has been hit, kill the program and close the tool to create a trace. (I killed the program via the "Kill" button, then "Close"d the connection from the Connections View - I did not close the tool, as that seemed unnecessary.)
  4. Open the program in the emulator. (I didn't do this explicitly.)
  5. Open the trace just created. (I dragged the new trace from New Traces->gdb->gedit into the Debugger Tool - this automatically sets up emulation.)
  6. Jump to the breakpoint snapshot. (I double-cliicked the Time entry for the breakpoint.)
  7. Goto Window -> Byte Viewer -> Memory Auto PC. (Did that.)
  8. Attempt to modify a byte in the memory window. (I clicked the Enable Editing button, then clicked on the bytes in Memory, and changed them to DE AD BE EF. The bytes were changed in the Memory and Dynamic Listing Views.)

Not much of the code in your stack trace has changed in the last year, so I have a feeling something I'm doing differs slightly from what you're doing. I will continue to play around, fo course, to see if I can re-create your error. Maybe try my variations above - see if you still see the error?

@hexagonal-sun
Copy link
Author

@d-millar Thanks for your reply! I just tried your steps and that didn't cause the error. So it seems as though it's related to closing the debugger and then opening the program in the emulator tool. Note that if you close ghidra completely and re-open it the issue is fixed. You need to perform the above steps without closing ghidra completely.

I've also verified that it's nothing to do with the program that I'm reversing. I've just replicated it with vim.

Hope that helps!

@d-millar
Copy link
Collaborator

Ah, that definitely helps - hopefully, i’ll be able to recreate this later today and knock out a fix. By the by, in case it wasn’t clear, you don’t have to close anything to get the trace, i.e. the trace is active and updated all the time. You can close the connection, if you prefer not to have the debugger running, and the residual trace should be (let me know if i’m wrong about this) identical to the trace you’re getting by closing and re-opening.

@d-millar
Copy link
Collaborator

I've located the problem (going to defer to @nsadeveloper789 for the solution), but should be a relatively simple fix. You're correct it's closing the tool that causes the problem - leaves a stale reference in the memory handler. As noted, the workaround for now is probably not to close the tool or, if you have to, restart Ghidra. Thanks for pointing this out!

@ryanmkurtz ryanmkurtz added the Status: Triage Information is being gathered label Jan 27, 2025
@nsadeveloper789
Copy link
Contributor

FWIW, there is no need to close the Debugger to re-open in the Emulator. The Emulator is just the Debugger without any connectors. If you need to create/save a trace explicitly, use the menus: Debugger → Save Trace. The flaw is pretty obvious (now that we've seen it happen), and I think the fix will be easy.

@nsadeveloper789 nsadeveloper789 added Feature: Debugger Status: Internal This is being tracked internally by the Ghidra team and removed Feature: Emulation Status: Triage Information is being gathered labels Jan 27, 2025
@nsadeveloper789
Copy link
Contributor

Eh. Not so easy. We could develop another workaround, but I don't think it's worth it given the existing workarounds. The whole LiveMemoryHandler thing is flawed given the possibility of two tools having the trace open at the same time. Any attempt to fix this while keeping that in place would have to consider in what order things are opened and closed in what tools, or worse that it remains open in more than one tool.

We'll need some time with this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Debugger Status: Internal This is being tracked internally by the Ghidra team
Projects
None yet
Development

No branches or pull requests

4 participants