summaryrefslogtreecommitdiffstats
path: root/tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py')
-rw-r--r--tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py207
1 files changed, 207 insertions, 0 deletions
diff --git a/tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py b/tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py
new file mode 100644
index 0000000..4a6fb56
--- /dev/null
+++ b/tools/ghidra/gsp-tu104-570.144/scripts/analyze_gsp_fwimage.py
@@ -0,0 +1,207 @@
+# Ghidra script to analyze GSP .fwimage binary
+# Usage: analyzeHeadless ... -postScript analyze_gsp_fwimage.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 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. Find all functions
+print("\n--- Finding Functions ---")
+functions = []
+func_iter = function_manager.getFunctions(True)
+while func_iter.hasNext():
+ func = func_iter.next()
+ functions.append({
+ "name": func.getName(),
+ "entry": str(func.getEntryPoint()),
+ "size": func.getBody().getNumAddresses(),
+ "signature": func.getSignature().toString() if func.getSignature() else ""
+ })
+
+print(f"Found {len(functions)} functions")
+
+# Save function list
+with open(os.path.join(output_dir, "functions.json"), "w") as f:
+ json.dump(functions, f, indent=2)
+
+# 2. Find RPC-related functions (vRPC/pRPC handlers)
+print("\n--- Finding RPC Handlers ---")
+rpc_keywords = [
+ "rpc", "Rpc", "RPC",
+ "vgpu", "Vgpu", "VGPU",
+ "vmiop", "Vmiop", "VMIOP",
+ "hal", "Hal", "HAL",
+ "bar", "Bar", "BAR",
+ "migrate", "Migrate", "MIGRATE",
+ "init", "Init", "INIT",
+ "boot", "Boot", "BOOT",
+ "kgsp", "Kgsp", "KGSP"
+]
+
+rpc_functions = []
+for func in functions:
+ name_lower = func["name"].lower()
+ for kw in rpc_keywords:
+ if kw.lower() in name_lower:
+ rpc_functions.append(func)
+ break
+
+print(f"Found {len(rpc_functions)} potential RPC-related functions")
+with open(os.path.join(output_dir, "rpc_functions.json"), "w") as f:
+ json.dump(rpc_functions, f, indent=2)
+
+# 3. Find strings related to vGPU initialization
+print("\n--- Finding vGPU-related Strings ---")
+vgpu_strings = []
+string_iter = listing.getDefinedData(True)
+while string_iter.hasNext():
+ data = string_iter.next()
+ if data.getDataType().getName() == "string":
+ value = data.getValue()
+ if value:
+ val_str = str(value).lower()
+ if any(kw in val_str for kw in ["vgpu", "vmiop", "rpc", "hal", "bar", "migrate", "init", "boot", "kgsp", "wpr", "firmware", "version"]):
+ vgpu_strings.append({
+ "address": str(data.getAddress()),
+ "value": str(value)
+ })
+
+print(f"Found {len(vgpu_strings)} vGPU-related strings")
+with open(os.path.join(output_dir, "vgpu_strings.json"), "w") as f:
+ json.dump(vgpu_strings, f, indent=2)
+
+# 4. Find entry points and initialization functions
+print("\n--- Finding Entry Points ---")
+entry_points = []
+# Look for common entry point names
+entry_names = [
+ "kgspInitRm_IMPL", "kgspInitRm", "kgspBootGspRm", "kgspBootGspRm_IMPL",
+ "gspBoot", "gspInit", "gspMain",
+ "nv_vgpu_vfio_get_ops", "nv_vgpu_vfio_set_ops",
+ "vgpu_init", "vgpu_init_IMPL",
+ "vmiop_init", "vmiop_init_IMPL",
+ "hal_init", "hal_init_IMPL"
+]
+
+for name in entry_names:
+ func = function_manager.getFunction(name)
+ if func:
+ entry_points.append({
+ "name": name,
+ "entry": str(func.getEntryPoint()),
+ "size": func.getBody().getNumAddresses()
+ })
+ print(f" Found: {name} at {func.getEntryPoint()}")
+
+# Also check for functions called from reset vector / entry
+# Look at the first few instructions
+entry_addr = program.getMinAddress()
+print(f"\nProgram entry address: {entry_addr}")
+
+# 5. Find WPR (Write Protected Region) related code
+print("\n--- Finding WPR-related Code ---")
+wpr_functions = []
+for func in functions:
+ name_lower = func["name"].lower()
+ if "wpr" in name_lower or "write_protect" in name_lower or "protect" in name_lower:
+ wpr_functions.append(func)
+
+print(f"Found {len(wpr_functions)} WPR-related functions")
+with open(os.path.join(output_dir, "wpr_functions.json"), "w") as f:
+ json.dump(wpr_functions, f, indent=2)
+
+# 6. Find memory management functions
+print("\n--- Finding Memory Management Functions ---")
+mem_keywords = ["alloc", "free", "map", "unmap", "pin", "unpin", "dma", "iommu", "mmio", "bar"]
+mem_functions = []
+for func in functions:
+ name_lower = func["name"].lower()
+ for kw in mem_keywords:
+ if kw in name_lower:
+ mem_functions.append(func)
+ break
+
+print(f"Found {len(mem_functions)} memory management functions")
+with open(os.path.join(output_dir, "mem_functions.json"), "w") as f:
+ json.dump(mem_functions, f, indent=2)
+
+# 7. Find interrupt/MSI-X related functions
+print("\n--- Finding Interrupt/MSI-X Functions ---")
+irq_keywords = ["irq", "interrupt", "msi", "msix", "eventfd", "doorbell"]
+irq_functions = []
+for func in functions:
+ name_lower = func["name"].lower()
+ for kw in irq_keywords:
+ if kw in name_lower:
+ irq_functions.append(func)
+ break
+
+print(f"Found {len(irq_functions)} interrupt-related functions")
+with open(os.path.join(output_dir, "irq_functions.json"), "w") as f:
+ json.dump(irq_functions, f, indent=2)
+
+# 8. Generate summary report
+print("\n--- Generating Summary Report ---")
+report = {
+ "firmware": "gsp-570.144",
+ "architecture": program.getLanguage().toString(),
+ "total_functions": len(functions),
+ "rpc_functions": len(rpc_functions),
+ "vgpu_strings": len(vgpu_strings),
+ "entry_points": entry_points,
+ "wpr_functions": len(wpr_functions),
+ "mem_functions": len(mem_functions),
+ "irq_functions": len(irq_functions)
+}
+
+with open(os.path.join(output_dir, "analysis_summary.json"), "w") as f:
+ json.dump(report, f, indent=2)
+
+# Print summary
+print(json.dumps(report, indent=2))
+
+# 9. Decompile key functions and save
+print("\n--- Decompiling Key Functions ---")
+from ghidra.app.decompiler import DecompInterface
+from ghidra.util.task import ConsoleTaskMonitor
+
+decompiler = DecompInterface()
+decompiler.openProgram(program)
+monitor = ConsoleTaskMonitor()
+
+key_functions = entry_points + rpc_functions[:20] + wpr_functions + mem_functions[:10] + irq_functions[:10]
+decompiled = {}
+
+for func_info in key_functions:
+ func = function_manager.getFunctionAt(func_info["entry"])
+ if func:
+ result = decompiler.decompileFunction(func, 60, monitor)
+ if result.decompileCompleted():
+ decompiled[func_info["name"]] = result.getDecompiledFunction().getC()
+ print(f" Decompiled: {func_info['name']}")
+ else:
+ print(f" Failed to decompile: {func_info['name']}")
+
+# Save decompiled code
+with open(os.path.join(output_dir, "decompiled_key_functions.c"), "w") as f:
+ for name, code in decompiled.items():
+ f.write(f"\n// ===== {name} =====\n")
+ f.write(code)
+ f.write("\n")
+
+print(f"\nDecompiled {len(decompiled)} key functions")
+print("Analysis complete!") \ No newline at end of file