Manual/Client Internals/Native binaries & security posture
v1.0.364 notes · build 2026-11-07 12:10 UTC

Native binaries & security posture

FM_Mono verdict · no pinning · no Integrity API · what actually gates
#security #native

Scope static: first pass = 7 key libraries + arm64 disassembly of the CalcChatSign helper in libxlua.so; 1.0.364 pass = all 39 libraries, both ABIs (symbols, strings, P/Invoke maps) + 2 more arm64 disassemblies. libsmsdk.so (ShuMei) fully decompiled — Obfuscator-LLVM string encryption reversed by emulating the .datadiv_decode* init functions.

libil2cpp.so static

Only 1.8 MB; zero strings for AESHelper/NetworkManager/SendLuaMessage/Unity type names; Assembly-CSharp never AOT-compiled; gameplay lives in hot-update .mdl files. It is FunPlus's FM_Mono bridge — not IL2CPP, not HybridCLR (no hybridclr/huatuo symbols). Exports the il2cpp_* ABI plus FM_Mono::*, LoadAssemblyByName, AddAssemblySearchPath(…, NativePersistType), SetAssemblyOnlyReadFromPackage, LoadAssemblyWithImageBinary, visitNoUpdateAssemblies. Built on Mono 6.13.0 (libmonoboehm-2.0, both ABIs). Java launcher com.rivergame.fm_mono.FMMonoBaseActivity; managed side FM_MonoLib.dll. Adds persistentDataPath/Assemblies/ as a .mdl search path; noUpdateAssemblies.json lists only SmartFox2X; the .mdl XOR scheme is unchanged.

Feasibility conclusions

  • ShuMei fingerprint (boxId → shumeiBoxId login field): no enforcement identified; empty/synthetic values accepted for new guests; the apparent reconnect gate = packageName/platform/appVersion mismatch vs the access token live; 2026-10-04 iOS capture reconnected with an empty shumeiBoxId.
  • Tencent ACE: not on the game-server protocol at all (local IPC to Tencent's backend); no enforcement identified.
  • SecurityCode/OneCode/CoreV (~3 login fields): plain MD5, hardcoded salt, fully reproducible.
  • packageSign = SHA1(packageName), a constant public string (not a cert hash); the genuine cert-dependent field is psh; 1.0.364 uses the same signing cert; iOS mode sends the iOS formula from rg_getPsh: (until 2026-10-18 it sent the Android value; the server accepted it for weeks) live.
  • libxlua.so static: the native chat branch is unreachable in 1.0.364 (chat = C# ChatService); the unkeyed MD5(MD5(appId+uid)+timestamp) matches the C# formula; only v7a registers rg_websocket; arm64 luaopen_native registers only rg_sqlite, rg_async, cutils, md5, base64, crypt; LuaEntry:__InitCModule() never called.
  • TLS: no pinning evidence; standard chain validation except the XAssetPro bundle downloader (disables it). Google Play Integrity / SafetyNet: not used.

Bottom line live: nothing below the protocol layer blocks a third-party client — guest creation, email-verification binds, and reconnect into established accounts all work end-to-end; after a security fix replaced ta device/anti-fraud sub-fields with placeholders, an unattended cron reconnected and collected resources over multiple days (August 2026). Earlier rejections were identity mismatches, not security gates.

ABI parity (1.0.364)

arm64-v8a = 21 libs, armeabi-v7a = 18; Tencent GME voice (libgmesdk, libtxffmpeg, libtxsoundtouch) arm64-only, no C# ABI guard. libsqlite3 3.28.0 (arm64) vs 3.19.3 (v7a); libxlua embeds SQLite 3.38.0. Unity 2019.4.41f1 per libunity.so, but the Java crash string says 2019.4.40f1 and C# hard-codes unityVersion=440; goclient deliberately sends 440.

notes build 2026-11-07 12:10 UTC · lw-notes@9c47e1b · sources: own capture/analysis cross-checked against the public dossier