ghidra/GhidraDocs/GhidraClass/Debugger/A4-MachineState.html

662 lines
33 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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;}
</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="#examining-machine-state-memory-registers-and-variables"
id="toc-examining-machine-state-memory-registers-and-variables">Examining
Machine State: Memory, Registers, and Variables</a>
<ul>
<li><a href="#machine-state" id="toc-machine-state">Machine State</a>
<ul>
<li><a href="#patching" id="toc-patching">Patching</a></li>
</ul></li>
<li><a href="#the-dynamic-listing" id="toc-the-dynamic-listing">The
Dynamic Listing</a>
<ul>
<li><a href="#cache-status-indication"
id="toc-cache-status-indication">Cache Status Indication</a></li>
<li><a href="#address-tracking" id="toc-address-tracking">Address
Tracking</a></li>
<li><a href="#module-region-indicator"
id="toc-module-region-indicator">Module / Region Indicator</a></li>
<li><a href="#go-to" id="toc-go-to">Go To</a></li>
<li><a href="#compare" id="toc-compare">Compare</a></li>
<li><a href="#exercise-reverse-engineer-the-board"
id="toc-exercise-reverse-engineer-the-board">Exercise: Reverse Engineer
the Board</a></li>
</ul></li>
<li><a href="#the-memory-viewer" id="toc-the-memory-viewer">The Memory
Viewer</a>
<ul>
<li><a href="#exercise-display-the-board-in-hex"
id="toc-exercise-display-the-board-in-hex">Exercise: Display the Board
in Hex</a></li>
</ul></li>
<li><a href="#registers" id="toc-registers">Registers</a>
<ul>
<li><a href="#exercise-reduce-the-mines"
id="toc-exercise-reduce-the-mines">Exercise: Reduce the Mines</a></li>
</ul></li>
<li><a href="#watches" id="toc-watches">Watches</a></li>
<li><a href="#sleigh-expressions" id="toc-sleigh-expressions">Sleigh
Expressions</a>
<ul>
<li><a href="#variables-and-constants"
id="toc-variables-and-constants">Variables and Constants</a></li>
<li><a href="#operators" id="toc-operators">Operators</a></li>
<li><a href="#exercise-find-and-modify-the-board-dimensions"
id="toc-exercise-find-and-modify-the-board-dimensions">Exercise: Find
and Modify the Board Dimensions</a></li>
<li><a href="#exercise-watch-the-cell-to-be-mined"
id="toc-exercise-watch-the-cell-to-be-mined">Exercise: Watch the Cell to
be Mined</a></li>
</ul></li>
<li><a href="#variable-hovers" id="toc-variable-hovers">Variable
Hovers</a></li>
</ul></li>
</ul>
</nav>
<section id="examining-machine-state-memory-registers-and-variables"
class="level1">
<h1>Examining Machine State: Memory, Registers, and Variables</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. It also assumes you know the basic control commands, e.g.,
Resume, Step, and Interrupt; as well as some basics for breakpoints. If
not, please refer to the previous modules.</p>
<p>This module will address the following features in more depth:</p>
<ul>
<li>Dynamic Listing window</li>
<li>Dynamic Bytes (Memory) window</li>
<li>Registers window</li>
<li>Watches window</li>
<li>Sleigh expressions</li>
<li>Variable value hovers</li>
</ul>
<section id="machine-state" class="level2">
<h2>Machine State</h2>
<p>There are at least two ways to define machine state. One way based on
a high-level understanding of a program is the collective values of all
variables. Another based on a low-level understanding of a program is
the collective values of all memory and all registers of all threads.
Because Ghidra is primarily concerned with examining software at the low
level, albeit to obtain a high-level understanding, we will generally
stick with the low-level definition. One could argue that machine state
also includes the underlying system and hardware, including peripherals.
When debugging user-space applications, Ghidra cannot generally inspect
the underlying system, except for a few things granted by the back-end
debugger, e.g., the virtual memory map. Thus, as far as we are
concerned, the machine state does not include the underlying system, but
it is still something you must be aware of while debugging.</p>
<p>Note that we also treat <em>registers</em> as something separate from
<em>memory</em>. While technically, one could argue registers are the
closest and smallest memory to the CPU, we think of memory as an
addressable array, e.g., DIMMs and flash ROMs. If applicable,
<em>memory-mapped</em> registers are considered part of memory by
Ghidra.</p>
<p>The Ghidra Debugger provides mechanisms for viewing and modifying
machine state at both the low and high levels. The Dynamic Listing and
Memory viewer provide access to memory, the Registers window provides
access to registers, and the Watches window provides access to memory
and registers via expressions. The only means of accessing high-level
variables is through value hovers, which are available in all listings
and the Decompiler.</p>
<section id="patching" class="level3">
<h3>Patching</h3>
<p>Many of the features allow you to edit the values, i.e.,
<em>patch</em> the live target. The windows that are adaptations of
their static counterparts work more or less as expected. Edits in any
<em>dynamic</em> window will attempt to patch the live target. Edits in
any <em>static</em> window will <strong>not</strong> patch the live
target; they modify the program database as usual. Some dynamic windows
may present tables with editable cells. These will often include a
<em>write-lock</em> toggle, like the static Byte viewer, to avoid
accidental patching. Furthermore, you must use the <img
src="images/record.png" alt="control mode" /> Control Mode toggle in the
global toolbar (next to the control actions) to enable patching
throughout the Debugger tool. For now, please only use the
<strong>Control Target</strong> and <strong>Control Target w/ Edits
Disabled</strong> options. The write toggle is included here so that
actions like copy-paste do not lead to accidental patching.</p>
</section>
</section>
<section id="the-dynamic-listing" class="level2">
<h2>The Dynamic Listing</h2>
<p>Up to this point, we have only used the Dynamic Listing to display
the instructions at the program counter. It can actually view and mark
up any part of the machine state in memory, e.g., mapped images, heap
pages, stack pages. Where the memory is mapped to images, Ghidra
attempts to synchronize the Static Listing and, by extension, the other
static analysis windows. The Dynamic Listing has most of the same
features as the Static Listing.</p>
<p>Re-launch <code>termmines</code> and then navigate to
<code>rand</code>. You may notice that the Static Listing has
disassembly, but the Dynamic Listing does not. This is because Ghidra
has not observed the program counter at <code>rand</code> yet, so it has
not automatically disassembled it. To manually disassemble in the
Dynamic Listing, place your cursor where you expect an instruction and
press <strong>D</strong>, just like you would in the Static Listing.</p>
<figure>
<img src="images/State_ListingAfterCallRand.png"
alt="The dynamic listing after a call to rand" />
<figcaption aria-hidden="true">The dynamic listing after a call to
rand</figcaption>
</figure>
<p>This action differs in that it does not follow flow. It proceeds
linearly, stopping at any control transfer instruction.</p>
<p>Now, we will examine the stack segment. Click the <img
src="images/register-marker.png" alt="location tracking" /> Track
Location drop-down and select <strong>Track Stack Pointer</strong>. The
window should seek to (and highlight in pale green) the address in the
stack pointer. Since the target has just entered <code>main</code>, we
should expect a return address at the top of the stack. With your cursor
at the stack pointer, press <strong><code>P</code></strong> to place a
pointer there, just like you would in the Static Listing. You can now
navigate to that address by double-clicking it. To return to the stack
pointer, you can use the back arrow in the global toolbar, you can click
the <img src="images/register-marker.png" alt="track location" /> Track
Location button, or you can double-click the <code>sp = [Address]</code>
label in the top right of the Dynamic Listing.</p>
<p>To examine a more complicated stack segment, we will break at
<code>rand</code>. Ensure your breakpoint at <code>rand</code> is
enabled and press <img src="images/resume.png" alt="resume" /> Resume.
Your Dynamic Listing should follow the stack pointer. In the menus,
select <strong>Debugger → Analysis → Unwind from frame 0</strong> or
press <strong><code>U</code></strong>.</p>
<figure>
<img src="images/State_ListingStackAfterCallRand.png"
alt="The dynamic listing of the stack after a call to rand" />
<figcaption aria-hidden="true">The dynamic listing of the stack after a
call to rand</figcaption>
</figure>
<p><strong>NOTE</strong>: We will cover the Stack window later in the
course, which is probably a more suitable way to navigate stack frames.
It is populated by the back-end debugger, which can usually unwind the
stack more reliably than Ghidra. The Unwind Stack action is useful when
you want an in-depth understanding of the actual contents of the stack,
or when you are emulating.</p>
<p>Now, switch back to <strong>Track Program Counter</strong>. If you
would like to track both the Program Counter and the Stack Pointer,
click the <img src="images/camera-photo.png" alt="clone" /> Clone button
in the local toolbar. Like the Static Listing, this clones an instance
of the Dynamic Listing, which you can configure differently than the
primary Dynamic Listing. Only the primary Dynamic Listing will
synchronize, and it does so only with the primary Static Listing.
<strong>NOTE</strong>: For the sake of disambiguation, we will use the
term <em>clone</em>, not <em>snapshot</em> when referring to multiple
instances of a Ghidra window. While this is inconsistent with the Ghidra
Beginner course materials, it is necessary to avoid confusion with
snapshots of the machine state, discussed later in this module.</p>
<p>The dynamic listing offers several additional features:</p>
<section id="cache-status-indication" class="level3">
<h3>Cache Status Indication</h3>
<p>The listings contents are read from a live target, which may become
unresponsive or otherwise temperamental. The Debugger uses a trace
database, which acts as a cache separating the GUI from the live target.
The UI requests memory pages from the target, the target asynchronously
retrieves those pages and stores them into the database, then the
database updates the UI. This sequence does not always go as expected;
thus, pages with stale data are displayed with a grey background. This
may also happen if auto-read is disabled. Typically, user-space targets
are not so temperamental, but others may be, or memory reads could be
expensive, in which case disabling automatic memory reads may be
advantageous. If the back-end debugger reports an error while reading
memory, the page will have a red background. To refresh the visible or
selected page(s), click the
<img alt="refresh" src="images/view-refresh.png" width="16px"/> Refresh
button. Examine the Debug Console window for errors / warnings before
spamming this button. To toggle auto read, use the
<img src="images/autoread.png" alt="auto-read" width="16px"/> Auto-Read
drop-down button from the local toolbar.</p>
</section>
<section id="address-tracking" class="level3">
<h3>Address Tracking</h3>
<p>We have already demonstrated this, but there are some finer details.
Some of the tracking options depend on the Watches window, discussed
later in this module. On occasion, the location cannot be displayed in
the listing, typically because it falls outside of the memory map. If
this happens, the address label at the top right of the listing will
have red text.</p>
</section>
<section id="module-region-indicator" class="level3">
<h3>Module / Region Indicator</h3>
<p>In the top left a label will display the name of the section
containing the cursor. If there is no containing section, it will fall
back to the containing module and then to the containing region. Rarely,
this label will be empty. This can happen when the cursor is outside any
known region, which only happens if you configure Ghidra to ignore the
memory map.</p>
</section>
<section id="go-to" class="level3">
<h3>Go To</h3>
<p>The <strong>Go To</strong> action in the Dynamic Listing differs from
the one in the Static Listing. Like the static one, it accepts an
address in hexadecimal, possibly prefixed with the address space and a
colon. However, it also accepts Sleigh expressions, allowing you to
treat <code>RAX</code> as a pointer and go to that address, for example.
We cover Sleigh expressions later in this module.</p>
</section>
<section id="compare" class="level3">
<h3>Compare</h3>
<p>The Compare action in the Dynamic Listing also differs from the one
in the Static Listing. It allows the comparison of two machine state
snapshots, covered in the <a href="A5-Navigation.html">Navigation</a>
module.</p>
</section>
<section id="exercise-reverse-engineer-the-board" class="level3">
<h3>Exercise: Reverse Engineer the Board</h3>
<p>All of the features in the default CodeBrowser tool are also in the
default Debugger tool, providing you Ghidras full suite of static
analysis tools during your dynamic sessions, albeit they are not as
immediately accessible. Your task is to reverse engineer the game
boards layout in memory. Because you are in a dynamic session, you have
an example board to work with. As you navigate the <code>.data</code>
section of <code>termmines</code> in the Static Listing, the Dynamic
Listing will follow along showing you the live values in memory. You can
also experiment by placing code units in the Dynamic Listing before
committing to them in the Static Listing.</p>
<section id="questions" class="level4">
<h4>Questions:</h4>
<ol type="1">
<li>How are the cells allocated?</li>
<li>How are the cells indexed? Row major, color major? 0-up, 1-up?</li>
<li>What is happening around the “border” of the board? Why might the
programmer have chosen this design?</li>
</ol>
</section>
</section>
</section>
<section id="the-memory-viewer" class="level2">
<h2>The Memory Viewer</h2>
<figure>
<img src="images/State_BytesStackAfterCallRand.png"
alt="The dynamic memory view of the stack after a call to rand" />
<figcaption aria-hidden="true">The dynamic memory view of the stack
after a call to rand</figcaption>
</figure>
<p>Just as the Dynamic Listing is the analog of the Static Listing, the
Memory viewer is the analog of the Bytes viewer. To open it, use
<strong>Windows → Byte Viewer → Memory …</strong> in the menus. Its
default configuration should be Auto PC, the same as the Dynamic
Listings default. It has all the same additional Debugger features as
the Dynamic Listing. Furthermore, bytes that have changed are displayed
in red text.</p>
<section id="exercise-display-the-board-in-hex" class="level3">
<h3>Exercise: Display the Board in Hex</h3>
<p>This is a bit quick and dirty, but it works and can be useful. Your
task is to configure the Memory viewer so that (within the memory
allocated to the board) the rows and columns of the Memory viewer
correspond to the rows and columns of the game board.
<strong>TIP</strong>: Use the <em>Alignment Address</em> and <em>Bytes
Per Line</em> settings.</p>
</section>
</section>
<section id="registers" class="level2">
<h2>Registers</h2>
<figure>
<img src="images/State_RegistersAfterCallRand.png"
alt="The registers after a call to rand" />
<figcaption aria-hidden="true">The registers after a call to
rand</figcaption>
</figure>
<p>The Registers window gives a view of all the registers on the target
and their current values. The register set can be very large, so there
are a few ways to sift and sort. As in most Ghidra tables, you can
filter using the box below the registers table. Additionally, you can
use the column headers to sort. The columns are:</p>
<ul>
<li>The <strong>Favorite</strong> column indicates which registers are
your favorite. By default, this includes the instruction pointer and the
stack pointer. You can quickly choose your favorite(s) by toggling the
check boxes in this column. Because this column is sorted by default,
your favorites are positioned at the top.</li>
<li>The <strong>Number</strong> column gives the number assigned to the
register by Ghidras processor specification. This is mostly just to
make the default sorting deterministic.</li>
<li>The <strong>Name</strong> column gives Ghidras name for the
register. This usually matches the name given by the back-end debugger,
but may not. For example, on x86-64, what Ghidra calls
<code>rflags</code> GDB calls <code>eflags</code>.</li>
<li>The <strong>Value</strong> column gives the registers current value
in hexadecimal. Values in gray are stale. Values in red have changed.
Right-clicking this column will present options to Go To the address, as
if the register were a pointer.</li>
<li>The <strong>Type</strong> column allows you to assign a type to,
i.e., create a data unit on, the register. This has more utility for
float types than integers, but it may still help you record what you
know about how a register is being used.</li>
<li>The <strong>Representation</strong> column displays the registers
value according to its assigned type, if applicable. If the type is a
pointer, then double-clicking this value will go to the address in the
Dynamic Listing.</li>
</ul>
<p>If you would like to adjust the list of registers in the table, use
the <img src="images/select-registers.png" alt="select registers" />
Select Registers button in the local toolbar. This will present all the
registers in Ghidras processor specification, including those which are
just artifacts of Sleigh. Typically, this is not necessary, since the
table will include all registers recognized by both Ghidra and the
back-end debugger. Nevertheless, if you believe a register is missing,
it is wise to check this selection.</p>
<section id="exercise-reduce-the-mines" class="level3">
<h3>Exercise: Reduce the Mines</h3>
<p>If you have not already reverse engineered the mine placement
algorithm, do that now. Think up a strategy you might employ, by
patching a register, to reduce the number of mines placed on the board.
The strategy need not result in a permanent change. It should only
affect the round being set up. For this exercise, you cannot patch
memory, but you may place a breakpoint. Verify your work by playing the
round.</p>
</section>
</section>
<section id="watches" class="level2">
<h2>Watches</h2>
<figure>
<img src="images/State_WatchesInCallSRand.png"
alt="The watches window in a call to srand" />
<figcaption aria-hidden="true">The watches window in a call to
srand</figcaption>
</figure>
<p>The Watches window gives the values of several user-specified Sleigh
expressions. This can provide an alternative to the Registers window
when you are really only interested in a couple of registers. It can
also watch values in memory. Furthermore, when a watch has a memory
address, the expression will appear as an option in the <strong>Location
Tracking</strong> menus of the Listing and Memory viewers. Selecting
that option will cause the window to follow that watch as its address
changes.</p>
<p>To add a watch, click the <img src="images/add.png" alt="add" /> Add
button. A new entry will appear. Double-click the left-most cell of the
row to set or edit the Sleigh expression. For starters, try something
like <code>RDI</code>. (Conventionally, this is the location for the
first parameter on Linux x86-64 systems.) The context menus for the
Listing and Registers windows include a <strong>Watch</strong> action,
which adds the current selection to the Watches window.</p>
<p>The columns are:</p>
<ul>
<li>The <strong>Expression</strong> column is the user-defined Sleigh
expression.</li>
<li>The <strong>Address</strong> column is the address of the resulting
value, if applicable. This may be in <code>register</code> space.
Double-clicking this cell will go to the address in the Dynamic
Listing.</li>
<li>The <strong>Symbol</strong> column gives the symbol in a mapped
program database closest to or containing the address, if
applicable.</li>
<li>The <strong>Value</strong> column gives the “raw” value of the
expression. If the result is in memory, it displays a byte array;
otherwise, it displays an integer.</li>
<li>The <strong>Type</strong> and <strong>Representation</strong>
columns work the same as in the Registers window, except they do
<em>not</em> save the data unit to the database. This has more uses than
the Registers window. For example, try <code>*:30 RDI</code> and set
this to <code>TerminatedCString</code>. Whenever <code>RDI</code> is a
string pointer, this will display the string up to 30 characters.</li>
<li>The <strong>Error</strong> column reports any errors in compiling or
evaluating the expression.</li>
</ul>
</section>
<section id="sleigh-expressions" class="level2">
<h2>Sleigh Expressions</h2>
<p>Watches and Go-To commands are expressed using Ghidras
<em>Sleigh</em> language. More precisely, expressions are the
sub-language of Sleigh for the right-hand side of assignment statements
in semantic sections. If you already know this language, then there is
little more to learn. Of note, you may use labels from mapped program
databases in your expression. For example, to see how far a return
address is into <code>main</code>, you could use
<code>*:8 RSP - main</code>.</p>
<p>For the complete specification, see the Semantic Section in the <a
href="../../../Ghidra/Features/Decompiler/src/main/doc/sleigh.xml">Sleigh
documentation</a>.</p>
<p>Sleigh is a bit unconventional in that its operators are typed rather
than its variables. All variables are fix-length bit vectors. Their
sizes are specified in bytes, but they have no other type
information.</p>
<section id="variables-and-constants" class="level3">
<h3>Variables and Constants</h3>
<p>Here are some examples of things you can reference by name:</p>
<ul>
<li><strong>Register</strong>: <code>RAX</code></li>
<li><strong>Label</strong>: <code>main</code></li>
<li><strong>Constant</strong>: <code>1234:8</code> or
<code>0x42d:8</code> — the value 1234 encoded as an 8-byte integer</li>
</ul>
<p>Registers vary by processor, but any register known to Ghidras
specification is allowed. (Due to limitations in Sleigh, you cannot
refer to the <code>contextreg</code> or any of its sub-registers.) A
label may come from any Ghidra program database that is mapped to the
current target. Due to limitations in Sleigh, you cannot specify a
labels namespace. The compiler will search only by name and select
arbitrarily from multiple matches.</p>
</section>
<section id="operators" class="level3">
<h3>Operators</h3>
<p>Here we will demonstrate each operator by example:</p>
<ul>
<li><strong>Integer Addition</strong>: <code>RAX + RCX</code></li>
<li><strong>Integer Subtraction</strong>: <code>RAX - RCX</code></li>
<li><strong>Integer Negation</strong>: <code>-RAX</code></li>
<li><strong>Integer Multiplication</strong>: <code>RAX * RCX</code></li>
<li><strong>Unsigned Integer Division</strong>:
<code>RAX / RCX</code></li>
<li><strong>Unsigned Integer Remainder</strong>:
<code>RAX % RCX</code></li>
<li><strong>Signed Integer Division</strong>:
<code>RAX s/ RCX</code></li>
<li><strong>Signed Integer Remainder</strong>:
<code>RAX s% RCX</code></li>
<li><strong>Left Shift</strong>: <code>RAX &lt;&lt; RCX</code></li>
<li><strong>Unsigned Right Shift</strong>:
<code>RAX &gt;&gt; RCX</code></li>
<li><strong>Signed Right Shift</strong>
<code>RAX s&gt;&gt; RCX</code></li>
<li><strong>Integer Comparison</strong>: <code>RAX == RCX</code> or
<code>RAX != RCX</code></li>
<li><strong>Unsigned Integer Comparison</strong>:
<code>RAX &lt; RCX</code> or <code>RAX &gt; RCX</code> or
<code>RAX &lt;= RCX</code> or <code>RAX &gt;= RCX</code></li>
<li><strong>Signed Integer Comparison</strong>:
<code>RAX s&lt; RCX</code> etc.</li>
<li><strong>Float Addition</strong>: <code>MM0 f+ MM1</code></li>
<li><strong>Float Subtraction</strong>: <code>MM0 f- MM1</code></li>
<li><strong>Float Negation</strong>: <code>f-MM0</code></li>
<li><strong>Float Multiplication</strong>: <code>MM0 f* MM1</code></li>
<li><strong>Float Division</strong>: <code>MM0 f/ MM1</code></li>
<li><strong>Float Absolute Value</strong>: <code>abs(MM0)</code></li>
<li><strong>Float Square Root</strong>: <code>sqrt(MM0)</code></li>
<li><strong>Float Comparison</strong>: <code>RAX f== RCX</code> or
<code>RAX f&lt; RCX</code> etc.</li>
<li><strong>Bitwise And</strong>: <code>RAX &amp; RCX</code></li>
<li><strong>Bitwise Or</strong>: <code>RAX | RCX</code></li>
<li><strong>Bitwise Xor</strong>: <code>RAX ^ RCX</code></li>
<li><strong>Bitwise Not</strong>: <code>~RAX</code></li>
<li><strong>Boolean And</strong>: <code>RAX &amp;&amp; RCX</code></li>
<li><strong>Boolean Or</strong>: <code>RAX || RCX</code></li>
<li><strong>Boolean Xor</strong>: <code>RAX ^^ RCX</code></li>
<li><strong>Boolean Not</strong>: <code>!RAX</code></li>
</ul>
<p><strong>NOTE</strong>: If the result of your expression is in
floating point, you will need to set the type of the watch accordingly.
The “raw” display will render the bit vector as an integer or byte
array. To read memory:</p>
<ul>
<li><strong>Dereference</strong>: <code>*:8 RSP</code> or
<code>*[ram]:8 RSP</code></li>
</ul>
<p><strong>NOTE</strong>: The <code>[ram]</code> part is optional. On
x86, you will rarely if ever specify the space, since there is only one
physical RAM space. The <code>:8</code> part specifies the number of
bytes to read from memory. It is also optional, but only if the size can
be inferred from the rest of the expression. To manipulate variable
size:</p>
<ul>
<li><strong>Zero Extension</strong>: <code>RAX + zext(EBX)</code></li>
<li><strong>Sign Extension</strong>: <code>RAX + sext(EBX)</code></li>
<li><strong>Truncation</strong>: <code>RAX:4</code> — Equivalent to
<code>EAX</code></li>
<li><strong>Truncation</strong>: <code>AL + RBX(4)</code> — AL added to
the the 5th byte of RBX</li>
<li><strong>Bit Extraction</strong>: <code>RAX[7,8]</code> — Equivalent
to <code>AL</code></li>
</ul>
<p><strong>NOTE</strong>: The second form of truncation drops the
least-significant 4 bytes of RBX and takes as many of the remaining
bytes (1 in this case) as necessary to match size with AL.</p>
<p><strong>NOTE</strong>: Need for these next miscellaneous operators in
Watch expressions is rare:</p>
<ul>
<li><strong>Unsigned Carry</strong>: <code>carry(RAX,RBX)</code></li>
<li><strong>Signed Carry</strong>: <code>scarry(RAX,RBX)</code></li>
<li><strong>Signed Borrow</strong>: <code>sborrow(RAX,RBX)</code></li>
<li><strong>Float NaN</strong>: <code>nan(MM0)</code></li>
<li><strong>Convert Integer to Float</strong>:
<code>MM0 + int2float(RAX)</code> — Context required to infer the float
size</li>
<li><strong>Convert Float to Integer</strong>:
<code>RAX + trunc(MM0)</code> — Context required to infer the integer
size</li>
<li><strong>Convert Float Size</strong>:
<code>MM0 + float2float(MM0_Da)</code> — Context required to infer the
new float size</li>
<li><strong>Float Round Ceiling</strong>: <code>ceil(MM0)</code></li>
<li><strong>Float Round Floor</strong>: <code>floor(MM0)</code></li>
<li><strong>Float Round Nearest</strong>: <code>round(MM0)</code></li>
</ul>
</section>
<section id="exercise-find-and-modify-the-board-dimensions"
class="level3">
<h3>Exercise: Find and Modify the Board Dimensions</h3>
<p>Your task is to set up watches on the width and height of the game
board, and then use those watches to change the size of the board. This
may involve some trial and error, and it may not work perfectly due to
the way <code>ncurses</code> refreshes the screen. For this exercise,
patching memory is expected, and the change should last until the target
is terminated.</p>
<p><strong>TIP</strong>: If the <code>termmines</code> image is subject
to ASLR, and you want your watch expression to generalize over
re-launches, try using <code>main</code> as an anchor for the image
base.</p>
</section>
<section id="exercise-watch-the-cell-to-be-mined" class="level3">
<h3>Exercise: Watch the Cell to be Mined</h3>
<p>Your task is to watch the byte value of the cell that is about to
have a mine placed in it. You will probably want to set a breakpoint
somewhere in the mine placement algorithm. It is okay if the watch does
not <em>always</em> display the correct byte. However, it must be
correct whenever the program counter is at your breakpoint. Register
allocations are fairly volatile, and as a result, watch expressions that
refer to registers are only valid in a limited scope. The rest of the
time, even though the watch may evaluate successfully, its value may
have no real meaning. Check your work by observing the mine bit being
ORed in as you step the target.</p>
<p><strong>TIP</strong>: Try creating watches for the row and column
indices, first. Then, perhaps referring to the Decompiler, formulate the
expression that dereferences that cell in the board.</p>
</section>
</section>
<section id="variable-hovers" class="level2">
<h2>Variable Hovers</h2>
<p>You may have already used these if you completed the exercises in the
<a href="A3-Breakpoints.html">Breakpoints</a> module. If you hover over
a variable in any listing or the Decompiler, the Debugger will attempt
to evaluate it and display information about it. In some cases,
evaluation may involve unwinding the stack. Unwinding proceeds until the
Debugger finds an invocation of the function containing or defining the
variable. If unwinding fails, the Debugger may disregard the stack. In
dynamic windows, the Debugger generally disregards the stack. In static
windows, the Debugger still uses dynamic information to unwind the stack
and evaluate the variable. A variable may be any of the following:</p>
<ul>
<li>A register in the listing. In this case, the hover will report the
registers value in the functions frame.</li>
<li>A local or parameter in the listing. If the variable is allocated in
a register, this behaves the same as hovering that register, except with
additional information presented. If the variable is allocated in stack
space, this only succeeds if unwinding succeeds.</li>
<li>A global variable in the listing. Unwinding is unnecessary for
these.</li>
<li>A local or parameter in the Decompiler. This behaves similarly to
hovering a variable in the Static Listing.</li>
<li>A global in the Decompiler. This behaves similarly to hovering a
global variable in the Static Listing.</li>
<li>A field reference in the Decompiler. A field reference is
essentially a C expression in terms of other variables. This will
evaluate those variables and then evaluate the expression.</li>
</ul>
<p>Depending on the particular variable and other circumstances, the
hover will contain some combination of these rows:</p>
<ul>
<li><strong>Name</strong>: The name of the variable</li>
<li><strong>Type</strong>: The type of the variable</li>
<li><strong>Location</strong>: The static location of the variable,
e.g., <code>Stack[0x4]</code></li>
<li><strong>Status</strong>: A progress indicator</li>
<li><strong>Frame</strong>: If evaluation required unwinding, a
description of the frame used for context</li>
<li><strong>Storage</strong>: The dynamic, physical location of the
variable, e.g., <code>7fffffffe618</code></li>
<li><strong>Bytes</strong>: The raw bytes currently stored in the memory
allocated to the variable</li>
<li><strong>Integer</strong>: The “raw” integer value of the variable,
rendered with varied signedness and radix</li>
<li><strong>Value</strong>: The value of the variable, according to its
type</li>
<li><strong>Instruction</strong>: If the variable points to code, the
target instruction</li>
<li><strong>Warnings</strong>: Warnings emitted during evaluation</li>
<li><strong>Error</strong>: If the value could not be evaluated, an
explanation or the exception</li>
</ul>
<p>The Name, Type, and Location entries are informational. They tell you
about the variable and its static definition. The Status, Frame, and
Storage entries are also informational, but tell you about the
variables dynamic evaluation. The Bytes, Integer, Value, and
Instruction entries tell you the dynamic value of the variable. Finally,
the Warnings and Error entries provide diagnostics. If there are many
warnings, then the value may not be accurate.</p>
</section>
</section>
</body>
</html>