KCP gameserver with packet dispatch, scene streaming, combat, gacha and the shop, plus a small HTTP server for the login flow and the wish history page. Game data under assets is pulled out of the client instead of being typed by hand. The excel tables come from the packed bin container and the spawn points from the compiled scene scripts.
76 lines
3.4 KiB
Markdown
76 lines
3.4 KiB
Markdown
# Yuanshen.Patch
|
|
|
|
Our own client patch for Genshin Impact 0.9.10, replacing the third-party
|
|
Redirect. A native `version.dll` proxy that embeds the Frida gadget and
|
|
redirects all client HTTP traffic to our own dispatch/SDK server.
|
|
|
|
## How it works
|
|
|
|
The game imports `version.dll`. Windows loads a `version.dll` sitting next to
|
|
`GenshinImpact.exe` before the system one, which is our injection point.
|
|
|
|
1. **`version.dll` (our proxy)** — re-exports all 17 real `version.dll`
|
|
functions and forwards each, at link time, to the genuine system DLL via the
|
|
drive-independent NT path `\\.\GLOBALROOT\SystemRoot\System32\version.dll.<fn>`
|
|
(the "perfect DLL proxy" technique — no self-recursion, the game runs
|
|
normally). See `src/exports.h`.
|
|
2. On load it spawns a worker thread (never blocks the loader lock), waits for
|
|
the IL2CPP runtime (`UserAssembly.dll`) to be ready, then `LoadLibrary`s the
|
|
**Frida gadget** — this is the embedded Frida. See `src/dllmain.cpp`.
|
|
3. **The gadget** self-initializes from its own DllMain, reads `gadget.config`,
|
|
and runs **`redirect.js`**, which hooks `UnityWebRequest.set_url` and
|
|
`Uri..ctor` and rewrites every request's host to `http://127.0.0.1:8899`
|
|
(our SDK). Progress is written to `YuanshenPatch.log` in the game folder.
|
|
|
|
## Why there is no RSA patch (for 0.9.10)
|
|
|
|
The reference (xeon/EncryptionPatch, "RSAPatch") targets Genshin 4.2 and does
|
|
two things: bypass the RSA signature check on `query_cur_region` /
|
|
`server_rand_key`, and force the session seed to 1337. Both defeat mechanisms
|
|
that were introduced ~2.7 — **two years after 0.9.10** — and are absent from
|
|
this build:
|
|
|
|
- 0.9.10 accepts a plaintext, unsigned `query_cur_region` (no `{content,sign}`
|
|
wrapper, no RSA), so there is no signature to bypass.
|
|
- 0.9.10 carries the session seed as the plaintext `secretKey` field in
|
|
`GetPlayerTokenRsp`, fed straight into MT19937-64. Our gameserver already
|
|
sets it to `1337`, so the seed already matches with no patch.
|
|
|
|
So for 0.9.10 the dispatch redirect is the only client patch required.
|
|
`rsapatch.js` is included as an optional, documented equivalent for signed
|
|
builds (2.7+); it is NOT loaded by `gadget.config` and its byte patterns are
|
|
4.2-specific — fill in offsets/method names for the exact build before use.
|
|
|
|
## Build
|
|
|
|
Requires the MSVC C++ toolset (VS 2022 BuildTools or newer).
|
|
|
|
```
|
|
powershell -ExecutionPolicy Bypass -File build.ps1
|
|
```
|
|
|
|
Produces `dist/version.dll` (x64, static CRT — depends only on `KERNEL32.dll`).
|
|
CMake is also provided (`cmake -B build -A x64 && cmake --build build --config Release`).
|
|
|
|
## Deploy
|
|
|
|
```
|
|
powershell -ExecutionPolicy Bypass -File deploy.ps1 -GameDir "D:\cbt1"
|
|
```
|
|
|
|
Copies `version.dll`, `gadget.dll`, `gadget.config`, `redirect.js` into the
|
|
game folder (backs up any existing `version.dll`). Then start the SDK
|
|
(`:8899`) and gameserver, and launch `GenshinImpact.exe`.
|
|
|
|
## Files
|
|
|
|
| File | Role |
|
|
|------|------|
|
|
| `src/exports.h` | 17 forwarded `version.dll` exports |
|
|
| `src/dllmain.cpp` | proxy entry, IL2CPP wait, gadget bootstrap, logging |
|
|
| `dist/redirect.js` | Frida script: HTTP dispatch redirect |
|
|
| `dist/gadget.config` | Frida gadget config (script mode, auto-resume) |
|
|
| `dist/rsapatch.js` | optional RSA/seed patch for signed builds (unused on 0.9.10) |
|
|
| `dist/gadget.dll` | Frida gadget (x64) |
|
|
| `build.ps1` / `build.bat` / `CMakeLists.txt` | build the proxy |
|
|
| `deploy.ps1` | copy the patch into the game folder |
|