01-kmycore-diskfs.sh 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #!/usr/bin/env bash
  2. # Fix 1: make kmyCore.dll's scanPlugin use the on-disk filesystem.
  3. #
  4. # kmyPlugin::PluginMgr::scanPlugin calls kmyIO::FS::newFS(0, NULL) which, in
  5. # packaged mode, hands back the in-memory data.rbpack filesystem. The engine's
  6. # .dlp asset loaders (FBXLoader/PNGLoader/OGGLoader/BulletPhysics/...) do NOT
  7. # live inside data.rbpack, so the scan finds none of them and the game loads an
  8. # empty scene (grey screen). This flips the target of that one `call` so it goes
  9. # to the disk-FS creator at RVA 0xAAA10 (which safely handles a NULL path).
  10. #
  11. # The change is a single byte in the rel32 displacement of the call:
  12. # file offset 0xD0B54 : 0x58 -> 0xB8 (retargets 0xAA9B0 -> 0xAAA10)
  13. # Before writing, the FULL 5-byte call instruction at 0xD0B53 is verified
  14. # (e8 58 92 fd ff), so a different build can't pass on a coincidental byte.
  15. #
  16. # Reversible: a .orig backup is written next to the file the first time.
  17. set -euo pipefail
  18. GAME_ROOT="${1:?usage: 01-kmycore-diskfs.sh <game-root-dir>}"
  19. DLL="$GAME_ROOT/data/kmyCore.dll"
  20. OFF=$((0xD0B54)) # the rel32 low byte we flip
  21. CALL_OFF=$((0xD0B53)) # start of the 5-byte call instruction
  22. ORIG_CALL="e85892fdff" # call -> disk/pack FS dispatcher RVA 0xAA9B0
  23. NEW_CALL="e8b892fdff" # call -> disk-FS creator RVA 0xAAA10
  24. # md5 of the known-good v1.1.0 unpatched kmyCore.dll (5,423,536 bytes)
  25. KNOWN_ORIG_MD5="68590231c9418eeab8b9d70203e1f08d"
  26. [ -f "$DLL" ] || { echo "!! not found: $DLL"; exit 1; }
  27. cur=$(od -An -tx1 -j "$CALL_OFF" -N5 "$DLL" | tr -d ' \n')
  28. if [ "$cur" = "$NEW_CALL" ]; then
  29. echo "== Fix 1: already applied (call @0x$(printf %x $CALL_OFF) = $NEW_CALL)"; exit 0
  30. fi
  31. if [ "$cur" != "$ORIG_CALL" ]; then
  32. echo "!! Fix 1: unexpected bytes $cur @0x$(printf %x $CALL_OFF) (expected $ORIG_CALL)."
  33. echo "!! This kmyCore.dll is a different build than this patch targets. Aborting."
  34. exit 3
  35. fi
  36. md5now=$(md5sum "$DLL" | cut -d' ' -f1)
  37. [ "$md5now" = "$KNOWN_ORIG_MD5" ] || \
  38. echo " (note: kmyCore.dll md5 $md5now != known $KNOWN_ORIG_MD5; byte matches, continuing)"
  39. [ -f "$DLL.orig" ] || cp -n "$DLL" "$DLL.orig"
  40. printf "\xb8" | dd of="$DLL" bs=1 seek="$OFF" count=1 conv=notrunc status=none
  41. echo "== Fix 1: patched kmyCore.dll (disk-FS), backup at kmyCore.dll.orig"