diff options
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.py | 207 |
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 |
