ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Ghidra emulator stops working when stumbled upon LOCK instruction

Open nogitsune-youkai opened this issue 1 year ago • 4 comments

Describe the bug When emulating software which runs in VM, ghidra apparently can't emulate properly LOCK instruction. Is it a bug or i'm doing something wrong?

To Reproduce Steps to reproduce the behavior:

  1. Simply launch emulator and emulate program

Expected behavior LOCK instruction should be emulated without issues.

Environment (please complete the following information):

  • OS: [Win 11]
  • Java Version: [21]
  • Ghidra Version: [11.1]
  • Ghidra Origin: [Github]

Additional context Full error log:

Sleigh userop 'LOCK' is not in the library ghidra.pcode.exec.ComposedPcodeUseropLibrary@21f3ab2b
ghidra.pcode.exec.PcodeExecutionException: Sleigh userop 'LOCK' is not in the library ghidra.pcode.exec.ComposedPcodeUseropLibrary@21f3ab2b
	at ghidra.pcode.exec.PcodeExecutor.step(PcodeExecutor.java:275)
	at ghidra.pcode.exec.PcodeExecutor.finish(PcodeExecutor.java:178)
	at ghidra.pcode.exec.PcodeExecutor.execute(PcodeExecutor.java:160)
	at ghidra.pcode.exec.PcodeExecutor.execute(PcodeExecutor.java:135)
	at ghidra.pcode.emu.DefaultPcodeThread.executeInstruction(DefaultPcodeThread.java:584)
	at ghidra.pcode.emu.DefaultPcodeThread.stepInstruction(DefaultPcodeThread.java:415)
	at ghidra.trace.model.time.schedule.Stepper$Enum$1.tick(Stepper.java:25)
	at ghidra.trace.model.time.schedule.TickStep.execute(TickStep.java:74)
	at ghidra.trace.model.time.schedule.Step.execute(Step.java:182)
	at ghidra.trace.model.time.schedule.Sequence.execute(Sequence.java:392)
	at ghidra.trace.model.time.schedule.TraceSchedule.finish(TraceSchedule.java:400)
	at ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin.doEmulateFromCached(DebuggerEmulationServicePlugin.java:723)
	at ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin.doEmulate(DebuggerEmulationServicePlugin.java:771)
	at ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin$EmulateTask.compute(DebuggerEmulationServicePlugin.java:262)
	at ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin$EmulateTask.compute(DebuggerEmulationServicePlugin.java:252)
	at ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin$AbstractEmulateTask.run(DebuggerEmulationServicePlugin.java:239)
	at ghidra.util.task.Task.monitoredRun(Task.java:134)
	at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: ghidra.pcode.exec.SleighLinkException: Sleigh userop 'LOCK' is not in the library ghidra.pcode.exec.ComposedPcodeUseropLibrary@21f3ab2b
	at ghidra.pcode.exec.PcodeExecutor.onMissingUseropDef(PcodeExecutor.java:578)
	at ghidra.pcode.emu.DefaultPcodeThread$PcodeThreadExecutor.onMissingUseropDef(DefaultPcodeThread.java:203)
	at ghidra.pcode.exec.PcodeExecutor.executeCallother(PcodeExecutor.java:562)
	at ghidra.pcode.exec.PcodeExecutor.stepOp(PcodeExecutor.java:249)
	at ghidra.pcode.emu.DefaultPcodeThread$PcodeThreadExecutor.stepOp(DefaultPcodeThread.java:180)
	at ghidra.pcode.exec.PcodeExecutor.step(PcodeExecutor.java:268)
	... 20 more

nogitsune-youkai avatar Jun 11 '24 15:06 nogitsune-youkai

You'll need to define for the emulator what the LOCK pcode userop means. See https://github.com/NationalSecurityAgency/ghidra/blob/master/GhidraDocs/GhidraClass/Debugger/B4-Modeling.md. That tutorial goes into quite a bit more than you need, but essentialy, create a custom userop library that defines LOCK, then use a script to install an emulator with that library into the UI.

nsadeveloper789 avatar Jun 13 '24 15:06 nsadeveloper789

Essentially, the same solution as found here, but for a different processor: https://github.com/NationalSecurityAgency/ghidra/issues/6089. It's very possible your definition is effectively a NOP.

nsadeveloper789 avatar Jun 13 '24 15:06 nsadeveloper789

Ok. Thank you, i'll look into it

nogitsune-youkai avatar Jun 13 '24 17:06 nogitsune-youkai

Essentially, the same solution as found here, but for a different processor: #6089. It's very possible your definition is effectively a NOP.

It's all great, but it will be really easy if it's just open "jython" window of active emulation tool and do something like:

def useropNOP():
  pass

and then do something like: getCurrentEmulator().registerSimpleUserOp("LOCK", useropNOP)

and continue emulation process instead of diving into java and Ghidra developing for hours, because simple LOCK/UNLOCK has no simple "nop" implementation and implementing it is really hard way, especially you do not have much time for it.

Maybe if it's not really possible to make easy way, then just bundle example script which will add nopped LOCK/UNLCOK with graphical launch(or how to do this?) of emulator? Or script which will implement NOP for LOCK/UNLOCK on the fly in active graphical emulation?

Or may be just add "SKIP unknown" option for emulator?

P.s. after of 5 hours of trying to implement this things such stupid way I give up and go will look for just patch emulator to skip it.

Marisa-Chan avatar Oct 10 '24 05:10 Marisa-Chan