mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
458 lines
25 KiB
HTML
458 lines
25 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="generator" content="pandoc" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||
<title>Ghidra Debugger</title>
|
||
<style>
|
||
code{white-space: pre-wrap;}
|
||
span.smallcaps{font-variant: small-caps;}
|
||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||
div.column{flex: auto; overflow-x: auto;}
|
||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||
ul.task-list{list-style: none;}
|
||
ul.task-list li input[type="checkbox"] {
|
||
width: 0.8em;
|
||
margin: 0 0.8em 0.2em -1.6em;
|
||
vertical-align: middle;
|
||
}
|
||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||
/* CSS for syntax highlighting */
|
||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||
.sourceCode { overflow: visible; }
|
||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||
div.sourceCode { margin: 1em 0; }
|
||
pre.sourceCode { margin: 0; }
|
||
@media screen {
|
||
div.sourceCode { overflow: auto; }
|
||
}
|
||
@media print {
|
||
pre > code.sourceCode { white-space: pre-wrap; }
|
||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||
}
|
||
pre.numberSource code
|
||
{ counter-reset: source-line 0; }
|
||
pre.numberSource code > span
|
||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||
pre.numberSource code > span > a:first-child::before
|
||
{ content: counter(source-line);
|
||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||
border: none; display: inline-block;
|
||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||
-khtml-user-select: none; -moz-user-select: none;
|
||
-ms-user-select: none; user-select: none;
|
||
padding: 0 4px; width: 4em;
|
||
color: #aaaaaa;
|
||
}
|
||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||
div.sourceCode
|
||
{ }
|
||
@media screen {
|
||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||
}
|
||
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||
code span.at { color: #7d9029; } /* Attribute */
|
||
code span.bn { color: #40a070; } /* BaseN */
|
||
code span.bu { color: #008000; } /* BuiltIn */
|
||
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||
code span.ch { color: #4070a0; } /* Char */
|
||
code span.cn { color: #880000; } /* Constant */
|
||
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||
code span.dt { color: #902000; } /* DataType */
|
||
code span.dv { color: #40a070; } /* DecVal */
|
||
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||
code span.ex { } /* Extension */
|
||
code span.fl { color: #40a070; } /* Float */
|
||
code span.fu { color: #06287e; } /* Function */
|
||
code span.im { color: #008000; font-weight: bold; } /* Import */
|
||
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||
code span.op { color: #666666; } /* Operator */
|
||
code span.ot { color: #007020; } /* Other */
|
||
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||
code span.sc { color: #4070a0; } /* SpecialChar */
|
||
code span.ss { color: #bb6688; } /* SpecialString */
|
||
code span.st { color: #4070a0; } /* String */
|
||
code span.va { color: #19177c; } /* Variable */
|
||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||
</style>
|
||
<link rel="stylesheet" href="style.css" />
|
||
<!--[if lt IE 9]>
|
||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||
<![endif]-->
|
||
</head>
|
||
<body>
|
||
<header id="nav"><a
|
||
class="beginner" href="A1-GettingStarted.html">Getting Started</a><a
|
||
class="beginner" href="A2-UITour.html">UI Tour</a><a
|
||
class="beginner" href="A3-Breakpoints.html">Breakpoints</a><a
|
||
class="beginner" href="A4-MachineState.html">Machine State</a><a
|
||
class="beginner" href="A5-Navigation.html">Navigation</a><a
|
||
class="beginner" href="A6-MemoryMap.html">Memory Map</a><a
|
||
class="advanced" href="B1-RemoteTargets.html">Remote Targets</a><a
|
||
class="advanced" href="B2-Emulation.html">Emulation</a><a
|
||
class="advanced" href="B3-Scripting.html">Scripting</a><a
|
||
class="advanced" href="B4-Modeling.html">Modeling</a>
|
||
</header>
|
||
<header id="title-block-header">
|
||
<h1 class="title">Ghidra Debugger</h1>
|
||
</header>
|
||
<nav id="TOC" role="doc-toc">
|
||
<ul>
|
||
<li><a href="#using-breakpoints" id="toc-using-breakpoints">Using
|
||
Breakpoints</a>
|
||
<ul>
|
||
<li><a href="#breakpoints" id="toc-breakpoints">Breakpoints</a></li>
|
||
<li><a href="#examining-minesweeper-board-setup"
|
||
id="toc-examining-minesweeper-board-setup">Examining Minesweeper Board
|
||
Setup</a>
|
||
<ul>
|
||
<li><a href="#set-the-breakpoints" id="toc-set-the-breakpoints">Set the
|
||
Breakpoints</a></li>
|
||
<li><a href="#toggling-the-breakpoints"
|
||
id="toc-toggling-the-breakpoints">Toggling the Breakpoints</a></li>
|
||
<li><a href="#importing-libc" id="toc-importing-libc">Importing
|
||
<code>libc</code></a></li>
|
||
<li><a href="#capturing-the-random-seed"
|
||
id="toc-capturing-the-random-seed">Capturing the Random Seed</a></li>
|
||
<li><a href="#locating-the-mine-placement-algorithm"
|
||
id="toc-locating-the-mine-placement-algorithm">Locating the Mine
|
||
Placement Algorithm</a></li>
|
||
<li><a href="#exercise-diagram-the-mines"
|
||
id="toc-exercise-diagram-the-mines">Exercise: Diagram the Mines</a></li>
|
||
<li><a
|
||
href="#optional-exercise-replicate-the-boards-forward-engineering"
|
||
id="toc-optional-exercise-replicate-the-boards-forward-engineering">Optional
|
||
Exercise: Replicate the Boards (Forward Engineering)</a></li>
|
||
</ul></li>
|
||
</ul></li>
|
||
</ul>
|
||
</nav>
|
||
<section id="using-breakpoints" class="level1">
|
||
<h1>Using Breakpoints</h1>
|
||
<p>This module assumes you know how to launch <code>termmines</code> in
|
||
Ghidra using GDB and know where to find the basic Debugger GUI
|
||
components. If not, please refer to the previous modules.</p>
|
||
<p>This module will address the Breakpoints window in more depth. While
|
||
the breakpoint manager is able to deal with a system of targets, we will
|
||
only deal with a single target at a time.</p>
|
||
<section id="breakpoints" class="level2">
|
||
<h2>Breakpoints</h2>
|
||
<p>Most likely, this window is empty if you have been following the
|
||
lesson.</p>
|
||
<figure>
|
||
<img src="images/Breakpoints_EmptyAfterLaunch.png"
|
||
alt="The breakpoints window" />
|
||
<figcaption aria-hidden="true">The breakpoints window</figcaption>
|
||
</figure>
|
||
<p>From here, you can toggle and delete existing breakpoints. There are
|
||
several ways to set a new breakpoint:</p>
|
||
<ol type="1">
|
||
<li>From any static or dynamic listing window, including Disassembly,
|
||
Memory/Hex, and the Decompiler, right-click and select <img
|
||
src="images/breakpoint-enable.png" alt="set breakpoint" /> Set
|
||
Breakpoint, press <strong><code>K</code></strong> on the keyboard, or
|
||
double-click the margin.</li>
|
||
<li>From the Terminal window, use the GDB command, e.g.,
|
||
<code>break main</code>.</li>
|
||
</ol>
|
||
<p>The advantage of using the listings is that you can quickly set a
|
||
breakpoint at any address. The advantage of using the Terminal window is
|
||
that you can specify something other than an address. Often, those
|
||
specifications still resolve to addresses, and Ghidra will display them.
|
||
Ghidra will memorize breakpoints by recording them as special bookmarks
|
||
in the program database. There is some iconography to communicate the
|
||
various states of a breakpoint. When all is well and normal, you should
|
||
only see enabled <img src="images/breakpoint-enable.png"
|
||
alt="enabled breakpoint" /> and disabled <img
|
||
src="images/breakpoint-disable.png" alt="disabled breakpoint" />
|
||
breakpoints. If the target is terminated (or not launched yet), you may
|
||
also see ineffective <img src="images/breakpoint-enable-ineff.png"
|
||
alt="ineffective breakpoint" /> breakpoints.</p>
|
||
</section>
|
||
<section id="examining-minesweeper-board-setup" class="level2">
|
||
<h2>Examining Minesweeper Board Setup</h2>
|
||
<p>Suppose we want to cheat at <code>termmines</code>. We might like to
|
||
understand how the mines are placed. Knowing that the mines are placed
|
||
randomly, we might hypothesize that it is using the <code>srand</code>
|
||
and <code>rand</code> functions from the C standard library. While we
|
||
can test that hypothesis by examining the imports statically, we might
|
||
also like to record some actual values, so we will approach this
|
||
dynamically. (This is the Debugger course, after all.) The breakpoint on
|
||
<code>srand</code> will allow us to capture the random seed. The
|
||
breakpoint on <code>rand</code> will help us find the algorithm that
|
||
places the mines.</p>
|
||
<section id="set-the-breakpoints" class="level3">
|
||
<h3>Set the Breakpoints</h3>
|
||
<p>In the Terminal, type the GDB commands to set breakpoints on
|
||
<code>srand</code> and <code>rand</code>:</p>
|
||
<div class="sourceCode" id="cb1"><pre
|
||
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">break</span> srand</span>
|
||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">break</span> rand</span></code></pre></div>
|
||
<p>The breakpoint window should now be updated:</p>
|
||
<figure>
|
||
<img src="images/Breakpoints_PopAfterSRandRand.png"
|
||
alt="Populated breakpoints window" />
|
||
<figcaption aria-hidden="true">Populated breakpoints window</figcaption>
|
||
</figure>
|
||
<p>For a single target, the lower panel of the Breakpoints window does
|
||
not add much information, but it does have some. We will start with the
|
||
top panel. This lists the <em>logical</em> breakpoints, preferring
|
||
static addresses.</p>
|
||
<ul>
|
||
<li>The left-most column <strong>State</strong> indicates the
|
||
breakpoint’s state. Here, we see the inconsistent <img
|
||
src="images/breakpoint-overlay-inconsistent.png" alt="inconsistent" />
|
||
overlay, because Ghidra cannot save the breakpoint without a program
|
||
database. That is because <code>srand</code> and <code>rand</code> are
|
||
in a different module, and we have not yet imported it into Ghidra.</li>
|
||
<li>The next column <strong>Name</strong> is the name of the breakpoint.
|
||
This is for informational purposes only. You can rename a breakpoint
|
||
however you like, and it will have no effect on the target nor back-end
|
||
debugger.</li>
|
||
<li>The next column <strong>Address</strong> gives the address of the
|
||
breakpoint. Notice that the addresses were resolved, even though the
|
||
breakpoints were specified by symbol. Typically, this is the
|
||
<em>static</em> address of the breakpoint; however, if the module image
|
||
is not imported, yet, this will be the <em>dynamic</em> address, subject
|
||
to relocation or ASLR.</li>
|
||
<li>The next column <strong>Image</strong> gives the name of the program
|
||
database containing the breakpoint. Again, because the module has not
|
||
been imported yet, this column is blank.</li>
|
||
<li>The next column <strong>Length</strong> gives the length of the
|
||
breakpoint. In GDB, this generally applies to watchpoints only.</li>
|
||
<li>The next column <strong>Kinds</strong> gives the kinds of
|
||
breakpoint. Most breakpoints are software execution breakpoints,
|
||
indicated by “SW_EXECUTE.” That is, they are implemented by patching the
|
||
target’s memory with a special instruction that traps execution —
|
||
<code>INT3</code> on x86. There are also hardware execution breakpoints
|
||
indicated by “HW_EXECUTE,” and access breakpoints indicated by “HW_READ”
|
||
and/or “HW_WRITE”. <strong>NOTE</strong>: GDB would call access
|
||
breakpoints <em>watchpoints</em>. An advantage to software breakpoints
|
||
is that you can have a practically unlimited number of them. Some
|
||
disadvantages are they can be detected easily, and they are limited to
|
||
execution breakpoints.</li>
|
||
<li>The next column <strong>Locations</strong> counts the number of
|
||
locations for the breakpoint. For a single-target session, this is most
|
||
likely 1.</li>
|
||
<li>The final column <strong>Sleigh</strong> is only applicable to the
|
||
emulator. It indicates that the breakpoint’s behavior has been
|
||
customized with Sleigh code. This is covered in <a
|
||
href="B2-Emulation.html">Emulation</a>.</li>
|
||
</ul>
|
||
<p>Now, we move to the bottom panel. This lists the breakpoint
|
||
locations, as reported by the back-end debugger(s). The State, Address,
|
||
and Sleigh columns are the same as the top, but for the individual
|
||
<em>dynamic</em> addresses.</p>
|
||
<ul>
|
||
<li>The <strong>Name</strong> column is the name as designated by the
|
||
back-end.</li>
|
||
<li>The <strong>Trace</strong> column indicates which target contains
|
||
the location. The text here should match one of the tabs from the
|
||
Dynamic Listing panel.</li>
|
||
<li>The <strong>Comment</strong> column is a user-defined comment. Its
|
||
default value is the specification that generated it, e.g.,
|
||
<code>srand</code>.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="toggling-the-breakpoints" class="level3">
|
||
<h3>Toggling the Breakpoints</h3>
|
||
<p>While there is no need to toggle the breakpoints right now, it is a
|
||
good time to demonstrate the feature. There are several ways to toggle a
|
||
breakpoint:</p>
|
||
<ol type="1">
|
||
<li>In any listing, as in setting a breakpoint, right-click and select a
|
||
toggle action, press <strong><code>K</code></strong> on the keyboard, or
|
||
double-click its icon in the margin.</li>
|
||
<li>From the Model window, expand the <em>Breakpoints</em> node and
|
||
double-click a breakpoint, or select one with the keyboard and press
|
||
<strong><code>ENTER</code></strong>.</li>
|
||
<li>From the Breakpoints window, single-click the breakpoint’s status
|
||
icon, right-click an entry and select a toggle action, or create a
|
||
selection and use a toggling action from the local toolbar. Either panel
|
||
works, but the top panel is preferred to keep the breakpoints
|
||
consistent. The local toolbar also has actions for toggling all
|
||
breakpoints in the session.</li>
|
||
<li>From the Terminal window, use the GDB commands, e.g.,
|
||
<code>disable 2</code>.</li>
|
||
</ol>
|
||
<p>Practice toggling them. Notice that no matter how you toggle the
|
||
breakpoints, the display updates. You might also type
|
||
<code>info break</code> into the Terminal to confirm the effect of
|
||
toggling breakpoints in the GUI. When you are finished, ensure both
|
||
breakpoints are enabled.</p>
|
||
<p><strong>NOTE</strong>: In all parts of the GUI, except the Model
|
||
window, Ghidra prefers to toggle breakpoint locations. Without getting
|
||
into details, this is the second level down of breakpoints shown in the
|
||
Model tree. If you set a breakpoint, and GDB calls this breakpoint 2,
|
||
then you toggle it in the listing, Ghidra will toggle, e.g., breakpoint
|
||
<em>location</em> 2.1, not the breakpoint <em>specification</em> 2. If
|
||
you disable breakpoint 2 using the Model or Terminal window, it may
|
||
become impossible to toggle the breakpoint in the Listing or Breakpoints
|
||
windows. If you find your session in this condition, just re-enable the
|
||
troublesome breakpoints in the Model or Terminal window.</p>
|
||
</section>
|
||
<section id="importing-libc" class="level3">
|
||
<h3>Importing <code>libc</code></h3>
|
||
<p>While the Debugger can operate without importing external modules, it
|
||
generally works better when you have. The symbols <code>srand</code> and
|
||
<code>rand</code> are in <code>libc</code>. If you would like to save
|
||
the breakpoints we placed on them, you must import the module. You could
|
||
do this in the usual manner, but the Debugger offers a convenient way to
|
||
import missing modules.</p>
|
||
<ol type="1">
|
||
<li><p>Navigate to a dynamic address that would be mapped to the missing
|
||
module. For our scenario, the easiest way to do that is to double-click
|
||
an address in the Breakpoints window. Either one points somewhere in
|
||
<code>libc</code>.</p></li>
|
||
<li><p>Check the Debug Console window for a note about the missing
|
||
module:</p>
|
||
<figure>
|
||
<img src="images/Breakpoints_MissingModuleNote.png"
|
||
alt="Missing module note in the debug console" />
|
||
<figcaption aria-hidden="true">Missing module note in the debug
|
||
console</figcaption>
|
||
</figure></li>
|
||
<li><p>Click the import button — leftmost of the remedial actions. It
|
||
will display a file browser pointed at the library file.</p></li>
|
||
<li><p>Proceed with the import and initial analysis as you would in the
|
||
CodeBrowser.</p></li>
|
||
</ol>
|
||
<p>Once imported, the Breakpoints window should update to reflect the
|
||
static addresses, the breakpoints should become consistent, and the
|
||
Static Listing should now be synchronized when navigating within
|
||
<code>libc</code>. <strong>NOTE</strong>: Ghidra has not automatically
|
||
disassembled the dynamic listing, because the program counter has not
|
||
actually landed there, yet.</p>
|
||
<figure>
|
||
<img src="images/Breakpoints_SyncedAfterImportLibC.png"
|
||
alt="The debugger tool with breakpoints synchronized after importing libc" />
|
||
<figcaption aria-hidden="true">The debugger tool with breakpoints
|
||
synchronized after importing libc</figcaption>
|
||
</figure>
|
||
<section id="troubleshooting" class="level4">
|
||
<h4>Troubleshooting</h4>
|
||
<p>If it seems nothing has changed, except now you have a second program
|
||
database open, then the new module may not be successfully mapped.</p>
|
||
<ol type="1">
|
||
<li>Re-check the Debug Console window and verify the note has been
|
||
removed.</li>
|
||
<li>If not, it might be because the module is symlinked in the file
|
||
system, so the name of the module and the name of the program database
|
||
do not match.</li>
|
||
<li>Ensure that <code>libc</code> is the current program (tab) in the
|
||
Static Listing.</li>
|
||
<li>In the Modules window, right-click on <code>libc</code>, and select
|
||
<strong>Map Module to libc</strong>. (Names and titles will likely
|
||
differ.)</li>
|
||
</ol>
|
||
</section>
|
||
</section>
|
||
<section id="capturing-the-random-seed" class="level3">
|
||
<h3>Capturing the Random Seed</h3>
|
||
<p>We can now allow <code>termmines</code> to execute, expecting it to
|
||
hit the <code>srand</code> breakpoint first. Click <img
|
||
src="images/resume.png" alt="resume" /> Resume. If all goes well, the
|
||
target should break at <code>srand</code>. If you have never written
|
||
code that uses <code>srand</code> before, you should briefly read its
|
||
manual page. It takes a single parameter, the desired seed. That
|
||
parameter contains the seed this very moment! We can then examine the
|
||
value of the seed by hovering over <code>param_1</code> in the
|
||
decompiler.</p>
|
||
<figure>
|
||
<img src="images/Breakpoints_SeedValueAfterBreakSRand.png"
|
||
alt="Seed value in decompiler hover" />
|
||
<figcaption aria-hidden="true">Seed value in decompiler
|
||
hover</figcaption>
|
||
</figure>
|
||
<p>We will cover other ways to examine memory and registers in the <a
|
||
href="A4-MachineState.html">Machine State</a> module. We have contrived
|
||
<code>termmines</code> so that its random seed will always start with
|
||
<code>0x5eed____</code>. If you see that in the value displayed, then
|
||
you have successfully recovered the seed. This seed will be used in an
|
||
optional exercise at the end of this module. You might write it down;
|
||
however, if you re-launch <code>termmines</code> between now and then,
|
||
you will have a different seed.</p>
|
||
</section>
|
||
<section id="locating-the-mine-placement-algorithm" class="level3">
|
||
<h3>Locating the Mine Placement Algorithm</h3>
|
||
<p>Press <img src="images/resume.png" alt="resume" /> Resume again. This
|
||
time, the target should break at <code>rand</code>. We are not
|
||
interested in the <code>rand</code> function itself, but rather how the
|
||
placement algorithm is using it. Press <img src="images/stepout.png"
|
||
alt="step out" /> Step Out to allow the target to return from
|
||
<code>rand</code>. If you still have the Decompiler up, you should be in
|
||
a code block resembling:</p>
|
||
<div class="sourceCode" id="cb2"><pre
|
||
class="sourceCode numberSource c numberLines"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1"></a><span class="cf">while</span> <span class="op">(</span>iVar2 <span class="op">=</span> DAT_00604164<span class="op">,</span> iVar1 <span class="op">=</span> DAT_00604160<span class="op">,</span> iVar10 <span class="op"><</span> _DAT_00604168<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb2-2"><a href="#cb2-2"></a> iVar3 <span class="op">=</span> rand<span class="op">();</span></span>
|
||
<span id="cb2-3"><a href="#cb2-3"></a> iVar2 <span class="op">=</span> DAT_00604164<span class="op">;</span></span>
|
||
<span id="cb2-4"><a href="#cb2-4"></a> iVar11 <span class="op">=</span> rand<span class="op">();</span></span>
|
||
<span id="cb2-5"><a href="#cb2-5"></a> lVar7 <span class="op">=</span> <span class="op">(</span><span class="dt">long</span><span class="op">)(</span>iVar11 <span class="op">%</span> iVar2 <span class="op">+</span> <span class="dv">1</span><span class="op">)</span> <span class="op">*</span> <span class="bn">0x20</span> <span class="op">+</span> <span class="op">(</span><span class="dt">long</span><span class="op">)(</span>iVar3 <span class="op">%</span> iVar1 <span class="op">+</span> <span class="dv">1</span><span class="op">);</span></span>
|
||
<span id="cb2-6"><a href="#cb2-6"></a> bVar14 <span class="op">=</span> <span class="op">*(</span>byte <span class="op">*)((</span><span class="dt">long</span><span class="op">)&</span>DAT_00604160 <span class="op">+</span> lVar7 <span class="op">+</span> <span class="bn">0x1c</span><span class="op">);</span></span>
|
||
<span id="cb2-7"><a href="#cb2-7"></a> <span class="cf">if</span> <span class="op">(-</span><span class="dv">1</span> <span class="op"><</span> <span class="op">(</span><span class="dt">char</span><span class="op">)</span>bVar14<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb2-8"><a href="#cb2-8"></a> iVar10 <span class="op">=</span> iVar10 <span class="op">+</span> <span class="dv">1</span><span class="op">;</span></span>
|
||
<span id="cb2-9"><a href="#cb2-9"></a> <span class="op">*(</span>byte <span class="op">*)((</span><span class="dt">long</span><span class="op">)&</span>DAT_00604160 <span class="op">+</span> lVar7 <span class="op">+</span> <span class="bn">0x1c</span><span class="op">)</span> <span class="op">=</span> bVar14 <span class="op">|</span> <span class="bn">0x80</span><span class="op">;</span></span>
|
||
<span id="cb2-10"><a href="#cb2-10"></a> <span class="op">}</span></span>
|
||
<span id="cb2-11"><a href="#cb2-11"></a><span class="op">}</span></span></code></pre></div>
|
||
<p>If you are thinking, “I could have just found <code>rand</code> in
|
||
the symbol table and followed its XRefs,” you are correct. However, it
|
||
is useful to use a dynamic debugging session to drive your analysis
|
||
chronologically through execution of the target, even if much of that
|
||
analysis is still static. The advantages of a dynamic session along side
|
||
static analysis should become more apparent as you progress through this
|
||
course.</p>
|
||
</section>
|
||
<section id="exercise-diagram-the-mines" class="level3">
|
||
<h3>Exercise: Diagram the Mines</h3>
|
||
<p>You goal is to capture the location of all the mines. You will
|
||
probably want to disable the breakpoints on <code>rand</code> and
|
||
<code>srand</code> for now. Devise a strategy using breakpoints and the
|
||
control buttons (Step, Resume, etc.) so that you can observe the
|
||
location of each mine. Use pen and paper to draw a diagram of the board,
|
||
and mark the location of each mine as you observe the algorithm placing
|
||
it. There should only be 10 mines in Beginner mode. Once the mines are
|
||
placed, press <img src="images/resume.png" alt="resume" /> Resume. Check
|
||
you work by winning the game. Alternatively, you can intentionally lose
|
||
to have the game reveal the mines.</p>
|
||
<section id="troubleshooting-1" class="level4">
|
||
<h4>Troubleshooting</h4>
|
||
<p>You may find that running both GDB and <code>termmines</code> in the
|
||
same Terminal makes viewing the game board difficult. The next time you
|
||
launch, be sure to use the <strong>Configure and Launch</strong>
|
||
sub-menu, then enable the <strong>Inferior TTY</strong> option. This
|
||
should start two Terminals, one with GDB and a second dedicated to
|
||
<code>termmines</code>. The game board will no longer be corrupted by
|
||
GDB’s prompts and diagnostics. You will probably want to undock the
|
||
<code>termmines</code> Terminal and resize it to fit the board.</p>
|
||
</section>
|
||
</section>
|
||
<section id="optional-exercise-replicate-the-boards-forward-engineering"
|
||
class="level3">
|
||
<h3>Optional Exercise: Replicate the Boards (Forward Engineering)</h3>
|
||
<p>You will need a C development environment for this exercise. Because,
|
||
as we have now confirmed, <code>termmines</code> is importing its random
|
||
number generator from the system, we can write a program that uses that
|
||
same generator. Further, because we can capture the seed, and we know
|
||
the placement algorithm, we can perfectly replicate the sequence of game
|
||
boards for any <code>termmines</code> session.</p>
|
||
<p>Write a program that takes a seed from the user and prints a diagram
|
||
of the first game board with the mines indicated. Optionally, have it
|
||
print each subsequent game board when the user presses
|
||
<strong>ENTER</strong>. Check your work by re-launching
|
||
<code>termmines</code>, capturing its seed, inputting it into your
|
||
program, and then winning the game. Optionally, win 2 more games in the
|
||
same session.</p>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
</body>
|
||
</html>
|