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

334 lines
16 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>Lifespan</strong> column gives the span of snapshots
where the region has been observed. Memory maps can change during the
course of execution, and this is how Ghidra records and presents that
history.</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>,
<strong>Execute</strong>, and <strong>Volatile</strong> columns give the
permissions/flags 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 Refresh
button, you can surgically 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. 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. 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 Address</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>Module Name</strong> column gives the full file path of
the module <em>on target</em>. In some cases, this gives some other
description of the module.</li>
<li>The <strong>Lifespan</strong> column gives the span of snapshots
where the module has been observed.</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>The section columns are:</p>
<ul>
<li>The <strong>Start Address</strong> gives the minimum address of the
section.</li>
<li>The <strong>End Address</strong> gives the maximum (inclusive)
address of the section.</li>
<li>The <strong>Section Name</strong> gives the name of the
section.</li>
<li>The <strong>Module Name</strong> gives the name of the module
containing the section.</li>
<li>The <strong>Length</strong> gives the number of bytes contained in
the section.</li>
</ul>
<p><strong>NOTE</strong>: There is no lifespan column for a section. The
lifespan of a section is the lifespan of its containing module.</p>
<p>Try using the filter and column headers in each pane to sift and
sort. This is especially helpful for the sections: Type the name of a
module or section. You can also toggle the filter button in the local
toolbar to filter the sections pane to those contained in a selected
module from the top pane. 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 Refresh button, you can capture memory surgically.</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 window, 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 Map Identically button in the Modules window toolbar.</li>
<li>Use the Add and Remove 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>F1</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, from the menus, you would
use <strong>Debugger → Copy Into Current Program</strong>.</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, from the menus, 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 Destination set to “New Program.”</p></li>
<li><p>Ensure “Read live targets memory” is checked. This will spare
you from having to create a full snapshot manually.</p></li>
<li><p>Do <em>not</em> check “Use overlays where blocks already
present.” It should not have any effect for a new program,
anyway.</p></li>
<li><p>It is probably best to include everything, though “Bytes” 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 Copy.</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>Again, in the top pane of the Modules window, right-click
<code>libncurses</code> and choose <strong>Select
Addresses</strong>.</li>
<li>Ensure the cursor in the Static Listing is at the minimum address of
<code>libncurses</code>.</li>
<li>In the Static Mappings window, click Add in the toolbar.</li>
<li>Click OK.</li>
</ol>
<p><strong>NOTE</strong>: This should be done by choosing <strong>Map to
libncurses</strong> in the right-click menu, but a bug seems to stifle
that, currently.</p>
</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>