Created
May 7, 2023 20:05
-
-
Save gsuberland/40b14cfe24cb82ffbc9d59924246b988 to your computer and use it in GitHub Desktop.
Ghidra script to cluster functions by their function ID, applying tags to functions in clusters of size >1. Helps identify functions that have identical or very similar behaviour.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Clusters functions by their function ID and applies tags to functions in clusters with a size larger than 1. | |
//@category FunctionID | |
//@author Graham Sutherland | |
import java.io.IOException; | |
import java.util.*; | |
import ghidra.app.script.GhidraScript; | |
import ghidra.feature.fid.hash.FidHashQuad; | |
import ghidra.feature.fid.plugin.HashLookupListMode; | |
import ghidra.feature.fid.service.FidService; | |
import ghidra.framework.model.DomainFile; | |
import ghidra.framework.model.DomainFolder; | |
import ghidra.program.database.ProgramContentHandler; | |
import ghidra.program.model.listing.*; | |
import ghidra.util.Msg; | |
import ghidra.util.NumericUtilities; | |
import ghidra.util.exception.CancelledException; | |
import ghidra.util.exception.VersionException; | |
public class ClusterFunctionsByFID extends GhidraScript | |
{ | |
FidService service; | |
@Override | |
protected void run() throws Exception | |
{ | |
println("Finding hashes..."); | |
service = new FidService(); | |
FunctionManager functionManager = currentProgram.getFunctionManager(); | |
FunctionIterator functions = functionManager.getFunctions(true); | |
Map<Long, ArrayList<Function>> fbh = new HashMap<Long, ArrayList<Function>>(); | |
for (Function function : functions) | |
{ | |
if (monitor.isCancelled()) | |
{ | |
return; | |
} | |
FidHashQuad hashQuad = service.hashFunction(function); | |
if (hashQuad == null) | |
{ | |
continue; | |
} | |
long hash = hashQuad.getFullHash(); | |
fbh.putIfAbsent(hash, new ArrayList<Function>()); | |
fbh.get(hash).add(function); | |
} | |
for (Map.Entry<Long, ArrayList<Function>> entry : fbh.entrySet()) | |
{ | |
ArrayList<Function> cluster = entry.getValue(); | |
if (cluster.size() > 1) | |
{ | |
// List<String> functionNames = new List<String>(); | |
printf("%x", entry.getKey()); | |
print(": "); | |
for (int i = 0; i < cluster.size(); i++) | |
{ | |
Function f = cluster.get(i); | |
print(f.getName() + " "); | |
f.addTag("fid_" + Long.toHexString(entry.getKey())); | |
} | |
print("\n"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment