以下是利用Ghidra 10.1的API编写的脚本,实现对带有调试信息的二进制文件进行函数信息抽取,并生成三元组(函数名,hasVariable,变量名)的JSON文件。
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceManager;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
public class Main00 extends GhidraScript {
@Override
public void run() throws Exception {
// Create JSON root object and triples array
JsonObject root = new JsonObject();
JsonArray triples = new JsonArray();
// Get function manager, symbol table, and reference manager
FunctionManager functionManager = currentProgram.getFunctionManager();
SymbolTable symbolTable = currentProgram.getSymbolTable();
ReferenceManager referenceManager = currentProgram.getReferenceManager();
// Iterate over all global functions
for (Function function : functionManager.getFunctions(true)) {
String functionName = function.getName();
Address entryAddress = function.getEntryPoint();
// Triple 1: Function entity (name)
JsonObject triple1 = new JsonObject();
triple1.addProperty("functionName", functionName);
triple1.addProperty("hasVariable", true); // Assuming every function has a variable
triples.add(triple1);
// Triple 2: Function relation (caller -> callee)
for (Reference reference : referenceManager.getReferencesTo(entryAddress)) {
if (!reference.isMemoryReference()) continue; // Only consider memory references
Address callerAddress = reference.getFromAddress();
String callerName = getSymbolName(symbolTable, callerAddress);
String calleeName = functionName;
JsonObject triple2 = new JsonObject();
triple2.addProperty("caller", callerName);
triple2.addProperty("callee", calleeName);
triples.add(triple2);
}
// Triple 3: Parameter entity (name)
for (Parameter parameter : function.getParameters()) {
String parameterName = parameter.getName();
JsonObject triple3 = new JsonObject();
triple3.addProperty("parameterName", parameterName);
triples.add(triple3);
}
// Triple 4: Variable entity (name, type)
for (Variable variable : function.getLocalVariables()) {
String variableName = variable.getName();
DataType dataType = variable.getDataType().getDataType();
JsonObject triple4 = new JsonObject();
triple4.addProperty("variableName", variableName);
triple4.addProperty("dataType", dataType.toString());
triples.add(triple4);
// Triple 5: Variable relation (reference type -> reference address)
for (Reference reference : referenceManager.getReferencesTo(variable)) {
if (!reference.isMemoryReference()) continue; // Only consider memory references
int refType = reference.getReferenceType();
Address refAddress = reference.getFromAddress();
JsonObject triple5 = new JsonObject();
triple5.addProperty("refType", refTypeToString(refType));
triple5.addProperty("refAddress", refAddress.toString());
triples.add(triple5);
}
}
// Triple 6: Instruction entity (address, mnemonic)
Listing listing = currentProgram.getListing();
CodeUnitIterator instructionIter =
listing.getCodeUnits(function.getBody(), true);
while (instructionIter.hasNext()) {
CodeUnit codeUnit= instructionIter.next();
if(!codeUnit.getMnemonicString().equals("")){
Address instAddr= codeUnit.getAddress();
String instMnemonic= codeUnit.getMnemonicString();
JsonObject triple6 = new JsonObject();
triple6.addProperty("instAddress", instAddr.toString());
triple6.addProperty("instMnemonic", instMnemonic);
triples.add(triple6);
}
}
}
// Add triples array to root object
root.add("triples", triples);
// Convert JSON object to string
Gson gson = new Gson();
String jsonString = gson.toJson(root);
// Write JSON string to output.json file
writeFile("output.json", jsonString);
}
private String getSymbolName(SymbolTable symbolTable, Address address) {
Symbol symbol = symbolTable.getPrimarySymbol(address);
if (symbol != null && !symbol.getName().isEmpty()) {
return symbol.getName();
}
return address.toString();
}
private String refTypeToString(int refType) {
switch (refType) {
case Reference.MEMORY_READ:
return "READ";
case Reference.MEMORY_WRITE:
return "WRITE";
case Reference.MEMORY_READ_WRITE:
return "READ_WRITE";
default:
return "UNKNOWN";
}
}
}
请在Ghidra中创建一个新的脚本,并将上述代码复制到脚本编辑器中。然后,通过运行按钮或菜单选项执行该脚本。
这个脚本会生成一个名为output.json的JSON文件,包含提取的函数信息和变量信息的三元组数据。
请确保你使用Ghidra 10.1版本并正确配置了相关环境。根据需要可能需要进行一些修改来适应你具体的需求。
希望对你有所帮助!如有任何问题,请随时提问。
内容由零声教学AI助手提供,问题来源于学员提问




