mirror of
https://github.com/daniel-lynch/ovrplugin-openxr-shim.git
synced 2026-10-06 01:00:05 +02:00
An independent reimplementation of Meta's libOVRPlugin ABI on top of OpenXR, so VrApi-era Meta Quest VR titles can run on non-Meta OpenXR runtimes (Monado, Steam Frame) instead of being locked to Meta hardware. Original code only — no Meta/Epic/Capcom binaries, headers, or assets. Includes a desktop harness that drives the shim against Monado headless. Scope/legal: interoperability; entitlement handling is out of scope. See README for the legal/scope section and docs/ for the research trail and design notes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D6sFYGXZPsq3v7xtcDES6g
72 lines
3.2 KiB
Java
72 lines
3.2 KiB
Java
// Dump ovrp* struct layouts Ghidra inferred + decompile the Compositor layer
|
|
// methods (ground-truth field offsets for ovrpLayerDesc / ovrpLayerSubmit).
|
|
// -> ~/dev/re4vr-port/analysis/struct_layouts.txt
|
|
// @category RE4VR
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.app.decompiler.*;
|
|
import ghidra.program.model.data.*;
|
|
import ghidra.program.model.listing.*;
|
|
import java.io.PrintWriter;
|
|
import java.util.*;
|
|
|
|
public class DumpStructs extends GhidraScript {
|
|
public void run() throws Exception {
|
|
String out = System.getProperty("user.home")
|
|
+ "/dev/re4vr-port/analysis/struct_layouts.txt";
|
|
PrintWriter w = new PrintWriter(out);
|
|
|
|
// 1) every struct/typedef whose name mentions ovrp or Layer
|
|
w.println("## ===== INFERRED STRUCT LAYOUTS (name ~ ovrp|Layer) =====");
|
|
DataTypeManager dtm = currentProgram.getDataTypeManager();
|
|
Iterator<DataType> it = dtm.getAllDataTypes();
|
|
while (it.hasNext()) {
|
|
DataType dt = it.next();
|
|
String nm = dt.getName();
|
|
if (!(nm.toLowerCase().contains("ovrp") || nm.contains("Layer"))) continue;
|
|
if (dt instanceof Structure) {
|
|
Structure s = (Structure) dt;
|
|
w.println("\nstruct " + nm + " /* size=" + s.getLength()
|
|
+ " (0x" + Integer.toHexString(s.getLength()) + ") */ {");
|
|
for (DataTypeComponent c : s.getComponents()) {
|
|
w.printf(" +0x%-4x %-24s %s%n", c.getOffset(),
|
|
c.getDataType().getName(),
|
|
c.getFieldName() == null ? "" : c.getFieldName());
|
|
}
|
|
w.println("};");
|
|
} else {
|
|
w.println(nm + " (" + dt.getClass().getSimpleName()
|
|
+ ", len=" + dt.getLength() + ")");
|
|
}
|
|
}
|
|
|
|
// 2) decompile the Compositor layer methods for real offsets
|
|
String[] targets = {
|
|
"ImportLayerDesc", "ExportEyeLayerDesc", "CalculateEyeLayerDesc",
|
|
"SetupLayer", "GetLayerTexture", "EndFrame", "SubmitLayer"
|
|
};
|
|
w.println("\n\n## ===== COMPOSITOR METHOD BODIES (field-offset ground truth) =====");
|
|
DecompInterface dec = new DecompInterface();
|
|
dec.openProgram(currentProgram);
|
|
FunctionManager fm = currentProgram.getFunctionManager();
|
|
Set<String> seen = new HashSet<>();
|
|
for (Function f : fm.getFunctions(true)) {
|
|
String name = f.getName();
|
|
boolean hit = false;
|
|
for (String t : targets) if (name.contains(t)) { hit = true; break; }
|
|
if (!hit) continue;
|
|
if (!seen.add(f.getEntryPoint().toString())) continue;
|
|
try {
|
|
DecompileResults r = dec.decompileFunction(f, 60, monitor);
|
|
DecompiledFunction df = r.getDecompiledFunction();
|
|
if (df != null) {
|
|
w.println("\n/* ===== " + name + " @ " + f.getEntryPoint()
|
|
+ " ===== */");
|
|
w.println(df.getC());
|
|
}
|
|
} catch (Exception e) { /* skip */ }
|
|
}
|
|
w.close();
|
|
println("DumpStructs: wrote " + out);
|
|
}
|
|
}
|