GP-6309 Refactor SequenceSearchState into BulkPatternSearcher

This commit is contained in:
ghidragon
2026-01-13 13:44:39 -05:00
parent 45252a5b15
commit e1e10c27b7
29 changed files with 1156 additions and 697 deletions

View File

@@ -30,31 +30,35 @@ import ghidra.util.constraint.ProgramDecisionTree;
public class DumpMissedStarts extends GhidraScript implements PatternFactory {
private static int bufsize = 20;
private DummyMatchAction dummyaction;
private SequenceSearchState root;
private BulkPatternSearcher<Pattern> patternSearcher;
private Memory memory;
private byte[] bytebuffer;
ArrayList<Match> matchlist;
ArrayList<Match<Pattern>> matchlist;
private boolean functionMatchesPattern(byte[] buff, int numbytes) {
private boolean functionMatchesPattern(byte[] buff, int numBytes) {
matchlist.clear();
root.sequenceMatch(buff, numbytes, matchlist);
if (matchlist.size() > 0)
patternSearcher.matches(buff, numBytes, matchlist);
if (matchlist.size() > 0) {
return true;
}
return false;
}
private boolean detectThunk(Function func, CodeUnit cu) {
if (cu == null)
if (cu == null) {
return true;
if (cu instanceof Data)
}
if (cu instanceof Data) {
return true;
}
return false;
}
private void writeBytes(Writer w, byte[] buffer, int numbytes) throws IOException {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < numbytes; ++i)
for (int i = 0; i < numbytes; ++i) {
buf.append(Integer.toHexString(buffer[i] & 0xff)).append(' ');
}
buf.append('\n');
w.write(buf.toString());
}
@@ -71,18 +75,20 @@ public class DumpMissedStarts extends GhidraScript implements PatternFactory {
ProgramDecisionTree patternDecisionTree = Patterns.getPatternDecisionTree();
ResourceFile[] fileList = Patterns.findPatternFiles(currentProgram, patternDecisionTree);
ArrayList<Pattern> patternlist = new ArrayList<>();
for (int i = 0; i < fileList.length; ++i)
for (int i = 0; i < fileList.length; ++i) {
Pattern.readPostPatterns(fileList[i].getFile(true), patternlist, this);
}
FileWriter fileWriter = new FileWriter(file);
root = SequenceSearchState.buildStateMachine(patternlist);
patternSearcher = new BulkPatternSearcher<>(patternlist);
FunctionManager functionManager = currentProgram.getFunctionManager();
FunctionIterator iter = functionManager.getFunctions(true);
while (iter.hasNext()) {
Function func = iter.next();
CodeUnit cu = listing.getCodeUnitAt(func.getEntryPoint());
if (detectThunk(func, cu))
if (detectThunk(func, cu)) {
continue;
}
int numbytes = memory.getBytes(func.getEntryPoint(), bytebuffer);
if ((numbytes > 0) && (!functionMatchesPattern(bytebuffer, numbytes))) {
writeBytes(fileWriter, bytebuffer, numbytes);
@@ -98,8 +104,9 @@ public class DumpMissedStarts extends GhidraScript implements PatternFactory {
@Override
public PostRule getPostRuleByName(String nm) {
if (nm.equals("align"))
if (nm.equals("align")) {
return new AlignRule();
}
return null;
}

View File

@@ -52,7 +52,7 @@ public class PatternStats extends GhidraScript implements PatternFactory {
private MatchActionMarker codeBoundary = new MatchActionMarker(MatchActionMarker.CODE_BOUNDARY);
private MatchActionMarker context = new MatchActionMarker(MatchActionMarker.CONTEXT);
private SequenceSearchState<Pattern> root;
private BulkPatternSearcher<Pattern> patternSearcher;
private ArrayList<PatternAccumulate> accumList;
private FunctionManager functionManager;
private Listing listing;
@@ -76,6 +76,7 @@ public class PatternStats extends GhidraScript implements PatternFactory {
@Override
public void apply(Program program, Address addr, Match<Pattern> match) {
// do nothing
}
@Override
@@ -255,7 +256,7 @@ public class PatternStats extends GhidraScript implements PatternFactory {
if (patternlist.size() == 0) {
return;
}
root = SequenceSearchState.buildStateMachine(patternlist);
patternSearcher = new BulkPatternSearcher<>(patternlist);
accumList = new ArrayList<>();
for (int i = 0; i < patternlist.size(); ++i) {
accumList.add(new PatternAccumulate(patternlist.get(i)));
@@ -329,7 +330,7 @@ public class PatternStats extends GhidraScript implements PatternFactory {
taskMonitor.setProgress(0);
ArrayList<Match<Pattern>> mymatches = new ArrayList<>();
long streamoffset = block.getStart().getOffset();
root.apply(block.getData(), mymatches, taskMonitor);
patternSearcher.search(block.getData(), mymatches, taskMonitor);
if (taskMonitor.isCancelled()) {
return;
}