summaryrefslogtreecommitdiffstats
path: root/tools/ghidra/gsp-fwimage-570.144/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ghidra/gsp-fwimage-570.144/scripts')
-rw-r--r--tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java156
-rw-r--r--tools/ghidra/gsp-fwimage-570.144/scripts/DecompileFunctions.java88
-rw-r--r--tools/ghidra/gsp-fwimage-570.144/scripts/ExtractFunctions.java126
-rw-r--r--tools/ghidra/gsp-fwimage-570.144/scripts/basic_analysis.py108
4 files changed, 478 insertions, 0 deletions
diff --git a/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java b/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
new file mode 100644
index 0000000..1776ea2
--- /dev/null
+++ b/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
@@ -0,0 +1,156 @@
+// Ghidra script to do basic disassembly analysis of GSP .fwimage binary
+// Usage: analyzeHeadless ... -postScript BasicAnalysis.java
+
+import ghidra.app.script.GhidraScript;
+import ghidra.program.model.listing.*;
+import ghidra.program.model.mem.*;
+import ghidra.program.model.symbol.*;
+import ghidra.program.model.address.*;
+import ghidra.util.task.TaskMonitor;
+import java.io.*;
+import java.util.*;
+import java.nio.file.*;
+
+public class BasicAnalysis extends GhidraScript {
+
+ @Override
+ protected void run() throws Exception {
+ Program program = getCurrentProgram();
+ Listing listing = program.getListing();
+ Memory memory = program.getMemory();
+ FunctionManager functionManager = program.getFunctionManager();
+
+ println("=== GSP Firmware .fwimage Basic Analysis ===");
+ println("Program: " + program.getName());
+ println("Architecture: " + program.getLanguage().toString());
+
+ // Create output directory
+ String outputDir = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP";
+ Files.createDirectories(Paths.get(outputDir));
+
+ // 1. Check memory blocks
+ println("\n--- Memory Blocks ---");
+ List<Map<String, Object>> memBlocks = new ArrayList<>();
+ for (MemoryBlock block : memory.getBlocks()) {
+ Map<String, Object> blockInfo = new HashMap<>();
+ blockInfo.put("name", block.getName());
+ blockInfo.put("start", block.getStart().toString());
+ blockInfo.put("end", block.getEnd().toString());
+ blockInfo.put("size", block.getSize());
+ blockInfo.put("execute", block.isExecute());
+ blockInfo.put("read", block.isRead());
+ blockInfo.put("write", block.isWrite());
+ memBlocks.add(blockInfo);
+ println(" " + block.getName() + ": " + block.getStart() + " - " + block.getEnd() +
+ " (" + block.getSize() + " bytes) r=" + block.isRead() + " w=" + block.isWrite() + " x=" + block.isExecute());
+ }
+ writeJson(outputDir + "/memory_blocks.json", memBlocks);
+
+ // 2. Find all functions
+ println("\n--- Finding Functions ---");
+ List<Map<String, Object>> functions = new ArrayList<>();
+ FunctionIterator funcIter = functionManager.getFunctions(true);
+ int count = 0;
+ while (funcIter.hasNext()) {
+ Function func = funcIter.next();
+ Map<String, Object> funcInfo = new HashMap<>();
+ funcInfo.put("name", func.getName());
+ funcInfo.put("entry", func.getEntryPoint().toString());
+ funcInfo.put("size", func.getBody().getNumAddresses());
+ functions.add(funcInfo);
+ count++;
+ if (count % 1000 == 0) {
+ println(" Found " + count + " functions...");
+ }
+ }
+ println("Total functions: " + functions.size());
+ writeJson(outputDir + "/functions.json", functions);
+
+ // 3. Find strings
+ println("\n--- Finding Strings ---");
+ List<Map<String, String>> strings = new ArrayList<>();
+ DataIterator dataIter = listing.getDefinedData(true);
+ while (dataIter.hasNext()) {
+ Data data = dataIter.next();
+ if (data.getDataType().getName().equals("string")) {
+ Object value = data.getValue();
+ if (value != null && value.toString().length() > 4) {
+ Map<String, String> strInfo = new HashMap<>();
+ strInfo.put("address", data.getAddress().toString());
+ strInfo.put("value", value.toString());
+ strings.add(strInfo);
+ }
+ }
+ }
+ println("Found " + strings.size() + " strings");
+
+ // Filter for interesting strings
+ String[] interestingKeywords = {"vgpu", "vmiop", "rpc", "hal", "bar", "migrate", "init", "boot", "kgsp", "wpr", "firmware", "version", "error", "fail", "assert", "panic", "nvidia", "rmapi", "gsp", "falcon", "mailbox", "interrupt", "dma", "iommu", "page", "mmu", "pde", "pte"};
+ List<Map<String, String>> interestingStrings = new ArrayList<>();
+ for (Map<String, String> s : strings) {
+ String val = s.get("value").toLowerCase();
+ for (String kw : interestingKeywords) {
+ if (val.contains(kw)) {
+ interestingStrings.add(s);
+ break;
+ }
+ }
+ }
+ println("Interesting strings: " + interestingStrings.size());
+ writeJson(outputDir + "/interesting_strings.json", interestingStrings);
+
+ // 4. Find entry point
+ println("\n--- Entry Point Analysis ---");
+ Address entryAddr = program.getMinAddress();
+ println("Program entry (min address): " + entryAddr);
+ Function funcAtZero = functionManager.getFunctionAt(entryAddr);
+ if (funcAtZero != null) {
+ println("Function at entry: " + funcAtZero.getName());
+ } else {
+ println("No function at entry point - creating one...");
+ Function func = functionManager.createFunction("entry_point", entryAddr, null, null, monitor);
+ if (func != null) {
+ println("Created function: " + func.getName());
+ }
+ }
+
+ println("\n--- Analysis Complete ---");
+ println("Results saved to " + outputDir);
+ }
+
+ private void writeJson(String path, Object data) throws IOException {
+ StringBuilder json = new StringBuilder();
+ json.append("[\n");
+ if (data instanceof List) {
+ List<?> list = (List<?>) data;
+ for (int i = 0; i < list.size(); i++) {
+ Object item = list.get(i);
+ if (item instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) item;
+ json.append(" {");
+ int j = 0;
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ json.append("\"").append(entry.getKey()).append("\": ");
+ Object val = entry.getValue();
+ if (val instanceof String) {
+ json.append("\"").append(escapeJson(val.toString())).append("\"");
+ } else {
+ json.append(val);
+ }
+ if (j < map.size() - 1) json.append(", ");
+ j++;
+ }
+ json.append("}");
+ }
+ if (i < list.size() - 1) json.append(",");
+ json.append("\n");
+ }
+ }
+ json.append("]");
+ Files.writeString(Paths.get(path), json.toString());
+ }
+
+ private String escapeJson(String s) {
+ return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
+ }
+} \ No newline at end of file
diff --git a/tools/ghidra/gsp-fwimage-570.144/scripts/DecompileFunctions.java b/tools/ghidra/gsp-fwimage-570.144/scripts/DecompileFunctions.java
new file mode 100644
index 0000000..da522cd
--- /dev/null
+++ b/tools/ghidra/gsp-fwimage-570.144/scripts/DecompileFunctions.java
@@ -0,0 +1,88 @@
+import ghidra.app.script.GhidraScript;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.listing.Function;
+import ghidra.program.model.listing.FunctionManager;
+import ghidra.app.decompiler.DecompInterface;
+import ghidra.app.decompiler.DecompileResults;
+import ghidra.util.task.TaskMonitor;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class DecompileFunctions extends GhidraScript {
+ private static final String OUTPUT_DIR = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP/decompiled/";
+
+ @Override
+ protected void run() throws Exception {
+ File outDir = new File(OUTPUT_DIR);
+ if (!outDir.exists()) {
+ outDir.mkdirs();
+ }
+
+ String[] args = getScriptArgs();
+ if (args.length == 0) {
+ println("No addresses provided. Usage: <addr1>,<addr2>,...");
+ return;
+ }
+
+ Set<Address> targetAddresses = new HashSet<>();
+ for (String arg : args) {
+ String[] addrs = arg.split(",");
+ for (String addrStr : addrs) {
+ addrStr = addrStr.trim();
+ if (addrStr.startsWith("0x")) {
+ addrStr = addrStr.substring(2);
+ }
+ Address addr = toAddr(addrStr);
+ if (addr != null) {
+ targetAddresses.add(addr);
+ println("Target: " + addr);
+ }
+ }
+ }
+
+ FunctionManager fm = currentProgram.getFunctionManager();
+ DecompInterface decompiler = new DecompInterface();
+ decompiler.openProgram(currentProgram);
+
+ for (Address addr : targetAddresses) {
+ Function func = fm.getFunctionAt(addr);
+ if (func == null) {
+ println("No function at " + addr + ", creating...");
+ func = createFunction(addr, null);
+ }
+ if (func != null) {
+ decompileAndSave(func, decompiler);
+ } else {
+ println("Failed to create function at " + addr);
+ }
+ }
+
+ decompiler.dispose();
+ }
+
+ private void decompileAndSave(Function func, DecompInterface decompiler) throws Exception {
+ String name = func.getName();
+ Address entry = func.getEntryPoint();
+ String safeName = name.replaceAll("[^a-zA-Z0-9_]", "_");
+ File outFile = new File(OUTPUT_DIR, safeName + "_" + entry.toString().replace(":", "_") + ".c");
+
+ DecompileResults results = decompiler.decompileFunction(func, 60, TaskMonitor.DUMMY);
+ if (results.decompileCompleted()) {
+ String code = results.getDecompiledFunction().getC();
+ try (PrintWriter pw = new PrintWriter(new FileWriter(outFile))) {
+ pw.println("// Function: " + name);
+ pw.println("// Address: " + entry);
+ pw.println("// Size: " + func.getBody().getNumAddresses() + " bytes");
+ pw.println();
+ pw.print(code);
+ }
+ println("Decompiled: " + name + " @ " + entry + " -> " + outFile.getName());
+ } else {
+ println("Decompilation failed for " + name + " @ " + entry + ": " + results.getErrorMessage());
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/ghidra/gsp-fwimage-570.144/scripts/ExtractFunctions.java b/tools/ghidra/gsp-fwimage-570.144/scripts/ExtractFunctions.java
new file mode 100644
index 0000000..2296a42
--- /dev/null
+++ b/tools/ghidra/gsp-fwimage-570.144/scripts/ExtractFunctions.java
@@ -0,0 +1,126 @@
+import ghidra.app.script.GhidraScript;
+import ghidra.program.model.listing.FunctionManager;
+import ghidra.program.model.listing.Function;
+import ghidra.program.model.listing.FunctionIterator;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.listing.Program;
+import ghidra.program.model.mem.Memory;
+import ghidra.program.model.mem.MemoryBlock;
+import ghidra.util.task.TaskMonitor;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExtractFunctions extends GhidraScript {
+
+ @Override
+ protected void run() throws Exception {
+ Program program = currentProgram;
+ FunctionManager functionManager = program.getFunctionManager();
+ Memory memory = program.getMemory();
+
+ String outputDir = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP";
+
+ // 1. Extract memory blocks
+ List<MemoryBlockInfo> memBlocks = new ArrayList<>();
+ for (MemoryBlock block : memory.getBlocks()) {
+ memBlocks.add(new MemoryBlockInfo(
+ block.getName(),
+ block.getStart().toString(),
+ block.getEnd().toString(),
+ block.getSize(),
+ block.isExecute(),
+ block.isRead(),
+ block.isWrite()
+ ));
+ }
+ writeJson(outputDir + "/memory_blocks.json", memBlocks);
+
+ // 2. Extract all functions (analysis must have run first)
+ List<FunctionInfo> functions = new ArrayList<>();
+ FunctionIterator funcIter = functionManager.getFunctions(true);
+ while (funcIter.hasNext()) {
+ Function func = funcIter.next();
+ functions.add(new FunctionInfo(
+ func.getName(),
+ func.getEntryPoint().toString(),
+ func.getBody().getNumAddresses()
+ ));
+ }
+ writeJson(outputDir + "/functions.json", functions);
+
+ // 3. Extract interesting strings
+ String[] keywords = {"vgpu", "vmiop", "rpc", "hal", "bar", "migrate", "init", "boot", "kgsp", "wpr", "firmware", "version", "error", "fail", "assert", "panic", "nvidia", "rmapi", "gsp", "falcon", "mailbox", "interrupt", "dma", "iommu", "page", "mmu", "pde", "pte"};
+ List<StringInfo> strings = new ArrayList<>();
+ var listing = program.getListing();
+ var dataIter = listing.getDefinedData(true);
+ while (dataIter.hasNext()) {
+ var data = dataIter.next();
+ if (data.getDataType().getName().equals("string")) {
+ String value = data.getValue().toString();
+ if (value.length() > 4) {
+ String lower = value.toLowerCase();
+ for (String kw : keywords) {
+ if (lower.contains(kw)) {
+ strings.add(new StringInfo(data.getAddress().toString(), value));
+ break;
+ }
+ }
+ }
+ }
+ }
+ writeJson(outputDir + "/interesting_strings.json", strings);
+
+ println("Extracted " + functions.size() + " functions, " + memBlocks.size() + " memory blocks, " + strings.size() + " interesting strings");
+ }
+
+ private void writeJson(String path, List<?> list) throws IOException {
+ try (FileWriter fw = new FileWriter(path)) {
+ fw.write("[\n");
+ for (int i = 0; i < list.size(); i++) {
+ fw.write(" " + toJson(list.get(i)));
+ if (i < list.size() - 1) fw.write(",");
+ fw.write("\n");
+ }
+ fw.write("]\n");
+ }
+ }
+
+ private String toJson(Object obj) {
+ if (obj instanceof MemoryBlockInfo) {
+ MemoryBlockInfo m = (MemoryBlockInfo) obj;
+ return String.format("{\"name\":\"%s\",\"start\":\"%s\",\"end\":\"%s\",\"size\":%d,\"execute\":%b,\"read\":%b,\"write\":%b}",
+ m.name, m.start, m.end, m.size, m.execute, m.read, m.write);
+ } else if (obj instanceof FunctionInfo) {
+ FunctionInfo f = (FunctionInfo) obj;
+ return String.format("{\"name\":\"%s\",\"entry\":\"%s\",\"size\":%d}",
+ f.name, f.entry, f.size);
+ } else if (obj instanceof StringInfo) {
+ StringInfo s = (StringInfo) obj;
+ return String.format("{\"address\":\"%s\",\"value\":\"%s\"}",
+ s.address, s.value.replace("\\", "\\\\").replace("\"", "\\\""));
+ }
+ return "{}";
+ }
+
+ static class MemoryBlockInfo {
+ String name, start, end;
+ long size;
+ boolean execute, read, write;
+ MemoryBlockInfo(String n, String s, String e, long sz, boolean ex, boolean rd, boolean wr) {
+ name = n; start = s; end = e; size = sz; execute = ex; read = rd; write = wr;
+ }
+ }
+
+ static class FunctionInfo {
+ String name, entry;
+ long size;
+ FunctionInfo(String n, String e, long sz) { name = n; entry = e; size = sz; }
+ }
+
+ static class StringInfo {
+ String address, value;
+ StringInfo(String a, String v) { address = a; value = v; }
+ }
+}
diff --git a/tools/ghidra/gsp-fwimage-570.144/scripts/basic_analysis.py b/tools/ghidra/gsp-fwimage-570.144/scripts/basic_analysis.py
new file mode 100644
index 0000000..4992106
--- /dev/null
+++ b/tools/ghidra/gsp-fwimage-570.144/scripts/basic_analysis.py
@@ -0,0 +1,108 @@
+# Ghidra script to do basic disassembly analysis of GSP .fwimage binary
+# Usage: analyzeHeadless ... -postScript basic_analysis.py
+
+import sys
+import os
+import json
+
+# Get the current program
+program = getCurrentProgram()
+listing = program.getListing()
+memory = program.getMemory()
+function_manager = program.getFunctionManager()
+
+print("=== GSP Firmware .fwimage Basic Analysis ===")
+print(f"Program: {program.getName()}")
+print(f"Architecture: {program.getLanguage().toString()}")
+
+# Create output directory
+output_dir = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP"
+os.makedirs(output_dir, exist_ok=True)
+
+# 1. Check memory blocks
+print("\n--- Memory Blocks ---")
+mem_blocks = []
+for block in memory.getBlocks():
+ mem_blocks.append({
+ "name": block.getName(),
+ "start": str(block.getStart()),
+ "end": str(block.getEnd()),
+ "size": block.getSize(),
+ "execute": block.isExecute(),
+ "read": block.isRead(),
+ "write": block.isWrite()
+ })
+ print(f" {block.getName()}: {block.getStart()} - {block.getEnd()} ({block.getSize()} bytes) r={block.isRead()} w={block.isWrite()} x={block.isExecute()}")
+
+with open(os.path.join(output_dir, "memory_blocks.json"), "w") as f:
+ json.dump(mem_blocks, f, indent=2)
+
+# 2. Find all functions (but don't decompile yet)
+print("\n--- Finding Functions ---")
+functions = []
+func_iter = function_manager.getFunctions(True)
+count = 0
+while func_iter.hasNext():
+ func = func_iter.next()
+ functions.append({
+ "name": func.getName(),
+ "entry": str(func.getEntryPoint()),
+ "size": func.getBody().getNumAddresses()
+ })
+ count += 1
+ if count % 1000 == 0:
+ print(f" Found {count} functions...")
+
+print(f"Total functions: {len(functions)}")
+
+with open(os.path.join(output_dir, "functions.json"), "w") as f:
+ json.dump(functions, f, indent=2)
+
+# 3. Find strings
+print("\n--- Finding Strings ---")
+strings = []
+string_iter = listing.getDefinedData(True)
+while string_iter.hasNext():
+ data = string_iter.next()
+ if data.getDataType().getName() == "string":
+ value = data.getValue()
+ if value and len(str(value)) > 4:
+ strings.append({
+ "address": str(data.getAddress()),
+ "value": str(value)
+ })
+
+print(f"Found {len(strings)} strings")
+
+# Filter for interesting strings
+interesting_keywords = ["vgpu", "vmiop", "rpc", "hal", "bar", "migrate", "init", "boot", "kgsp", "wpr", "firmware", "version", "error", "fail", "assert", "panic", "nvidia", "rmapi", "gsp", "falcon", "mailbox", "interrupt", "dma", "iommu", "page", "mmu", "pde", "pte"]
+interesting_strings = [s for s in strings if any(kw in s['value'].lower() for kw in interesting_keywords)]
+print(f"Interesting strings: {len(interesting_strings)}")
+
+with open(os.path.join(output_dir, "interesting_strings.json"), "w") as f:
+ json.dump(interesting_strings, f, indent=2)
+
+# 4. Find entry point (offset 0)
+print("\n--- Entry Point Analysis ---")
+entry_addr = program.getMinAddress()
+print(f"Program entry (min address): {entry_addr}")
+
+# Check what's at address 0
+func_at_zero = function_manager.getFunctionAt(entry_addr)
+if func_at_zero:
+ print(f"Function at entry: {func_at_zero.getName()}")
+else:
+ print("No function at entry point - creating one...")
+ # Create function at entry point
+ func = function_manager.createFunction("entry_point", entry_addr, None, None)
+ if func:
+ print(f"Created function: {func.getName()}")
+
+# 5. Look for RISC-V standard function prologues
+print("\n--- Looking for Function Prologues ---")
+# RISC-V typical prologue: addi sp, sp, -X; sd ra, X-8(sp); sd s0, X-16(sp); addi s0, sp, X
+# Let's search for common patterns
+
+# 6. Find cross-references to interesting addresses
+print("\n--- Analysis Complete ---")
+print(f"Results saved to {output_dir}") \ No newline at end of file