mirror of
https://github.com/daniel-lynch/ovrplugin-openxr-shim.git
synced 2026-10-06 02:00:05 +02:00
Repo hygiene round following a full review. No shim behaviour changes. Leak risk: - .gitignore: ignore CLAUDE.md (personal assistant-lane config, was one `git add -A` away from a public commit) and scratch_obj/. Docs vs. reality: - shim/README.md: rewritten. It described a pre-implementation skeleton with "core fns are TODO stubs returning -1005", three mutually inconsistent stub counts, and four completed milestones listed as open. Now carries the verified breakdown: 438/438 exports = 371 generated stubs + 46 core + 7 layers + 2 Vulkan queries + 12 passthru trampolines. - TESTING.md: dropped the self-contradicting "NOT yet" block (5 of 6 items were done or misstated, and contradicted the same file 45 lines above). Path B now points at tools/desktop-harness, which exists, instead of the orphaned shim/tests/harness.c. Path A prereqs marked as the record they are. - HOST.md: corrected the runtime assumption. The OpenXR runtime inside Lepton is SteamVR (vendor/etc/openxr/1/active_runtime.json -> vrclient.so), not Monado. Favourable: SteamVR emulates Oculus Touch by default and advertises the XR_FB_foveation family, so the existing input and foveation paths should carry over. The old "remaining unknowns" are resolved by Lepton's published source and replaced with the items to check before a first Frame boot. - README.md: same runtime correction. - docs/research/RECON.md: the four passages prescribing an entitlement NOP/stub/bypass are corrected in place rather than merely disclaimed by the top banner, which they contradicted. Build correctness: - shim/build_android.sh: missing patchelf is now fatal. It warned and exited 0, producing a .so that cannot resolve the OpenXR loader at runtime. - scripts/fetch_deps.sh + packaging/build_openxr_loader.sh: pin the OpenXR and Vulkan header versions (were tracking `main`), overridable via OPENXR_TAG / VULKAN_HEADERS_TAG; require cmake for the loader build. - packaging/steamframe_patches.sh: use the apktool.jar that fetch_deps.sh downloads. Its prereq check demanded an `apktool` binary on PATH that the documented setup never provides, so it could not run after a clean setup. - shim/gen_stubs.sh: it reads all_exports.txt, not shim_surface.txt; comment and emitted banner corrected. stubs.c regenerated (banner line only). - shim/src/core.c: split seven `if (out) ...; return ...;` one-liners. Host build now compiles with zero warnings, down from seven. Verified: host build 0 warnings; gen_stubs.sh output identical on regeneration; bash -n clean on all edited scripts; pinned header/tarball URLs return 200 and the tag tarball extracts to the expected directory name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
206 lines
8.8 KiB
Markdown
206 lines
8.8 KiB
Markdown
# RE4 VR (Quest 2) — Dump & Recon Checklist
|
|
|
|
Goal of this phase: **non-destructively dump your own legally-owned copy of RE4 VR
|
|
off the Quest 2 and answer the one question that decides the whole project** —
|
|
is the VR runtime OpenXR (shimmable) or VrApi (proprietary, must reimplement)?
|
|
|
|
Target app: `com.Armature.VR4` (Armature Studio / Capcom / Oculus, UE 4.25.3)
|
|
|
|
Legal posture: dump-your-own only. We extract from hardware *you own* running a
|
|
copy *you own*. **Nothing here gets redistributed** — only patches/shims you
|
|
author, applied by people who dump their own copy. Same model as ReXGlue.
|
|
|
|
> **Editor's note (2026-06, revised 2026-09):** this is a historical recon document. Its
|
|
> original text proposed an entitlement-stub approach in a few places (§4, the wiring
|
|
> summary, the decision tree). That was **not** carried into the project: entitlement
|
|
> handling is out of scope and the shim ships **no circumvention code** (see the README's
|
|
> scope section). Those passages have since been **corrected in place** so the document no
|
|
> longer reads as instructions; the correction is noted inline where it applies.
|
|
|
|
---
|
|
|
|
## 0. Prereqs (do while the Quest charges)
|
|
|
|
- [ ] Install Android platform-tools (adb): `sudo apt install android-tools-adb`
|
|
or grab Google's platform-tools zip.
|
|
- [ ] Verify: `adb version`
|
|
- [ ] Install analysis tooling:
|
|
- [ ] Ghidra (native .so disassembly/patching)
|
|
- [ ] `patchelf`, `binutils` (`readelf`, `nm`, `objdump`), `file`, `unzip`
|
|
- [ ] Python 3 + `pip install lief` (scripted ELF inspection/patching)
|
|
- [ ] FModel **or** umodel/UModel (UE 4.25 .pak browsing) — optional this phase
|
|
- [ ] FluffyQuack's UnrealPak tools — optional this phase
|
|
- [ ] Enable **Developer Mode** on the Quest (Meta Quest mobile app →
|
|
Devices → Developer Mode → on; requires a registered dev org — free).
|
|
- [ ] Plug Quest into PC via USB-C, put on headset, **Allow USB debugging**
|
|
when prompted (and check "always allow from this computer").
|
|
|
|
---
|
|
|
|
## 1. Confirm the device + app are visible
|
|
|
|
```bash
|
|
adb devices # should list one device, state "device" not "unauthorized"
|
|
adb shell pm list packages | grep -i armature # expect: com.Armature.VR4
|
|
adb shell dumpsys package com.Armature.VR4 | grep -i versionName
|
|
```
|
|
|
|
- [ ] Device shows as `device`
|
|
- [ ] `com.Armature.VR4` present
|
|
- [ ] Note the versionName here: `____________`
|
|
|
|
---
|
|
|
|
## 2. Locate and pull the APK(s)
|
|
|
|
Split APKs are common, so grab every path.
|
|
|
|
```bash
|
|
adb shell pm path com.Armature.VR4 # prints one or more base/split apk paths
|
|
mkdir -p ~/dev/re4vr-port/dump && cd ~/dev/re4vr-port/dump
|
|
# pull each path the command above printed, e.g.:
|
|
adb pull /data/app/~~xxxx/com.Armature.VR4-yyyy/base.apk .
|
|
# repeat for any split_*.apk lines
|
|
```
|
|
|
|
- [ ] `base.apk` pulled
|
|
- [ ] Any `split_*.apk` pulled
|
|
- [ ] Record sizes: `ls -lh *.apk`
|
|
|
|
---
|
|
|
|
## 3. Pull the OBB (game data / .pak files)
|
|
|
|
```bash
|
|
adb shell ls -la /sdcard/Android/obb/com.Armature.VR4/
|
|
adb pull /sdcard/Android/obb/com.Armature.VR4/ .
|
|
```
|
|
|
|
- [ ] OBB pulled (e.g. `main.NNN.com.Armature.VR4.obb`)
|
|
- [ ] Note the version number NNN in the OBB filename: `______`
|
|
(you'll need it if you ever repack)
|
|
|
|
---
|
|
|
|
## 4. ⭐ THE DECISIVE CHECK — OpenXR vs VrApi
|
|
|
|
This is the whole reason we're here. Inspect the native libs in the APK.
|
|
|
|
```bash
|
|
cd ~/dev/re4vr-port/dump
|
|
unzip -l base.apk | grep -iE 'lib/arm64-v8a/.*\.so' # list native libs
|
|
# the money grep:
|
|
unzip -l base.apk | grep -iE 'arm64.*(vrapi|openxr|ovrplatform|oculus|UE4)'
|
|
```
|
|
|
|
Interpret the result:
|
|
|
|
| Lib found in `lib/arm64-v8a/` | Meaning | Difficulty |
|
|
|-----------------------------------|-----------------------------------------------------|------------|
|
|
| `libopenxr_loader.so` | ✅ Standard OpenXR — Steam Frame provides a runtime; you translate vendor extensions. | Tractable |
|
|
| `libvrapi.so` | ⚠️ Proprietary Meta VrApi — must reimplement/shim the runtime. | Hard |
|
|
| `libovrplatformloader.so` | Present either way — the platform/entitlement library. **Left untouched** by this project (out of scope). | Not patched |
|
|
| `libUE4.so` (or split into modules)| The Unreal runtime itself — the host you'll be hooking. | n/a |
|
|
|
|
- [x] **RESULT — runtime is:** ☑ **VrApi** (legacy OVRPlugin path). Confirmed
|
|
2026-06-23 on app v2.3 (versionCode 203). `libvrapi.so` present,
|
|
`libopenxr_loader.so` ABSENT. `libOVRPlugin.so` NEEDs `libvrapi.so` and
|
|
imports 114 `vrapi_*` symbols; 0 OpenXR symbols anywhere.
|
|
- [x] `libovrplatformloader.so` present? ☑ yes (hard-NEEDED by libUE4.so)
|
|
|
|
**REFINED WIRING (the seam that matters):**
|
|
```
|
|
libUE4.so --(ovrp_* C API, 239 refs)--> libOVRPlugin.so --(114 vrapi_)--> libvrapi.so --> Horizon OS
|
|
libUE4.so --(NEEDED + ovr_* Platform SDK, 132 refs)--> libovrplatformloader.so (entitlement)
|
|
```
|
|
- libUE4.so has **0 vrapi_ refs** — game speaks **OVRPlugin's ovrp_* C API**, not
|
|
VrApi directly. libvrapi is just OVRPlugin's backend.
|
|
- => **PORT SEAM = reimplement libOVRPlugin.so (ovrp_* on OpenXR), drop libvrapi.**
|
|
ovrp_* is the documented Unity-shared API (OVR_Plugin.h); modern Meta OVRPlugin
|
|
has an OpenXR backend = reference impl / prior art.
|
|
- => **Leave the ovr_* Platform SDK alone** (`libovrplatformloader.so`). Entitlement and
|
|
account handling are **out of scope**: the original library is kept and its real check
|
|
runs unchanged. (The original recon note here proposed stubbing it; that was *not*
|
|
carried into the project — see the README's scope section.)
|
|
|
|
> If you want to double-check beyond filename presence, extract and inspect
|
|
> imports of `libUE4.so` (it may dynamically link the runtime):
|
|
> ```bash
|
|
> unzip base.apk 'lib/arm64-v8a/*' -d apk_libs
|
|
> readelf -d apk_libs/lib/arm64-v8a/libUE4.so | grep -i NEEDED
|
|
> nm -D --defined-only apk_libs/lib/arm64-v8a/libopenxr_loader.so 2>/dev/null | grep -i xr | head
|
|
> nm -D apk_libs/lib/arm64-v8a/libUE4.so | grep -iE 'xrCreate|vrapi_' | head
|
|
> ```
|
|
> `xrCreate*`/`xr*` symbols → OpenXR codepath. `vrapi_*` symbols → VrApi codepath.
|
|
> A binary can ship both libs but only *call* one — the symbol check tells you
|
|
> which is actually wired up.
|
|
|
|
---
|
|
|
|
## 5. Manifest & build recon
|
|
|
|
```bash
|
|
# Needs apktool (sudo apt install apktool) OR aapt from build-tools
|
|
aapt dump badging base.apk | grep -iE 'sdkVersion|native-code|package'
|
|
apktool d -s base.apk -o apk_decoded # -s = don't decode .dex, faster
|
|
grep -iE 'oculus|vr|xr|entitlement|permission' apk_decoded/AndroidManifest.xml
|
|
```
|
|
|
|
- [ ] minSdk / targetSdk noted: `______`
|
|
- [ ] `native-code` ABI (expect `arm64-v8a`): `______`
|
|
- [ ] Any Oculus/entitlement metadata flags in manifest noted below.
|
|
|
|
---
|
|
|
|
## 6. Confirm .pak accessibility (asset layer)
|
|
|
|
The community reports these are unencrypted — verify so you know the asset
|
|
layer is open if you ever need it.
|
|
|
|
```bash
|
|
# unzip the OBB (it's a zip), find Content/Paks/*.pak, then:
|
|
# try opening in FModel/umodel as UE 4.25.3, no AES key
|
|
```
|
|
|
|
- [x] .pak opens with no AES key (confirms community finding) ☑ yes
|
|
Verified 2026-06-23: pakchunk9 footer bEncryptedIndex=0, EncryptionKeyGuid
|
|
all-zero, pak version 9 (FrozenIndex / UE4.25-26). Plaintext index — 53
|
|
readable asset paths incl. /Game/Levels/BIO4/... Asset layer fully open.
|
|
- OBB layout: store (uncompressed) zip. main.203 (4.0GB) + patch.203 (4.0GB,
|
|
the v2.3 update layer) + a stashed VR4-Android-Shipping-arm64.apk (== base.apk).
|
|
Paks at VR4/Content/Paks/pakchunk{0..9}[optional]-Android_ETC2.pak (ETC2 =
|
|
Android texture compression; 'optional' = hi-res texture chunks).
|
|
Bink cutscenes at VR4/Content/Movies/*.bk2.
|
|
|
|
---
|
|
|
|
## 7. Record findings → decide path
|
|
|
|
Fill this in, then we branch:
|
|
|
|
```
|
|
versionName: 2.3 (versionCode 203, minSdk 25, targetSdk 29)
|
|
runtime: VrApi (libvrapi via libOVRPlugin; NO openxr) [CONFIRMED 2026-06-23]
|
|
ovrplatform loader: present (hard-NEEDED by libUE4.so)
|
|
UE version: 4.25.3 (engine = libUE4.so, stripped, arm64)
|
|
ABIs: arm64-v8a (single base.apk, no splits)
|
|
paks encrypted: NO — unencrypted, no AES key (CONFIRMED 2026-06-23, pak v9)
|
|
device: Quest 2 serial <redacted-serial> (codename hollywood)
|
|
```
|
|
|
|
**Decision tree:**
|
|
- **OpenXR** → next phase: map which Meta OpenXR vendor extensions the binary
|
|
requests, plan the OpenXR→Steam-Frame-runtime shim.
|
|
This is the "weekend-of-shimming" branch.
|
|
- **VrApi** → next phase: scope a VrApi reimplementation/translation shim
|
|
(much larger). Reassess whether the project is worth it vs. waiting/UEVR.
|
|
- **Either way** → `libovrplatformloader.so` is left as shipped. Entitlement handling is
|
|
out of scope for this project and no bypass is part of it; on Quest the platform's real
|
|
check runs unchanged. (The original recon note assumed a patch here; superseded.)
|
|
|
|
---
|
|
|
|
## Notes / scratch
|
|
|
|
(paste command output, symbol dumps, and decisions here as you go)
|