mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 03:09:36 +08:00
Merge remote-tracking branch 'origin/GP-6456_ghidra_red_ImproveTenetLoader--SQUASHED'
This commit is contained in:
+33
-10
@@ -173,7 +173,29 @@ public class TenetLoader implements Loader {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
try {
|
||||
final byte[] bytes = new byte[1000];
|
||||
provider.getInputStream(0).read(bytes);
|
||||
final String[] lines = new String(bytes, StandardCharsets.UTF_8).split("\n");
|
||||
|
||||
if (lines.length == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip last line as it could be a partial one
|
||||
for (int i = 0; i < (lines.length - 1); i++) {
|
||||
final String line = lines[i];
|
||||
if (((i != 0) && SLIDE_PATTERN.matcher(line).find()) ||
|
||||
(!SLIDE_PATTERN.matcher(line).find() && !REG_PATTERN.matcher(line).find())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (final IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +231,8 @@ public class TenetLoader implements Loader {
|
||||
final DomainObject domainObject, final boolean loadIntoProgram,
|
||||
final boolean mirrorFsLayout) {
|
||||
final List<Option> list = new ArrayList<>();
|
||||
list.add(new DomainFileOption(DOMAIN_FILE_OPTION_NAME, "", false));
|
||||
list.add(new DomainFileOption(DOMAIN_FILE_OPTION_NAME,
|
||||
COMMAND_LINE_ARG_PREFIX + "-associatedProgram", false));
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -258,7 +281,7 @@ public class TenetLoader implements Loader {
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
trace = this.loadTrace(settings.provider(), settings.importName(), program,
|
||||
trace = loadTrace(settings.provider(), settings.importName(), program,
|
||||
settings.consumer(), settings.log(), settings.monitor());
|
||||
|
||||
final long loadDone = System.currentTimeMillis();
|
||||
@@ -347,7 +370,7 @@ public class TenetLoader implements Loader {
|
||||
|
||||
snapNumber++;
|
||||
|
||||
this.setupMemoryAndMapping(program, trace, slideValue, snap);
|
||||
setupMemoryAndMapping(program, trace, slideValue, snap);
|
||||
|
||||
try {
|
||||
while (line != null) {
|
||||
@@ -376,8 +399,8 @@ public class TenetLoader implements Loader {
|
||||
}
|
||||
curIp = Long.parseLong(ipMatcher.group(1), 16);
|
||||
|
||||
if (!this.parseRegisterOperations(snap, curIp, line, lineNumber,
|
||||
traceThread, trace, log, monitor)) {
|
||||
if (!parseRegisterOperations(snap, curIp, line, lineNumber, traceThread,
|
||||
trace, log, monitor)) {
|
||||
errorCount++;
|
||||
lineNumber++;
|
||||
monitor.setProgress(lineNumber);
|
||||
@@ -391,7 +414,7 @@ public class TenetLoader implements Loader {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
this.parseMemoryOperations(snap, curIp, line, trace, monitor);
|
||||
parseMemoryOperations(snap, curIp, line, trace, monitor);
|
||||
|
||||
lineNumber++;
|
||||
monitor.setProgress(lineNumber);
|
||||
@@ -475,8 +498,9 @@ public class TenetLoader implements Loader {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setupMemoryAndMapping(final Program program, final Trace trace, final long slideValue,
|
||||
final long snap) throws DuplicateNameException, TraceOverlappedRegionException {
|
||||
private void setupMemoryAndMapping(final Program program, final Trace trace,
|
||||
final long slideValue, final long snap)
|
||||
throws DuplicateNameException, TraceOverlappedRegionException {
|
||||
final TraceModuleManager modMan = trace.getModuleManager();
|
||||
final TraceStaticMappingManager mapMan = trace.getStaticMappingManager();
|
||||
final URL projectUrl = program.getDomainFile().getLocalProjectURL("");
|
||||
@@ -522,5 +546,4 @@ public class TenetLoader implements Loader {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+123
-25
@@ -65,7 +65,7 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
|
||||
private Trace createTraceWithLoader(final String testFile) throws Exception {
|
||||
this.createProgram();
|
||||
this.intoProject(this.program);
|
||||
intoProject(program);
|
||||
|
||||
final TenetLoader loader = new TenetLoader();
|
||||
final ByteProvider provider =
|
||||
@@ -76,11 +76,11 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
loader.getDefaultOptions(provider, loadSpec, null, false, false);
|
||||
final Option programOption = Unique.assertOne(
|
||||
options.stream().filter(o -> o.getName().equals(TenetLoader.DOMAIN_FILE_OPTION_NAME)));
|
||||
programOption.setValue(this.program.getDomainFile().getPathname());
|
||||
programOption.setValue(program.getDomainFile().getPathname());
|
||||
|
||||
final MessageLog log = new MessageLog();
|
||||
final ImporterSettings settings = new ImporterSettings(provider, "test",
|
||||
this.env.getProject(), "/", false, loadSpec, options, this, log, this.monitor);
|
||||
final ImporterSettings settings = new ImporterSettings(provider, "test", env.getProject(),
|
||||
"/", false, loadSpec, options, this, log, monitor);
|
||||
|
||||
final LoadResults<? extends DomainObject> results = loader.load(settings);
|
||||
if (!(results.getPrimary().domainObject instanceof final Trace trace)) {
|
||||
@@ -99,11 +99,54 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
public void testBadRegisterNames() throws Exception {
|
||||
final String testFile = """
|
||||
pc=0x1,rax=0x1234
|
||||
pc=0x2,rax=0x1234
|
||||
pc=0x3,rax=0x1234
|
||||
pc=0x4,rax=0x1234
|
||||
pc=0x5,rax=0x1234
|
||||
pc=0x6,rax=0x1234
|
||||
pc=0x7,rax=0x1234
|
||||
pc=0x8,rax=0x1234
|
||||
pc=0x9,rax=0x1234
|
||||
pc=0xa,rax=0x1234
|
||||
""";
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
assertNotNull(trace);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the file content check for the loader
|
||||
*/
|
||||
@Test
|
||||
public void testFileContent() throws Exception {
|
||||
final String junk_line = "asdf\n";
|
||||
final String slide_line = "slide=0x0\n";
|
||||
final String reg_line = "pc=0x1,r0=0x1234\n";
|
||||
|
||||
this.createProgram();
|
||||
intoProject(program);
|
||||
|
||||
final TenetLoader loader = new TenetLoader();
|
||||
|
||||
ByteProvider provider = new ByteArrayProvider("test.tenet", (junk_line).getBytes("utf-8"));
|
||||
assertEquals(0, loader.findSupportedLoadSpecs(provider).size());
|
||||
|
||||
provider = new ByteArrayProvider("test.tenet", (slide_line + junk_line).getBytes("utf-8"));
|
||||
assertEquals(0, loader.findSupportedLoadSpecs(provider).size());
|
||||
|
||||
provider = new ByteArrayProvider("test.tenet", (reg_line + junk_line).getBytes("utf-8"));
|
||||
assertEquals(0, loader.findSupportedLoadSpecs(provider).size());
|
||||
|
||||
provider = new ByteArrayProvider("test.tenet",
|
||||
(reg_line + slide_line + reg_line.repeat(TenetLoader.ERROR_THRESHOLD))
|
||||
.getBytes("utf-8"));
|
||||
assertEquals(0, loader.findSupportedLoadSpecs(provider).size());
|
||||
|
||||
provider = new ByteArrayProvider("test.tenet",
|
||||
(slide_line + reg_line.repeat(TenetLoader.ERROR_THRESHOLD - 2) + junk_line)
|
||||
.getBytes("utf-8"));
|
||||
assertEquals(0, loader.findSupportedLoadSpecs(provider).size());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the filename check for the loader
|
||||
*/
|
||||
@@ -113,10 +156,18 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
slide=0x0
|
||||
pc=0x1,r0=0x1234
|
||||
pc=0x2,r1=0x4321
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
this.createProgram();
|
||||
this.intoProject(this.program);
|
||||
intoProject(program);
|
||||
|
||||
final TenetLoader loader = new TenetLoader();
|
||||
|
||||
@@ -139,18 +190,26 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
slide=0x0
|
||||
pc=0x1,r0=0x1234
|
||||
pc=0x2,r1=0x4321
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
addPlugin(this.tool, DebuggerRegistersPlugin.class);
|
||||
addPlugin(this.tool, DebuggerModelPlugin.class);
|
||||
addPlugin(this.tool, DebuggerThreadsPlugin.class);
|
||||
addPlugin(this.tool, DebuggerListingPlugin.class);
|
||||
addPlugin(this.tool, DebuggerTimePlugin.class);
|
||||
addPlugin(tool, DebuggerRegistersPlugin.class);
|
||||
addPlugin(tool, DebuggerModelPlugin.class);
|
||||
addPlugin(tool, DebuggerThreadsPlugin.class);
|
||||
addPlugin(tool, DebuggerListingPlugin.class);
|
||||
addPlugin(tool, DebuggerTimePlugin.class);
|
||||
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
|
||||
this.traceManager.openTrace(trace);
|
||||
this.traceManager.activateTrace(trace);
|
||||
traceManager.openTrace(trace);
|
||||
traceManager.activateTrace(trace);
|
||||
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
@@ -163,7 +222,7 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
public void testManyLinesBadRegisterNames() throws Exception {
|
||||
// Should fail after 10 lines with bad registers
|
||||
final String badTestFile = "pc=0x1,rax=0x1234\n".repeat(TenetLoader.ERROR_THRESHOLD + 1);
|
||||
assertThrows(LoadException.class, () -> this.createTraceWithLoader(badTestFile));
|
||||
assertThrows(LoadException.class, () -> createTraceWithLoader(badTestFile));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -174,7 +233,7 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
public void testManyLinesNoPc() throws Exception {
|
||||
// Should fail after {@TenetLoader.ERROR_THRESHOLD} lines with no PC
|
||||
final String badTestFile = "r1=0x1234\n".repeat(TenetLoader.ERROR_THRESHOLD + 1);
|
||||
assertThrows(LoadException.class, () -> this.createTraceWithLoader(badTestFile));
|
||||
assertThrows(LoadException.class, () -> createTraceWithLoader(badTestFile));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -186,9 +245,16 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
pc=0x1,r0=0x1234,mr=0x1000:0000000000001337
|
||||
pc=0x2,r1=0x4321,mw=0x2000:deadbeefdeadbeef
|
||||
pc=0x3,mw=0x1000:87654321,mr=0x2000:c0ffee
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
|
||||
final AddressSpace addrSpace =
|
||||
trace.getBaseLanguage().getAddressFactory().getDefaultAddressSpace();
|
||||
@@ -219,8 +285,16 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
final String testFile = """
|
||||
pc=0x1,r1=0x1234
|
||||
r2=0x1234
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
assertNotNull(trace);
|
||||
}
|
||||
|
||||
@@ -232,13 +306,21 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
final String testFile = """
|
||||
pc=0x1,r0=0x1234
|
||||
pc=0x2,r1=0x4321
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
|
||||
final TraceStaticMapping staticMapping =
|
||||
Unique.assertOne(trace.getStaticMappingManager().getAllEntries());
|
||||
assertEquals(this.program.getImageBase().getUnsignedOffset(),
|
||||
assertEquals(program.getImageBase().getUnsignedOffset(),
|
||||
staticMapping.getMinTraceAddress().getUnsignedOffset());
|
||||
}
|
||||
|
||||
@@ -251,9 +333,17 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
slide=0x0
|
||||
pc=0x1,r0=0x1234
|
||||
pc=0x2,r1=0x4321
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
|
||||
final TraceThread thread = Unique.assertOne(trace.getThreadManager().getAllThreads());
|
||||
final TraceMemorySpace regs =
|
||||
@@ -261,12 +351,12 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
|
||||
assertNotNull(regs);
|
||||
assertEquals("1",
|
||||
regs.getValue(0, this.program.getLanguage().getProgramCounter())
|
||||
regs.getValue(0, program.getLanguage().getProgramCounter())
|
||||
.getUnsignedValue()
|
||||
.toString(16));
|
||||
|
||||
assertEquals("2",
|
||||
regs.getValue(1, this.program.getLanguage().getProgramCounter())
|
||||
regs.getValue(1, program.getLanguage().getProgramCounter())
|
||||
.getUnsignedValue()
|
||||
.toString(16));
|
||||
|
||||
@@ -281,13 +371,21 @@ public class TenetLoaderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
slide=0x10000
|
||||
pc=0x1,r0=0x1234
|
||||
pc=0x2,r1=0x4321
|
||||
pc=0x3,r1=0x4321
|
||||
pc=0x4,r1=0x4321
|
||||
pc=0x5,r1=0x4321
|
||||
pc=0x6,r1=0x4321
|
||||
pc=0x7,r1=0x4321
|
||||
pc=0x8,r1=0x4321
|
||||
pc=0x9,r1=0x4321
|
||||
pc=0xa,r1=0x4321
|
||||
""";
|
||||
|
||||
final Trace trace = this.createTraceWithLoader(testFile);
|
||||
final Trace trace = createTraceWithLoader(testFile);
|
||||
|
||||
final TraceStaticMapping staticMapping =
|
||||
Unique.assertOne(trace.getStaticMappingManager().getAllEntries());
|
||||
assertEquals(this.program.getImageBase().getUnsignedOffset() + 0x10000,
|
||||
assertEquals(program.getImageBase().getUnsignedOffset() + 0x10000,
|
||||
staticMapping.getMinTraceAddress().getUnsignedOffset());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user