ghidra/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.html

316 lines
15 KiB
HTML
Raw 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="#memory-map" id="toc-memory-map">Memory Map</a>
<ul>
<li><a href="#regions" id="toc-regions">Regions</a></li>
<li><a href="#modules" id="toc-modules">Modules</a></li>
<li><a href="#optional-exercise-find-the-time-surgically"
id="toc-optional-exercise-find-the-time-surgically">Optional Exercise:
Find the Time Surgically</a></li>
<li><a href="#static-mappings" id="toc-static-mappings">Static
Mappings</a></li>
<li><a href="#moving-knowledge-from-dynamic-to-static"
id="toc-moving-knowledge-from-dynamic-to-static">Moving Knowledge from
Dynamic to Static</a></li>
<li><a href="#exercise-export-and-map-ncurses"
id="toc-exercise-export-and-map-ncurses">Exercise: Export and Map
<code>ncurses</code></a></li>
<li><a href="#exercise-cheat-like-the-devs"
id="toc-exercise-cheat-like-the-devs">Exercise: Cheat Like the
Devs</a></li>
</ul></li>
</ul>
</nav>
<section id="memory-map" class="level1">
<h1>Memory Map</h1>
<p>This modules 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 following features in more depth:</p>
<ul>
<li>The Regions window</li>
<li>The Modules window</li>
<li>The Static Mappings window</li>
</ul>
<p>If you do not have an active session, please launch
<code>termmines</code> in the Debugger.</p>
<section id="regions" class="level2">
<h2>Regions</h2>
<figure>
<img src="images/MemoryMap_RegionsAfterLaunch.png"
alt="Regions window after launch" />
<figcaption aria-hidden="true">Regions window after launch</figcaption>
</figure>
<p>The Regions window displays a list of all the memory regions known to
the back-end debugger. In practice, not all targets will report this
information. The nearest analog from the CodeBrowser is the Memory Map
window. Unlike the Memory Map window, the Regions window includes all
regions mapped to external modules, as well as regions allocated for
stacks, heaps, or other system objects. The columns are:</p>
<ul>
<li>The <strong>Name</strong> column gives the name of the region. For
file-backed mappings, this should include the name of the file. It may
or may not include a section name. Typically, the name will include the
start address to avoid collisions.</li>
<li>The <strong>Start</strong> column gives the minimum address of the
region.</li>
<li>The <strong>End</strong> column gives the maximum (inclusive)
address of the region.</li>
<li>The <strong>Length</strong> column gives the number of bytes in the
region.</li>
<li>The <strong>Read</strong>, <strong>Write</strong>, and
<strong>Execute</strong> columns give the permissions of the
region.</li>
</ul>
<p>Try using the filter and column headers to sift and sort for
interesting regions. Double-click the start or end address to navigate
to them in the Dynamic Listing. Select one or more regions, right-click,
and choose <strong>Select Addresses</strong>. That should select all the
addresses in those regions in the Dynamic Listing. Used with the
<strong>Read Memory</strong> button in the Dynamic Listing, you can
selectively capture memory into the current snapshot.</p>
</section>
<section id="modules" class="level2">
<h2>Modules</h2>
<figure>
<img src="images/MemoryMap_ModulesAfterLaunch.png"
alt="Modules window after launch" />
<figcaption aria-hidden="true">Modules window after launch</figcaption>
</figure>
<p>The Modules window has two panes, though the second is disabled by
default. The top pane displays a list of all the <em>modules</em> known
to the back-end debugger. The bottom pane displays a list of all the
<em>sections</em> known to the back-end debugger. In practice, not all
targets will report module information. Fewer targets report section
information, and those that do may only report them to Ghidra when
specifically requested. The nearest analog to the bottom panel from the
CodeBrowser is (also) the Memory Map window. The top panel has no real
analog; however, the tabs above the Static Listing pane serve a similar
purpose.</p>
<p>For a target that reports section information, the bottom panel will
display a lot of the same information as the Regions window. The columns
differ slightly, and the sections panel will <em>not</em> include
stacks, heaps, etc.</p>
<p>The module columns are:</p>
<ul>
<li>The <strong>Base</strong> column gives the image base for the
module. This should be the minimum address of the module.</li>
<li>The <strong>Max</strong> column gives the maximum address of the
module.</li>
<li>The <strong>Name</strong> column gives the (short) name of the
module.</li>
<li>The <strong>Mapping</strong> column gives the mapped Ghidra program
database for the module.</li>
<li>The <strong>Length</strong> column gives the distance between the
base and max address (inclusive). Note that not every address between
base and max is necessarily mapped to the module. ELF headers specify
the load address of each section, so the memory footprint usually has
many gaps.</li>
</ul>
<p>See the Help (press <strong><code>F1</code></strong> in the Modules
panel) to learn more about the Sections table, if desired. It can be
enabled using the <strong>Show Sections Table</strong> button in the
local toolbar.</p>
<p>Double-click any address to navigate to it. Make a selection of
modules or sections, right-click, and choose <strong>Select
Addresses</strong>. Again, combined with the Dynamic Listings
<strong>Read Memory</strong> button, you can capture memory
selectively.</p>
</section>
<section id="optional-exercise-find-the-time-surgically" class="level2">
<h2>Optional Exercise: Find the Time Surgically</h2>
<p>Repeat the “Find the Time” exercise from the previous module, but use
the Modules and Regions windows to form a more surgical selection for
capturing into the snapshots.</p>
</section>
<section id="static-mappings" class="level2">
<h2>Static Mappings</h2>
<p>The Static Mappings window provides user access to the traces static
mapping table. There are two ways to open the window:</p>
<ol type="1">
<li>In the menu: <strong>Window → Debugger → Static
Mappings</strong>.</li>
<li>From the Modules window, click Map Manually in the local
toolbar.</li>
</ol>
<figure>
<img src="images/MemoryMap_StaticMappingAfterLaunch.png"
alt="Static mappings window after launch" />
<figcaption aria-hidden="true">Static mappings window after
launch</figcaption>
</figure>
<p>Each row in the table is a range of mapped addresses. The columns
are:</p>
<ul>
<li>The <strong>Dynamic Address</strong> column gives the minimum
dynamic address in the mapped range.</li>
<li>The <strong>Static Program</strong> column gives the Ghidra URL of
the static image.</li>
<li>The <strong>Static Address</strong> column gives the minimum static
address in the mapped range.</li>
<li>The <strong>Length</strong> column gives the number of bytes in the
range.</li>
<li>The <strong>Shift</strong> column gives the difference in address
offsets from static to dynamic.</li>
<li>The <strong>Lifespan</strong> column gives the span of snapshots for
which this mapped range applies.</li>
</ul>
<p>The Ghidra Debugger relies heavily on Module information to
synchronize the listings and to correlate its static and dynamic
knowledge. Instead of using the module list directly for this
correlation, it populates a <em>static mapping</em> table. This permits
other sources, including user overrides, to inform the correlation. By
default, whenever a new program is opened and/or imported, the Debugger
will attempt to match it to a module in the trace and map it.
Furthermore, when you navigate to an address in a module that it is not
yet mapped to a program, it will search your project for a match and
open it automatically. You may notice the two address columns, as well
as the shift column. This illustrates that the Debugger can recognize
and cope with module relocation, especially from ASLR.</p>
<p>There are many ways to manually override the mappings:</p>
<ul>
<li>From the Modules window, select one or more modules, and choose from
the <strong>Map Module</strong> actions. Selecting a single module at a
time, it is possible to surgically map each to a chosen program.</li>
<li>From the Sections panel, select one or more sections, and choose
from the <strong>Map Section</strong> actions. This is certainly more
tedious and atypical, but it allows the surgical mapping of each section
to a chosen memory block from among your open programs.</li>
<li>From the Regions window, select one or more regions, and choose from
the <strong>Map Region</strong> actions.</li>
<li>Click the <strong>Map Identically</strong> button in the Modules
window toolbar.</li>
<li>Use the <strong>Add</strong> and <strong>Remove</strong> buttons in
the Static Mappings window toolbar.</li>
</ul>
<p>These methods are not described in detail here. For more information,
hover over the relevant actions and press
<strong><code>F1</code></strong> for help.</p>
</section>
<section id="moving-knowledge-from-dynamic-to-static" class="level2">
<h2>Moving Knowledge from Dynamic to Static</h2>
<p>There are occasions when it is necessary or convenient to transfer
data or markup from the dynamic session into a static program database.
For example, suppose during experimentation, you have placed a bunch of
code units in the Dynamic Listing. You might have done this because the
memory is uninitialized in the Static Listing, and you preferred some
trial and error in the Dynamic Listing, where the memory is populated.
In this case, you would want to copy those code units (though not
necessarily the byte values) from the Dynamic Listing into the Static
Listing. After selecting the units to copy, you would use
<strong>Debugger → Copy Into Current Program</strong> in the menus.</p>
<p>In another example, you might not have an on-disk image for a module,
but you would still like to perform static analysis on that module. In
this case, you would want to copy everything within that module from the
dynamic session into a program database. After selecting the addresses
in that module, you would use <strong>Debugger → Copy Into New
Program</strong>.</p>
<p>For demonstration, we will walk through this second case, pretending
we cannot load <code>libncurses</code> from disk:</p>
<ol type="1">
<li><p>In the top pane of the Modules window, right-click
<code>libncurses</code> and choose <strong>Select Addresses</strong>.
(Do not click <strong>Import From File System</strong>, since we are
pretending you cannot.)</p></li>
<li><p>Change focus to the Dynamic Listing.</p></li>
<li><p>In the global menu, choose <strong>Debugger → Copy Into New
Program</strong>.</p>
<figure>
<img src="images/MemoryMap_CopyNcursesInto.png"
alt="Copy dialog for ncurses" />
<figcaption aria-hidden="true">Copy dialog for ncurses</figcaption>
</figure></li>
<li><p>Keep <strong>Destination</strong> set to “&lt;New
Program&gt;.”</p></li>
<li><p>Ensure <strong>Read live targets memory</strong> is checked.
This will spare you from having to create a full snapshot
manually.</p></li>
<li><p>Do <em>not</em> check <strong>Use overlays where blocks already
exist</strong>. It should not have any effect for a new program,
anyway.</p></li>
<li><p>It is probably best to include everything, though
<strong>Bytes</strong> is the bare minimum.</p></li>
<li><p>The table displays the <em>copy plan</em>. For a new program,
this will copy with an identical mapping of addresses, which is probably
the best plan, since the target system has already applied fixups. Do
not change any addresses, lest your corrupt references in the
copy.</p></li>
<li><p>Click <strong>Copy</strong>.</p></li>
<li><p>When prompted, name the program <code>libncurses</code>.</p></li>
<li><p>You may need to click the <code>termmines</code> tab in the
Static Listing to get the UI to completely update.</p></li>
<li><p>Click back over to <code>libncurses</code> and save the program.
If you are prompted to analyze, go ahead.</p></li>
</ol>
<p>Undoubtedly, we would like to map that new program into our dynamic
session.</p>
<ol type="1">
<li>Ensure that the new <code>libncurses</code> capture is still the
current program.</li>
<li>In the top pane of the Modules window, right-click
<code>libncurses</code> and choose <strong>Map to
libncurses</strong>.</li>
<li>Check the proposed mapping and click <strong>OK</strong>.</li>
</ol>
</section>
<section id="exercise-export-and-map-ncurses" class="level2">
<h2>Exercise: Export and Map <code>ncurses</code></h2>
<p>Repeat this technique for the “system-supplied DSO” module. In
practice, there is no real reason to do this, but this particular module
prevents you from using <strong>Import From File System</strong>.</p>
</section>
<section id="exercise-cheat-like-the-devs" class="level2">
<h2>Exercise: Cheat Like the Devs</h2>
<p>This concludes the portion on the basic features of the Ghidra
Debugger. Now, lets put your new knowledge to good use!</p>
<p>The developers left a cheat code in <code>termmines</code>. Your goal
is to figure out the cheat code, determine what it does, and describe
how it is implemented. If you have already stumbled upon this cheat, you
must still explain how it is implemented.</p>
</section>
</section>
</body>
</html>