import ghidra.app.script.GhidraScript; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; import ghidra.program.model.data.*; import ghidra.program.model.lang.*; import ghidra.app.decompiler.*; import java.util.*; import java.io.*; // ServerPlayer::Read/Write had no parameters: create this (ECX) = ServerPlayer_ser928*, stream (stack+4); verify decompile. public class FixPlayer extends GhidraScript { @Override public void run() throws Exception { DataTypeManager dtm = currentProgram.getDataTypeManager(); List l = new ArrayList(); dtm.findDataTypes("Game::ServerPlayer_ser928", l); DataType view = l.get(0); List l2 = new ArrayList(); dtm.findDataTypes("Stream", l2); DataType stream = null; for (DataType d : l2) if (d.getCategoryPath().getPath().equals("/Mars")) stream = d; Register ecx = currentProgram.getRegister("ECX"); PrintWriter log = new PrintWriter(new FileWriter("/tmp/spine/fixplayer.log")); for (long a : new long[]{0x008563e0L, 0x008804d0L}) { Function f = getFunctionAt(toAddr(a)); List ps = new ArrayList(); ps.add(new ParameterImpl("this", new PointerDataType(view), ecx, currentProgram)); ps.add(new ParameterImpl("stream", new PointerDataType(stream == null ? VoidDataType.dataType : stream), 4, currentProgram)); f.setCustomVariableStorage(true); f.replaceParameters(ps, Function.FunctionUpdateType.CUSTOM_STORAGE, true, SourceType.USER_DEFINED); log.println(f.getName(true) + " params=" + f.getParameterCount() + " " + f.getPrototypeString(false, false)); } DecompInterface decomp = new DecompInterface(); decomp.openProgram(currentProgram); Function f = getFunctionAt(toAddr(0x008563e0L)); DecompileResults res = decomp.decompileFunction(f, 240, monitor); PrintWriter w = new PrintWriter(new FileWriter("/tmp/spine/verify_ServerPlayer_Write.c")); w.println(res.getDecompiledFunction().getC()); w.close(); decomp.dispose(); log.close(); println("fixplayer done"); } }