mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 07:31:43 +08:00
GP-5102: Fix NPE when TraceModule.getBase() is null during mapping.
This commit is contained in:
+7
-5
@@ -26,8 +26,7 @@ import ghidra.app.plugin.core.debug.utils.ProgramURLUtils;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.AddressRangeImpl;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
|
||||
@@ -73,8 +72,7 @@ public class ProgramModuleIndexer implements DomainFolderChangeListener {
|
||||
// TODO: Note language and prefer those from the same processor?
|
||||
// Will get difficult with new OBTR, since I'd need a platform
|
||||
// There's also the WoW64 issue....
|
||||
protected record IndexEntry(String name, String dfID, NameSource source) {
|
||||
}
|
||||
protected record IndexEntry(String name, String dfID, NameSource source) {}
|
||||
|
||||
protected class ModuleChangeListener
|
||||
implements DomainObjectListener, DomainObjectClosedListener {
|
||||
@@ -383,7 +381,11 @@ public class ProgramModuleIndexer implements DomainFolderChangeListener {
|
||||
|
||||
public DomainFile getBestMatch(TraceModule module, Program currentProgram,
|
||||
Collection<IndexEntry> entries) {
|
||||
return getBestMatch(module.getBase().getAddressSpace(), module, currentProgram, entries);
|
||||
Address base = module.getBase();
|
||||
AddressSpace space = base == null
|
||||
? module.getTrace().getBaseAddressFactory().getDefaultAddressSpace()
|
||||
: base.getAddressSpace();
|
||||
return getBestMatch(space, module, currentProgram, entries);
|
||||
}
|
||||
|
||||
public List<IndexEntry> getBestEntries(TraceModule module) {
|
||||
|
||||
+29
-27
@@ -69,32 +69,7 @@ import ghidra.util.table.GhidraTable;
|
||||
@Category(NightlyCategory.class)
|
||||
public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
|
||||
DebuggerModulesProvider provider;
|
||||
|
||||
protected TraceObjectModule modExe;
|
||||
protected TraceObjectSection secExeText;
|
||||
protected TraceObjectSection secExeData;
|
||||
|
||||
protected TraceObjectModule modLib;
|
||||
protected TraceObjectSection secLibText;
|
||||
protected TraceObjectSection secLibData;
|
||||
|
||||
protected SchemaContext ctx;
|
||||
|
||||
@Override
|
||||
protected void createTrace(String langID) throws IOException {
|
||||
super.createTrace(langID);
|
||||
try {
|
||||
activateObjectsMode();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void activateObjectsMode() throws Exception {
|
||||
// NOTE the use of index='1' allowing object-based managers to ID unique path
|
||||
ctx = XmlSchemaContext.deserialize("""
|
||||
public static final String CTX_XML = """
|
||||
<context>
|
||||
<schema name='Session' elementResync='NEVER' attributeResync='ONCE'>
|
||||
<attribute name='Processes' schema='ProcessContainer' />
|
||||
@@ -129,7 +104,34 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
|
||||
<schema name='Section' elementResync='NEVER' attributeResync='NEVER'>
|
||||
<interface name='Section' />
|
||||
</schema>
|
||||
</context>""");
|
||||
</context>""";
|
||||
|
||||
DebuggerModulesProvider provider;
|
||||
|
||||
protected TraceObjectModule modExe;
|
||||
protected TraceObjectSection secExeText;
|
||||
protected TraceObjectSection secExeData;
|
||||
|
||||
protected TraceObjectModule modLib;
|
||||
protected TraceObjectSection secLibText;
|
||||
protected TraceObjectSection secLibData;
|
||||
|
||||
protected SchemaContext ctx;
|
||||
|
||||
@Override
|
||||
protected void createTrace(String langID) throws IOException {
|
||||
super.createTrace(langID);
|
||||
try {
|
||||
activateObjectsMode();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void activateObjectsMode() throws Exception {
|
||||
// NOTE the use of index='1' allowing object-based managers to ID unique path
|
||||
ctx = XmlSchemaContext.deserialize(CTX_XML);
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(ctx.getSchema(new SchemaName("Session")));
|
||||
|
||||
+25
@@ -25,18 +25,26 @@ import org.junit.Test;
|
||||
|
||||
import db.Transaction;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerTest;
|
||||
import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProviderTest;
|
||||
import ghidra.app.services.DebuggerStaticMappingService;
|
||||
import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange;
|
||||
import ghidra.dbg.target.schema.SchemaContext;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName;
|
||||
import ghidra.dbg.target.schema.XmlSchemaContext;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.database.target.DBTraceObject;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.target.TraceObjectKeyPath;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
// Not technically a GUI test, but must be carried out in the context of a plugin tool
|
||||
@@ -667,4 +675,21 @@ public class DebuggerStaticMappingServiceTest extends AbstractGhidraHeadedDebugg
|
||||
assertMapsTwoWay(Long.MAX_VALUE, Long.MAX_VALUE);
|
||||
assertMapsTwoWay(Long.MIN_VALUE, Long.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProposeModuleMappingNullBase() throws Throwable {
|
||||
DBTraceObject objModBash;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
SchemaContext ctx = XmlSchemaContext.deserialize(DebuggerModulesProviderTest.CTX_XML);
|
||||
DBTraceObjectManager objects = tb.trace.getObjectManager();
|
||||
objects.createRootObject(ctx.getSchema(new SchemaName("Session")));
|
||||
objModBash =
|
||||
objects.createObject(TraceObjectKeyPath.parse("Processes[1].Modules[/bin/bash]"));
|
||||
objModBash.insert(Lifespan.nowOn(0), ConflictResolution.DENY);
|
||||
}
|
||||
|
||||
TraceModule modBash = objModBash.queryInterface(TraceObjectModule.class);
|
||||
assertEquals(Map.of(),
|
||||
mappingService.proposeModuleMaps(List.of(modBash), List.of(program)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user