import ghidra.app.script.GhidraScript;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileResults;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
// Offline, pinned-image decompilation. Does not attach to, patch or invoke the game.
public class LocalFlightDecompile extends GhidraScript {
public void run() throws Exception {
if (getScriptArgs().length != 2 || currentProgram.getImageBase().getOffset()!=0x140000000L
|| !currentProgram.getExecutableSHA256().equalsIgnoreCase("6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93"))
throw new IllegalArgumentException("Expected the pinned D-installation image and two output/manifest paths.");
Path output=Path.of(getScriptArgs()[0]).toAbsolutePath();Files.createDirectories(output);
var rows=Files.readAllLines(Path.of(getScriptArgs()[1]),StandardCharsets.UTF_8);
if(rows.size()>256)throw new IllegalArgumentException("Too many fixed function addresses.");
long[] targets=new long[rows.size()];
for(int i=0;i<rows.size();i++){
if(!rows.get(i).matches("0x[0-9a-fA-F]{6,8}"))throw new IllegalArgumentException("Expected fixed PE RVA.");
targets[i]=Long.parseLong(rows.get(i).substring(2),16);
Address a=currentProgram.getImageBase().add(targets[i]);var block=currentProgram.getMemory().getBlock(a);
if(block==null||!block.isExecute())throw new IllegalArgumentException("Target outside code.");
if(getFunctionAt(a)==null){disassemble(a);createFunction(a,"localflight_"+Long.toHexString(targets[i]));}
}
DecompInterface decompiler=new DecompInterface();
try{
if(!decompiler.openProgram(currentProgram))throw new IllegalStateException(decompiler.getLastMessage());
for(long rva:targets){
monitor.checkCancelled();Function fn=getFunctionAt(currentProgram.getImageBase().add(rva));
DecompileResults result=decompiler.decompileFunction(fn,45,monitor);
if(!result.decompileCompleted())throw new IllegalStateException(result.getErrorMessage());
Files.writeString(output.resolve(Long.toHexString(rva)+".c"),result.getDecompiledFunction().getC(),StandardCharsets.UTF_8);
println("Offline decompiled fixed RVA "+Long.toHexString(rva));
}
}finally{decompiler.dispose();}
}
}
import ghidra.app.script.GhidraScript;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileResults;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
// Offline, pinned-image decompilation. Does not attach to, patch or invoke the game.
public class LocalFlightDecompile extends GhidraScript {
public void run() throws Exception {
if (getScriptArgs().length != 2 || currentProgram.getImageBase().getOffset()!=0x140000000L
|| !currentProgram.getExecutableSHA256().equalsIgnoreCase("6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93"))
throw new IllegalArgumentException("Expected the pinned D-installation image and two output/manifest paths.");
Path output=Path.of(getScriptArgs()[0]).toAbsolutePath();Files.createDirectories(output);
var rows=Files.readAllLines(Path.of(getScriptArgs()[1]),StandardCharsets.UTF_8);
if(rows.size()>256)throw new IllegalArgumentException("Too many fixed function addresses.");
long[] targets=new long[rows.size()];
for(int i=0;i<rows.size();i++){
if(!rows.get(i).matches("0x[0-9a-fA-F]{6,8}"))throw new IllegalArgumentException("Expected fixed PE RVA.");
targets[i]=Long.parseLong(rows.get(i).substring(2),16);
Address a=currentProgram.getImageBase().add(targets[i]);var block=currentProgram.getMemory().getBlock(a);
if(block==null||!block.isExecute())throw new IllegalArgumentException("Target outside code.");
if(getFunctionAt(a)==null){disassemble(a);createFunction(a,"localflight_"+Long.toHexString(targets[i]));}
}
DecompInterface decompiler=new DecompInterface();
try{
if(!decompiler.openProgram(currentProgram))throw new IllegalStateException(decompiler.getLastMessage());
for(long rva:targets){
monitor.checkCancelled();Function fn=getFunctionAt(currentProgram.getImageBase().add(rva));
DecompileResults result=decompiler.decompileFunction(fn,45,monitor);
if(!result.decompileCompleted())throw new IllegalStateException(result.getErrorMessage());
Files.writeString(output.resolve(Long.toHexString(rva)+".c"),result.getDecompiledFunction().getC(),StandardCharsets.UTF_8);
println("Offline decompiled fixed RVA "+Long.toHexString(rva));
}
}finally{decompiler.dispose();}
}
}