This module assumes you have completed the Getting Started module. If not, please go back.
This module will briefly introduce each window in the Ghidra Debugger. We assume some familiarity with trap-and-trace debugging. If you have not used GDB or a similar debugger before, you may find the Ghidra Debugger difficult to grasp.
If you would like your tool to look more or less like the one
presented in the screenshot here, launch termmines
from the
Debugger using GDB.
Like the CodeBrowser tool, the Debugger tool is a preconfigured
collection of plugins and panels that present Ghidra’s dynamic analysis
features. You may re-configure, save, export, import, etc. the tool to
fit your preferences. For reference, here is a screenshot of the default
configuration after launching termmines
:
Many of the buttons in the global toolbar are the same as in the CodeBrowser. Coincidentally, in the screenshot, the debugger-specific buttons start just above the Dynamic Listing in the global toolbar. They are:
continue
in GDB.CTRL
-C
or
interrupt
in GDB.kill
in GDB.quit
in GDB.stepi
,
nexti
, and finish
. Step [Extended] represents
additional step commands supported by the back end. GDB provides
Advance and Return.Starting at the top left and working clockwise, the windows are:
x/10i $pc
. The tabs at the top list the
active traces. Traces with a icon represent live targets. The nearest equivalent to
the tabs in GDB is info inferiors
.info break
.info registers
.maintenance info sections
. Note that this differs from the
Regions window.info threads
.backtrace
.display
.info proc mappings
.The control buttons are all located on the global toolbar. Start by pressing the Step Into button. Notice that the Dynamic Listing moves forward a single instruction each time you press it. Also notice that the Static Listing moves with the Dynamic Listing. You may navigate in either listing, and so long as there is a corresponding location in the other, the two will stay synchronized. You may also open the Decompiler just as you would in the CodeBrowser, and it will stay in sync too.
When you have clicked Step Into a sufficient number of
times, you should end up in a subroutine. You can click Step Out to
leave the subroutine. Note that the target is allowed to execute until
it returns from the subroutine; it does not skip out of it. Now, click
Step
Over until you reach another CALL
instruction.
Notice that when you click Step Over again, it will not descend
into the subroutine. Instead, the target is allowed to execute the
entire subroutine before stopping again — after the CALL
instruction.
If you prefer, you may use the GDB commands from the Terminal instead
of the buttons. Try si
and/or ni
. You can also
pass arguments which is not possible with the buttons,
e.g. si 10
to step 10 instructions in one command.
If you need to terminate the target you should use the
Disconnect button rather than the Kill
button, in general. Otherwise, each launch will create a new connection,
and you will end up with several stale connections. Additionally, if
your target exits or otherwise terminates on its own, you will get a
stale connection. Use the Connections window to clean such connections
up, or just type quit
into the session’s Terminal. The
re-use of connections and/or the use of multiple concurrent connections
is not covered in this course.
First, check that synchronization is enabled. This is the default behavior, but, still, check it first. In the top-right of the Dynamic Listing is its local drop-down menu. Click it and check that Auto-Sync Cursor with Static Listing is selected.
If that does not work, check the top-left label of the Dynamic
Listing to see what module you are in. Also check the Debug Console
window. If you are in a system library, e.g., ld-linux
,
then this is the expected behavior. You may optionally import it, as
suggested by the Debug Console, but this is covered later. You may also
try typing into the Terminal, one command at a time, checking
for errors after each:
break main
continue
That should get you from the system entry into the target’s
main
routine, assuming it has one. Next time you launch,
check the configuration and change Run Command to
“start”, not “starti”.
If you are not in a system library, then check the Modules window to
see if termmines
is listed. If so, it seems the module
mapper failed to realize that module is the current program. Right-click
the module and select Map to termmines. Confirm the
dialog. If termmines
is not listed, then your version of
GDB may not be supported. If you file a bug report, please include your
GDB version, Linux distribution, and/or other platform details.
There is probably a discrepancy between the version you imported and
the version you launched. This should not happen with
termmines
, but perhaps you re-ran make
between
importing and launching? For other system libraries, this could happen
if you or an administrator applied system updates since you imported.
You probably need to re-import the affected module image(s). If this
happens to you in practice, and you have substantial investment in the
old program database, consider using the Version Tracker to port your
knowledge to the new database.
This can happen if the Control Mode is set to Control Emulator. See the above heading about Control Mode. Change it back to Control Target.
If you were not already following along with an instructor, then try
some of the stepping buttons. One of the first subroutines called in
termmines
parses command-line arguments. Try stepping until
you have entered that subroutine. TIP: Use the
Decompiler to help you recognize when you have entered the command-line
parsing subroutine. Alternatively, use the Static Listing and Decompiler
to identify the parsing subroutine (as you would in the CodeBrowser),
and then use the Step buttons to drive the target into
it.