diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommandConstants.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommandConstants.java
index 4dcaa23d3f..6f5f0cc725 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommandConstants.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommandConstants.java
@@ -4,9 +4,9 @@
* 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.
@@ -43,9 +43,10 @@ public final class DyldInfoCommandConstants {
public final static int BIND_TYPE_TEXT_ABSOLUTE32 = 2;
public final static int BIND_TYPE_TEXT_PCREL32 = 3;
- public final static int BIND_SPECIAL_DYLIB_SELF = 0;
- public final static int BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1;
- public final static int BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2;
+ public final static int BIND_SPECIAL_DYLIB_SELF = 0;
+ public final static int BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1;
+ public final static int BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2;
+ public final static int BIND_SPECIAL_DYLIB_WEAK_LOOKUP = -3;
public final static int BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1;
public final static int BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8;
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java
index 7c6aae4da3..b43ec8a59f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java
@@ -28,15 +28,15 @@ import ghidra.app.util.opinion.MachoProgramBuilder;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
-import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.Relocation.Status;
-import ghidra.program.model.symbol.Symbol;
-import ghidra.program.model.symbol.SymbolTable;
+import ghidra.program.model.symbol.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class DyldChainedFixups {
+ public static final int RELOCATION_TYPE = 0x8888;
+
/**
* Walks the chained fixup information and collects a {@link List} of {@link DyldFixup}s that
* will need to be applied to the image
@@ -67,10 +67,10 @@ public class DyldChainedFixups {
long chainLoc = page + nextOff;
final long chainValue = DyldChainedPtr.getChainValue(reader, chainLoc, pointerFormat);
- long newChainValue = chainValue;
+ Long newChainValue = chainValue;
boolean isAuthenticated = DyldChainedPtr.isAuthenticated(pointerFormat, chainValue);
boolean isBound = DyldChainedPtr.isBound(pointerFormat, chainValue);
- Symbol symbol = null;
+ String symbol = null;
Integer libOrdinal = null;
if (isBound) {
@@ -88,13 +88,16 @@ public class DyldChainedFixups {
int chainOrdinal = (int) DyldChainedPtr.getOrdinal(pointerFormat, chainValue);
long addend = DyldChainedPtr.getAddend(pointerFormat, chainValue);
DyldChainedImport chainedImport = chainedImports.getChainedImport(chainOrdinal);
- List globalSymbols = symbolTable.getGlobalSymbols(chainedImport.getName());
+ symbol = SymbolUtilities.replaceInvalidChars(chainedImport.getName(), true);
+ libOrdinal = chainedImport.getLibOrdinal();
+ List globalSymbols = symbolTable.getGlobalSymbols(symbol);
if (globalSymbols.size() > 0) {
- symbol = globalSymbols.get(0);
- newChainValue = symbol.getAddress().getOffset();
- libOrdinal = chainedImport.getLibOrdinal();
+ newChainValue = globalSymbols.getFirst().getAddress().getOffset();
+ newChainValue += isAuthenticated ? auth_value_add : addend;
+ }
+ else {
+ newChainValue = null;
}
- newChainValue += isAuthenticated ? auth_value_add : addend;
}
else {
if (isAuthenticated) {
@@ -110,7 +113,7 @@ public class DyldChainedFixups {
}
fixups.add(new DyldFixup(chainLoc, newChainValue, DyldChainedPtr.getSize(pointerFormat),
- symbol != null ? symbol.getName() : null, libOrdinal));
+ symbol, libOrdinal));
next = DyldChainedPtr.getNext(pointerFormat, chainValue);
nextOff += next * DyldChainedPtr.getStride(pointerFormat);
@@ -128,12 +131,11 @@ public class DyldChainedFixups {
* @param log The log
* @param monitor A cancellable monitor
* @return A {@link List} of fixed up {@link Address}'s
- * @throws MemoryAccessException If there was a problem accessing memory
* @throws CancelledException If the user cancelled the operation
*/
public static List fixupChainedPointers(List fixups, Program program,
Address imagebase, List libraryPaths, MessageLog log, TaskMonitor monitor)
- throws MemoryAccessException, CancelledException {
+ throws CancelledException {
List fixedAddrs = new ArrayList<>();
if (fixups.isEmpty()) {
return fixedAddrs;
@@ -142,37 +144,42 @@ public class DyldChainedFixups {
monitor.initialize(fixups.size(), "Fixing up chained pointers...");
for (DyldFixup fixup : fixups) {
monitor.increment();
- Status status = Status.FAILURE;
+ Status status = Status.UNSUPPORTED;
Address addr = imagebase.add(fixup.offset());
+ String symbol = fixup.symbol();
+ long[] value = new long[] {};
try {
- if (fixup.size() == 8 || fixup.size() == 4) {
- if (fixup.size() == 8) {
- memory.setLong(addr, fixup.value());
+ if (fixup.value() != null) {
+ if (fixup.size() == 8 || fixup.size() == 4) {
+ if (fixup.size() == 8) {
+ memory.setLong(addr, fixup.value());
+ }
+ else {
+ memory.setInt(addr, fixup.value().intValue());
+ }
+ fixedAddrs.add(addr);
+ status = Status.APPLIED_OTHER;
}
- else {
- memory.setInt(addr, (int) fixup.value());
+ value = new long[] { fixup.value() };
+ }
+ if (symbol != null && fixup.libOrdinal() != null) {
+ value = new long[] { fixup.libOrdinal() };
+ try {
+ MachoProgramBuilder.fixupExternalLibrary(program, libraryPaths,
+ fixup.libOrdinal(), symbol);
+ }
+ catch (Exception e) {
+ log.appendMsg("WARNING: Problem fixing up symbol '%s' - %s"
+ .formatted(symbol, e.getMessage()));
}
- fixedAddrs.add(addr);
- status = Status.APPLIED_OTHER;
- }
- else {
- status = Status.UNSUPPORTED;
}
}
+ catch (Exception e) {
+ status = Status.FAILURE;
+ }
finally {
program.getRelocationTable()
- .add(addr, status, 0, new long[] { fixup.value() }, fixup.size(),
- fixup.symbol() != null ? fixup.symbol() : null);
- }
- if (fixup.symbol() != null && fixup.libOrdinal() != null) {
- try {
- MachoProgramBuilder.fixupExternalLibrary(program, libraryPaths,
- fixup.libOrdinal(), fixup.symbol());
- }
- catch (Exception e) {
- log.appendMsg("WARNING: Problem fixing up symbol '%s' - %s"
- .formatted(fixup.symbol(), e.getMessage()));
- }
+ .add(addr, status, RELOCATION_TYPE, value, fixup.size(), symbol);
}
}
log.appendMsg("Fixed up " + fixedAddrs.size() + " chained pointers.");
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedImport.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedImport.java
index 65db0e2a69..e83510ce00 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedImport.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedImport.java
@@ -47,14 +47,16 @@ public class DyldChainedImport implements StructConverter {
switch (imports_format) {
case DYLD_CHAINED_IMPORT: {
int ival = reader.readNextInt();
- lib_ordinal = ival & 0xff;
+ int ordinal = ival & 0xff;
+ lib_ordinal = ordinal > 0xf0 ? (byte) ordinal : ordinal;
weak_import = ((ival >> 8) & 1) == 1;
name_offset = (ival >> 9 & 0x7fffff);
break;
}
case DYLD_CHAINED_IMPORT_ADDEND: {
int ival = reader.readNextInt();
- lib_ordinal = ival & 0xff;
+ int ordinal = ival & 0xff;
+ lib_ordinal = ordinal > 0xf0 ? (byte) ordinal : ordinal;
weak_import = ((ival >> 8) & 1) == 1;
name_offset = (ival >> 9 & 0x7fffff);
addend = reader.readNextInt();
@@ -62,7 +64,8 @@ public class DyldChainedImport implements StructConverter {
}
case DYLD_CHAINED_IMPORT_ADDEND64: {
long ival = reader.readNextLong();
- lib_ordinal = (int) (ival & 0xffff);
+ int ordinal = (int) (ival & 0xffff);
+ lib_ordinal = ordinal > 0xfff0 ? (short) ordinal : ordinal;
weak_import = ((ival >> 16) & 1) == 1;
name_offset = ((ival >> 32) & 0xffffffffL);
addend = reader.readNextLong();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo4.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo4.java
index 362e08d2b3..fb60e86291 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo4.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfo4.java
@@ -207,7 +207,7 @@ public class DyldCacheSlideInfo4 extends DyldCacheSlideInfoCommon {
chainValue += valueAdd /* + slide */;
}
- fixups.add(new DyldFixup(dataOffset, chainValue, 4, null, null));
+ fixups.add(new DyldFixup(dataOffset, Long.valueOf(chainValue), 4, null, null));
}
return fixups;
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
index 84427ee984..85dbee0e00 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheSlideInfoCommon.java
@@ -173,7 +173,7 @@ public abstract class DyldCacheSlideInfoCommon implements StructConverter {
memory.setLong(addr, fixup.value());
}
else {
- memory.setInt(addr, (int) fixup.value());
+ memory.setInt(addr, fixup.value().intValue());
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldFixup.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldFixup.java
index 30543d40e6..a1843b9eaf 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldFixup.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldFixup.java
@@ -19,9 +19,9 @@ package ghidra.app.util.bin.format.macho.dyld;
* Stores information needed to perform a dyld pointer fixup
*
* @param offset The offset of where to perform the fixup (from some base address/index)
- * @param value The fixed up value
+ * @param value The fixed up value, or {@code null} if this fixup is unsupported
* @param size The size of the fixup in bytes
* @param symbol The symbol associated with the fixup (could be null)
* @param libOrdinal The library ordinal associated with the fixup (could be null)
*/
-public record DyldFixup(long offset, long value, int size, String symbol, Integer libOrdinal) {}
+public record DyldFixup(long offset, Long value, int size, String symbol, Integer libOrdinal) {}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java
index 2c4da7f172..509aa8cf91 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java
@@ -684,17 +684,14 @@ public class MachoProgramBuilder {
monitor.increment();
int symbolIndex = indirectSymbols.get(i);
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
- if (symbol != null) {
- String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
- if (name != null && name.length() > 0) {
- Function stubFunc = createOneByteFunction(name, startAddr);
- if (stubFunc != null) {
- ExternalLocation loc = program.getExternalManager()
- .addExtLocation(Library.UNKNOWN, name, null,
- SourceType.IMPORTED);
- stubFunc.setThunkedFunction(loc.createFunction());
- }
- }
+ String name =
+ symbol != null ? SymbolUtilities.replaceInvalidChars(symbol.getString(), true)
+ : "STUB_" + startAddr;
+ Function stubFunc = createOneByteFunction(name, startAddr);
+ if (stubFunc != null && symbol != null) {
+ ExternalLocation loc = program.getExternalManager()
+ .addExtLocation(Library.UNKNOWN, name, null, SourceType.IMPORTED);
+ stubFunc.setThunkedFunction(loc.createFunction());
}
startAddr = startAddr.add(symbolSize);
@@ -1283,7 +1280,8 @@ public class MachoProgramBuilder {
String libraryPath = null;
- if (command instanceof DynamicLibraryCommand dylibCommand) {
+ if (command instanceof DynamicLibraryCommand dylibCommand &&
+ dylibCommand.getCommandType() != LoadCommandTypes.LC_ID_DYLIB) {
DynamicLibrary dylib = dylibCommand.getDynamicLibrary();
libraryPath = dylib.getName().getString();
}
@@ -1861,6 +1859,15 @@ public class MachoProgramBuilder {
*/
public static void fixupExternalLibrary(Program program, List libraryPaths,
int libraryOrdinal, String symbol) throws Exception {
+
+ switch (libraryOrdinal) {
+ case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_SELF:
+ case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
+ case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
+ case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_WEAK_LOOKUP:
+ return;
+ }
+
ExternalManager extManager = program.getExternalManager();
int libraryIndex = libraryOrdinal - 1;
if (libraryIndex < 0 || libraryIndex >= libraryPaths.size()) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ExternalSymbolResolver.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ExternalSymbolResolver.java
index 296326cdea..3e75775ab8 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ExternalSymbolResolver.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ExternalSymbolResolver.java
@@ -4,9 +4,9 @@
* 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.
@@ -52,6 +52,46 @@ public class ExternalSymbolResolver implements Closeable {
StringUtilities.pad("" + libraryIndex, ' ', 4));
}
+ /**
+ * Returns an ordered list of library names, as specified by the logic/rules of the original
+ * operating system's loader (eg. Elf / MachO dynamic library loading / symbol resolving
+ * rules)
+ *
+ * @param program The {@link Program}
+ * @return list of library names, in original order
+ */
+ public static List getOrderedRequiredLibraryNames(Program program) {
+ TreeMap orderLibraryMap = new TreeMap<>();
+ Options options = program.getOptions(Program.PROGRAM_INFO);
+ for (String optionName : options.getOptionNames()) {
+
+ // Legacy programs may have the old "ELF Required Library [" program property, so
+ // we should not assume that the option name starts exactly with
+ // REQUIRED_LIBRARY_PROPERTY_PREFIX. We must deal with a potential substring at the
+ // start of the option name.
+ int prefixIndex = optionName.indexOf(REQUIRED_LIBRARY_PROPERTY_PREFIX);
+ if (prefixIndex == -1 || !optionName.endsWith("]")) {
+ continue;
+ }
+ String libName = options.getString(optionName, null);
+ if (libName == null) {
+ continue;
+ }
+ String indexStr = optionName
+ .substring(prefixIndex + REQUIRED_LIBRARY_PROPERTY_PREFIX.length(),
+ optionName.length() - 1)
+ .trim();
+ try {
+ orderLibraryMap.put(Integer.parseInt(indexStr), libName.trim());
+ }
+ catch (NumberFormatException e) {
+ Msg.error(ExternalSymbolResolver.class,
+ "Program contains invalid property: " + optionName);
+ }
+ }
+ return new ArrayList<>(orderLibraryMap.values());
+ }
+
private final ProjectData projectData;
private final TaskMonitor monitor;
private final List programsToFix = new ArrayList<>();
@@ -333,7 +373,7 @@ public class ExternalSymbolResolver implements Closeable {
private List getLibsToSearch() throws CancelledException {
List result = new ArrayList<>();
ExternalManager externalManager = program.getExternalManager();
- for (String libName : getOrderedRequiredLibraryNames()) {
+ for (String libName : getOrderedRequiredLibraryNames(program)) {
Library lib = externalManager.getExternalLibrary(libName);
String libPath = lib != null ? lib.getAssociatedProgramPath() : null;
Program libProg = libPath != null ? getLibraryProgram(libPath) : null;
@@ -409,46 +449,6 @@ public class ExternalSymbolResolver implements Closeable {
}
return symbolIds;
}
-
- /**
- * Returns an ordered list of library names, as specified by the logic/rules of the original
- * operating system's loader (eg. Elf / MachO dynamic library loading / symbol resolving
- * rules)
- *
- * @return list of library names, in original order
- */
- private Collection getOrderedRequiredLibraryNames() {
- TreeMap orderLibraryMap = new TreeMap<>();
- Options options = program.getOptions(Program.PROGRAM_INFO);
- for (String optionName : options.getOptionNames()) {
-
- // Legacy programs may have the old "ELF Required Library [" program property, so
- // we should not assume that the option name starts exactly with
- // REQUIRED_LIBRARY_PROPERTY_PREFIX. We must deal with a potential substring at the
- // start of the option name.
- int prefixIndex = optionName.indexOf(REQUIRED_LIBRARY_PROPERTY_PREFIX);
- if (prefixIndex == -1 || !optionName.endsWith("]")) {
- continue;
- }
- String libName = options.getString(optionName, null);
- if (libName == null) {
- continue;
- }
- String indexStr = optionName
- .substring(prefixIndex + REQUIRED_LIBRARY_PROPERTY_PREFIX.length(),
- optionName.length() - 1)
- .trim();
- try {
- orderLibraryMap.put(Integer.parseInt(indexStr), libName.trim());
- }
- catch (NumberFormatException e) {
- Msg.error(ExternalSymbolResolver.class,
- "Program contains invalid property: " + optionName);
- }
- }
- return orderLibraryMap.values();
- }
-
}
/**
diff --git a/GhidraDocs/GhidraClass/Debugger/A2-UITour.html b/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
index 63e0f8913d..5cb1debdfe 100644
--- a/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
+++ b/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
@@ -352,9 +352,9 @@ id="the-listings-are-not-in-sync-i.e.-they-do-not-move-together."
class="level3">
The listings are not in sync, i.e., they do not move together.
First, check that synchronization is enabled. This is the default
-behavior, but, still, check it first. In the top-right of the Dynamic
-Listing is its local drop-down menu. Click it and check that
-Auto-Sync Cursor with Static Listing is selected.
+behavior, but, still, check it first. In the Debugger →
+Synchronization menu, check that Synchronize Static and
+Dynamic Locations is selected.
If that does not work, check the top-left label of the Dynamic
Listing to see what module you are in. Also check the Debug Console
window. If you are in a system library, e.g., ld-linux
,
diff --git a/GhidraDocs/GhidraClass/Debugger/A2-UITour.md b/GhidraDocs/GhidraClass/Debugger/A2-UITour.md
index 24d1bdd013..6efd4f0871 100644
--- a/GhidraDocs/GhidraClass/Debugger/A2-UITour.md
+++ b/GhidraDocs/GhidraClass/Debugger/A2-UITour.md
@@ -167,8 +167,7 @@ The re-use of connections and/or the use of multiple concurrent connections is *
First, check that synchronization is enabled.
This is the default behavior, but, still, check it first.
-In the top-right of the Dynamic Listing is its local drop-down menu.
-Click it and check that **Auto-Sync Cursor with Static Listing** is selected.
+In the **Debugger → Synchronization** menu, check that **Synchronize Static and Dynamic Locations** is selected.
If that does not work, check the top-left label of the Dynamic Listing to see what module you are in.
Also check the Debug Console window.
diff --git a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.html b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.html
index 954e3b8211..8d514d35c7 100644
--- a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.html
+++ b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.html
@@ -162,8 +162,7 @@ src="images/breakpoint-enable.png" alt="set breakpoint" /> Set
Breakpoint, press K
on the keyboard, or
double-click the margin.
From the Breakpoints window, use the Set Breakpoint
-dropdown to access the various breakpoint actions defined by
-GDB.
+dropdown to access the various breakpoint actions defined by GDB.
From the Terminal window, use the GDB command, e.g.,
break main
.
diff --git a/GhidraDocs/GhidraClass/Debugger/A5-Navigation.html b/GhidraDocs/GhidraClass/Debugger/A5-Navigation.html
index 9a149b9e11..ce1a2751a3 100644
--- a/GhidraDocs/GhidraClass/Debugger/A5-Navigation.html
+++ b/GhidraDocs/GhidraClass/Debugger/A5-Navigation.html
@@ -239,11 +239,11 @@ caused the target to break. This only applies to snapshots that were
created because of an event, which is most.
The PC column gives the address of the next
instruction.
+The Module column gives the name of the module
+containing the PC.
The Function column gives the name of the function
containing the PC mapped to its static program database, if
available.
-The Module column gives the name of the module
-containing the PC.
The Description column describes the event that
generated the snapshot. This can be edited in the table, or by pressing
CTRL
-SHIFT
-N
to
diff --git a/GhidraDocs/GhidraClass/Debugger/A5-Navigation.md b/GhidraDocs/GhidraClass/Debugger/A5-Navigation.md
index b842ddb110..e81c74c81f 100644
--- a/GhidraDocs/GhidraClass/Debugger/A5-Navigation.md
+++ b/GhidraDocs/GhidraClass/Debugger/A5-Navigation.md
@@ -128,8 +128,8 @@ The columns are:
* The **Event Thread** column indicates which thread caused the target to break.
This only applies to snapshots that were created because of an event, which is most.
* The **PC** column gives the address of the next instruction.
-* The **Function** column gives the name of the function containing the PC mapped to its static program database, if available.
* The **Module** column gives the name of the module containing the PC.
+* The **Function** column gives the name of the function containing the PC mapped to its static program database, if available.
* The **Description** column describes the event that generated the snapshot.
This can be edited in the table, or by pressing **`CTRL`-`SHIFT`-`N`** to mark interesting snapshots.
diff --git a/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.html b/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.html
index c35e1f8d6e..9b3e65a298 100644
--- a/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.html
+++ b/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.html
@@ -55,9 +55,9 @@ Mappings
Moving Knowledge from
Dynamic to Static
-Exercise: Export and Map
-ncurses
+Exercise: Export
+and Map system-supplied DSO
Exercise: Cheat Like the
Devs
@@ -276,7 +276,7 @@ anyway.
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
+not change any addresses, lest you corrupt references in the
copy.
Click Copy.
When prompted, name the program libncurses
.
@@ -296,8 +296,9 @@ libncurses.
Check the proposed mapping and click OK.
-
-Exercise: Export and Map ncurses
+
+Exercise: Export and Map system-supplied DSO
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 Import From File System.
diff --git a/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.md b/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.md
index a3347d8e58..92fc2844e2 100644
--- a/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.md
+++ b/GhidraDocs/GhidraClass/Debugger/A6-MemoryMap.md
@@ -144,7 +144,7 @@ For demonstration, we will walk through this second case, pretending we cannot l
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.
+ Do not change any addresses, lest you corrupt references in the 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.
@@ -157,7 +157,7 @@ Undoubtedly, we would like to map that new program into our dynamic session.
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`
+## Exercise: Export and Map `system-supplied DSO`
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 **Import From File System**.