mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 03:09:36 +08:00
Merge remote-tracking branch 'origin/GP-1431_Dan_memoryBytesHelp--SQUASHED'
This commit is contained in:
@@ -46,6 +46,8 @@ src/main/help/help/topics/DebuggerInterpreterPlugin/DebuggerInterpreterPlugin.ht
|
||||
src/main/help/help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerGoToDialog.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerListingPlugin.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerMemoryBytesPlugin/images/DebuggerMemoryBytesPlugin.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerMemviewPlugin/DebuggerMemviewPlugin.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerMemviewPlugin/images/DebuggerMemviewPlugin.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DebuggerMemviewPlugin/images/DebuggerMemviewPlugin_old.png||GHIDRA||||END|
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
sortgroup="h"
|
||||
target="help/topics/DebuggerRegistersPlugin/DebuggerRegistersPlugin.html" />
|
||||
|
||||
<tocdef id="DebuggerMemoryBytesPlugin" text="Memory"
|
||||
sortgroup="h1"
|
||||
target="help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html" />
|
||||
|
||||
<tocdef id="DebuggerListingPlugin" text="Dynamic Listing"
|
||||
sortgroup="i"
|
||||
target="help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html" />
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE doctype PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META name="generator" content=
|
||||
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||
|
||||
<TITLE>Debugger: Memory (Dynamic Bytes)</TITLE>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
|
||||
</HEAD>
|
||||
|
||||
<BODY lang="EN-US">
|
||||
<H1><A name="plugin"></A>Debugger: Memory (Dynamic Bytes)</H1>
|
||||
|
||||
<TABLE width="100%">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD align="center" width="100%"><IMG alt="" border="1" src=
|
||||
"images/DebuggerMemoryBytesPlugin.png"></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
||||
<P><A name="Toggle_Header"></A>The memory, or dynamic bytes, window is analogous to Ghidra's
|
||||
bytes window for static analysis, but in the dynamic context. That is, it displays memory
|
||||
contents from a target. More precisely, it displays recorded memory contents in a trace. In
|
||||
most use cases, that trace is "at the present," meaning it is the most recent memory from a
|
||||
live target. Multiple memory windows can be displayed simultaneously, using the same pattern as
|
||||
many other Ghidra windows. The "primary" window is always displayed and generally tracks with
|
||||
the rest of the tool. Any window can be "snapshotted," i.e., duplicated. This is where memory
|
||||
windows differ from static bytes windows. Static snapshots remain in place; they do not
|
||||
automatically navigate. Dynamic snapshots can still be configured to navigate, following the
|
||||
rest of the tool. A common use is to configure a "snapshot" to follow the stack pointer. Still,
|
||||
you can disable a window's automatic navigation, so it behaves like a true snapshot. A current
|
||||
limitation is that you cannot use snapshots to display different points in time for the same
|
||||
trace.</P>
|
||||
|
||||
<P>Because not all memory is captured, some background coloring is used to indicate the state
|
||||
of attempted memory reads. Regardless of state, the most-recent contents, as recorded in the
|
||||
trace, are displayed in the window, defaulting to 00. "Stale" memory, that is ranges of memory
|
||||
which have not been read at the current time, are displayed with a darker background. Where
|
||||
that memory is marked "read-only" and has been successfully read previously, that coloring is
|
||||
subdued, since the contents are not likely to have changed. Where a read was attempted but
|
||||
failed, the first address in the failed range is displayed with a pink background. Otherwise,
|
||||
up-to-date contents are displayed with the default background color.</P>
|
||||
|
||||
<P>NOTE: Modification of trace byte contents is a work in progress. At the moment, the feature
|
||||
is simply disabled. In general, modifications to bytes when the window is "at the present" are
|
||||
directed to the target. Otherwise, they simply modify the historical or emulated values stored
|
||||
in the trace. A modification at a given time remains in effect, but stale, for all future times
|
||||
up to but excluding the time of the next recorded value.</P>
|
||||
|
||||
<H2>Actions</H2>
|
||||
|
||||
<P>The memory window provides a variety of actions, some for managing and configuring windows,
|
||||
and others for capturing memory from a target.</P>
|
||||
|
||||
<H3><A name="follows_thread"></A>Follows Selected Thread</H3>
|
||||
|
||||
<P>This action is only available on snapshot memory windows. The primary window always follows
|
||||
the tool's current thread. Disabling this toggle causes the snapshot to remain on its own
|
||||
current thread rather than following the tool's. The current thread is used when computing a
|
||||
location to navigate to automatically. It is only applicable when "Track Location" is set to
|
||||
something other than "Do Not Track."</P>
|
||||
|
||||
<H3><A name="track_location"></A>Track Location</H3>
|
||||
|
||||
<P>This action is always available on all memory windows. It configures automatic navigation
|
||||
for the window. When location tracking is enabled, the window is automatically navigated to an
|
||||
address computed from the trace's or target's machine state. The address is also highlighted in
|
||||
green. The computed address is affected by the tool's current "coordinates," that is the
|
||||
selected thread, frame, and point in time. The options are pluggable, but currently consist
|
||||
of:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Do Not Track - disables automatic navigation.</LI>
|
||||
|
||||
<LI>Track Program Counter - (default) navigates this window to the current program counter.
|
||||
If the stack contains a record of the program counter, it is preferred to the recorded
|
||||
register value. Note that debuggers may vary in how they report the program counter, and its
|
||||
meaning may vary among platforms. While there may be some nuances to the register value, the
|
||||
value recorded in the stack should indicate the next instruction to be executed.</LI>
|
||||
|
||||
<LI>Track Stack Pointer - navigates this window to the current stack pointer. Again,
|
||||
platforms may vary in how they define the stack pointer.</LI>
|
||||
</UL>
|
||||
|
||||
<H3><A name="go_to"></A>Go To (G)</H3>
|
||||
|
||||
<P>This action is available whenever a trace is active in the window. It prompts the user for
|
||||
an address, which can be expressed in Sleigh, then attempts to navigate to it. The expression
|
||||
is evaluated in the context of the current thread, frame, and point in time. If the current
|
||||
trace is live and at the present, the target may be queried to retrieve any machine state
|
||||
required to evaluate the expression.</P>
|
||||
|
||||
<TABLE width="100%">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD align="center" width="100%"><IMG alt="" src=
|
||||
"help/topics/DebuggerListingPlugin/images/DebuggerGoToDialog.png"></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
||||
<H3><A name="capture_memory"></A>Capture Memory</H3>
|
||||
|
||||
<P>This action is available when the current trace is "at the present" with a live target, and
|
||||
there is a selection of addresses in the memory window. It will instruct the recorder to
|
||||
capture the contents of memory for the selected range(s). Typically, the viewable addresses are
|
||||
automatically captured — see the Auto-Read action.</P>
|
||||
|
||||
<H3><A name="auto_memory"></A>Auto-Read Memory</H3>
|
||||
|
||||
<P>This action is always available on all memory windows. It configures whether or not the
|
||||
memory range(s) displayed in the window are automatically captured. Like the Capture Memory
|
||||
action, capture can only occur when the current trace is "at the present" with a live target.
|
||||
It occurs when the user scrolls the window, or when the window is otherwise navigated to a new
|
||||
location. Note that other components may capture memory, regardless of this windows's
|
||||
configuration. For example, the recorder typically captures the page of memory pointed to by
|
||||
the program counter. In other words, this action <EM>cannot</EM> "disable all memory captures."
|
||||
The options are pluggable, but currently consist of:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Do Not Read Memory - disables automatic memory capture <EM>for this window
|
||||
only</EM>.</LI>
|
||||
|
||||
<LI>Read Visible Memory - automatically reads stale ranges that enter this window's
|
||||
view.</LI>
|
||||
|
||||
<LI>Read Visible Memory, RO Once - (default) behaves like Read Visible Memory, except it will
|
||||
neglect to capture read-only ranges that have been captured previously.</LI>
|
||||
</UL>
|
||||
|
||||
<H3><A name="Byte_Viewer_Options"></A>Byte Viewer Options</H3>
|
||||
|
||||
<P>This action does the same as it does for the static context.</P>
|
||||
|
||||
<H3><A name="Enable_Disable_Byteviewer_Editing"></A>Toggle Editing</H3>
|
||||
|
||||
<P>This action does the same as it does for the static context. NOTE: This feature is currently
|
||||
disabled, as it is a work in progress.</P>
|
||||
|
||||
<H2><A name="colors"></A>Tool Options: Colors</H2>
|
||||
|
||||
<P>The memory-state and tracked-location background colors are replicated from the <A href=
|
||||
"help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html">Dynamic Listing</A>.</P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
+128
@@ -0,0 +1,128 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.memory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
import ghidra.app.plugin.assembler.Assembler;
|
||||
import ghidra.app.plugin.assembler.Assemblers;
|
||||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin;
|
||||
import ghidra.app.services.DebuggerTraceManagerService;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegisterSpace;
|
||||
import ghidra.trace.model.symbol.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.database.UndoableTransaction;
|
||||
import help.screenshot.GhidraScreenShotGenerator;
|
||||
|
||||
public class DebuggerMemoryBytesPluginScreenShots extends GhidraScreenShotGenerator {
|
||||
|
||||
DebuggerTraceManagerService traceManager;
|
||||
DebuggerMemoryBytesPlugin memoryPlugin;
|
||||
DebuggerMemoryBytesProvider memoryProvider;
|
||||
DebuggerListingPlugin listingPlugin; // For colors
|
||||
ToyDBTraceBuilder tb;
|
||||
|
||||
@Before
|
||||
public void setUpMine() throws Throwable {
|
||||
traceManager = addPlugin(tool, DebuggerTraceManagerServicePlugin.class);
|
||||
memoryPlugin = addPlugin(tool, DebuggerMemoryBytesPlugin.class);
|
||||
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
|
||||
memoryProvider = waitForComponentProvider(DebuggerMemoryBytesProvider.class);
|
||||
tool.showComponentProvider(memoryProvider, true);
|
||||
|
||||
tb = new ToyDBTraceBuilder("echo", ToyProgramBuilder._X64);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDownMine() {
|
||||
tb.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaptureDebuggerMemoryBytesPlugin() throws Throwable {
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
long snap = tb.trace.getTimeManager().createSnapshot("First").getKey();
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion(".text", Range.atLeast(0L), tb.range(0x00400000, 0x0040ffff),
|
||||
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||
|
||||
TraceSymbolManager symbolManager = tb.trace.getSymbolManager();
|
||||
TraceNamespaceSymbol global = symbolManager.getGlobalNamespace();
|
||||
|
||||
TraceSymbol mainLabel = symbolManager
|
||||
.labels()
|
||||
.create(snap, null, tb.addr(0x00400000),
|
||||
"main", global, SourceType.USER_DEFINED);
|
||||
@SuppressWarnings("unused")
|
||||
TraceSymbol cloneLabel = symbolManager
|
||||
.labels()
|
||||
.create(snap, null, tb.addr(0x00400060),
|
||||
"clone", global, SourceType.USER_DEFINED);
|
||||
TraceSymbol childLabel = symbolManager
|
||||
.labels()
|
||||
.create(snap, null, tb.addr(0x00400034),
|
||||
"child", global, SourceType.USER_DEFINED);
|
||||
@SuppressWarnings("unused")
|
||||
TraceSymbol exitLabel = symbolManager
|
||||
.labels()
|
||||
.create(snap, null, tb.addr(0x00400061),
|
||||
"exit", global, SourceType.USER_DEFINED);
|
||||
|
||||
Assembler assembler = Assemblers.getAssembler(tb.trace.getProgramView());
|
||||
|
||||
assembler.assemble(mainLabel.getAddress(),
|
||||
"PUSH RBP",
|
||||
"MOV RBP,RSP",
|
||||
"CALL clone",
|
||||
"TEST EAX,EAX",
|
||||
"JNZ child",
|
||||
"SUB RSP,0x10",
|
||||
"MOV dword ptr [RSP],0x6c6c6548",
|
||||
"MOV dword ptr [RSP+4],0x57202c6f",
|
||||
"MOV dword ptr [RSP+8],0x646c726f",
|
||||
"MOV word ptr [RSP+0xc],0x21",
|
||||
"CALL exit",
|
||||
"SUB RSP,0x10",
|
||||
"MOV dword ptr [RSP],0x2c657942",
|
||||
"MOV dword ptr [RSP+4],0x726f5720",
|
||||
"MOV dword ptr [RSP+8],0x21646c",
|
||||
"CALL exit");
|
||||
|
||||
TraceThread thread = tb.getOrAddThread("[1]", snap);
|
||||
|
||||
TraceMemoryRegisterSpace regs =
|
||||
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(snap, new RegisterValue(tb.language.getProgramCounter(),
|
||||
childLabel.getAddress().getOffsetAsBigInteger()));
|
||||
}
|
||||
|
||||
traceManager.openTrace(tb.trace);
|
||||
traceManager.activateTrace(tb.trace);
|
||||
|
||||
captureIsolatedProvider(DebuggerMemoryBytesProvider.class, 600, 600);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user