Skip to content

Instantly share code, notes, and snippets.

@gsuberland
Created May 7, 2023 20:05
Show Gist options
  • Save gsuberland/40b14cfe24cb82ffbc9d59924246b988 to your computer and use it in GitHub Desktop.
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.
// 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