GP-3887: Update Debugger course for Trace RMI.

This commit is contained in:
Dan 2024-04-22 10:11:25 -04:00
parent 190f1eaa1e
commit a93a695e6a
79 changed files with 2235 additions and 1663 deletions

View file

@ -26,28 +26,26 @@ The columns are:
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.
* The **Lifespan** 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.
* The **Start** column gives the minimum address of the region.
* The **End** column gives the maximum (inclusive) address of the region.
* The **Length** column gives the number of bytes in the region.
* The **Read**, **Write**, **Execute**, and **Volatile** columns give the permissions/flags of the region.
* The **Read**, **Write**, and **Execute** columns give the permissions of the region.
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 **Select Addresses**.
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.
Used with the **Read Memory** button in the Dynamic Listing, you can selectively capture memory into the current snapshot.
## Modules
![Modules window after launch](images/MemoryMap_ModulesAfterLaunch.png)
The Modules window has two panes.
The Modules window has two panes, though the second is disabled by default.
The top pane displays a list of all the *modules* known to the back-end debugger.
The bottom pane displays a list of all the *sections* known to the back-end debugger.
In practice, not all targets will report module information.
Fewer targets report section 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.
@ -58,32 +56,19 @@ The module columns are:
* The **Base** column gives the image base for the module.
This should be the minimum address of the module.
* The **Max Address** column gives the maximum address of the module.
* The **Max** column gives the maximum address of the module.
* The **Name** column gives the (short) name of the module.
* The **Module Name** column gives the full file path of the module *on target*.
In some cases, this gives some other description of the module.
* The **Lifespan** column gives the span of snapshots where the module has been observed.
* The **Mapping** column gives the mapped Ghidra program database for the module.
* The **Length** 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.
The section columns are:
See the Help (press **`F1`** in the Modules panel) to learn more about the Sections table, if desired.
It can be enabled using the **Show Sections Table** button in the local toolbar.
* The **Start Address** gives the minimum address of the section.
* The **End Address** gives the maximum (inclusive) address of the section.
* The **Section Name** gives the name of the section.
* The **Module Name** gives the name of the module containing the section.
* The **Length** gives the number of bytes contained in the section.
**NOTE**: There is no lifespan column for a section.
The lifespan of a section is the lifespan of its containing module.
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 **Select Addresses**.
Again, combined with the Dynamic Listing's Refresh button, you can capture memory surgically.
Again, combined with the Dynamic Listing's **Read Memory** button, you can capture memory selectively.
## Optional Exercise: Find the Time Surgically
@ -121,14 +106,14 @@ There are many ways to manually override the mappings:
* From the Modules window, select one or more modules, and choose from the **Map Module** actions.
Selecting a single module at a time, it is possible to surgically map each to a chosen program.
* From the Sections window, select one or more sections, and choose from the **Map Section** actions.
* From the Sections panel, select one or more sections, and choose from the **Map Section** 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.
* From the Regions window, select one or more regions, and choose from the **Map Region** actions.
* Click the Map Identically button in the Modules window toolbar.
* Use the Add and Remove buttons in the Static Mappings window toolbar.
* Click the **Map Identically** button in the Modules window toolbar.
* Use the **Add** and **Remove** buttons in the Static Mappings window toolbar.
These methods are not described in detail here.
For more information, hover over the relevant actions and press **F1** for help.
For more information, hover over the relevant actions and press **`F1`** for help.
## Moving Knowledge from Dynamic to Static
@ -136,11 +121,11 @@ There are occasions when it is necessary or convenient to transfer data or marku
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 **Debugger → Copy Into Current Program**.
After selecting the units to copy, you would use **Debugger → Copy Into Current Program** in the menus.
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 **Debugger → Copy Into New Program**.
After selecting the addresses in that module, you would use **Debugger → Copy Into New Program**.
For demonstration, we will walk through this second case, pretending we cannot load `libncurses` from disk:
@ -151,16 +136,16 @@ For demonstration, we will walk through this second case, pretending we cannot l
![Copy dialog for ncurses](images/MemoryMap_CopyNcursesInto.png)
1. Keep Destination set to "New Program."
1. Ensure "Read live target's memory" is checked.
1. Keep **Destination** set to "<New Program>."
1. Ensure **Read live target's memory** is checked.
This will spare you from having to create a full snapshot manually.
1. Do *not* check "Use overlays where blocks already present."
1. Do *not* check **Use overlays where blocks already exist**.
It should not have any effect for a new program, anyway.
1. It is probably best to include everything, though "Bytes" is the bare minimum.
1. It is probably best to include everything, though **Bytes** is the bare minimum.
1. The table displays the *copy plan*.
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.
1. Click Copy.
1. Click **Copy**.
1. When prompted, name the program `libncurses`.
1. You may need to click the `termmines` tab in the Static Listing to get the UI to completely update.
1. Click back over to `libncurses` and save the program.
@ -168,12 +153,9 @@ For demonstration, we will walk through this second case, pretending we cannot l
Undoubtedly, we would like to map that new program into our dynamic session.
1. Again, in the top pane of the Modules window, right-click `libncurses` and choose **Select Addresses**.
1. Ensure the cursor in the Static Listing is at the minimum address of `libncurses`.
1. In the Static Mappings window, click Add in the toolbar.
1. Click OK.
**NOTE**: This should be done by choosing **Map to libncurses** in the right-click menu, but a bug seems to stifle that, currently.
1. Ensure that the new `libncurses` capture is still the current program.
1. In the top pane of the Modules window, right-click `libncurses` and choose **Map to libncurses**.
1. Check the proposed mapping and click **OK**.
## Exercise: Export and Map `ncurses`