chore/fix: align build with KiouForge + make 1.0.2 chinlan actually work#44
Open
tkgstrator wants to merge 8 commits into
Open
chore/fix: align build with KiouForge + make 1.0.2 chinlan actually work#44tkgstrator wants to merge 8 commits into
tkgstrator wants to merge 8 commits into
Conversation
Sets up vendor/KIOU-Hook (IPA-Patch/KIOU-Hook) alongside the existing Chinlan and Kanade submodules. Nothing in the current tree consumes it yet — this only makes the shared IPA-Patch hook catalog/library available for future incremental adoption. Matches the KiouForge tree shape so shared code can be picked up without extra setup.
… IPA_CHINLAN
- Adopts KiouForge's Makefile shape so the two IPA-Patch tweaks share
the same build surface:
* make deploy target (scp + trollstorehelper install force + relaunch)
* BUNDLE_ID_SUFFIX for installing alongside the original app
* IPA_OUT / --output / --bundle-id-suffix wired into build_patched_ipa.sh
* KIOU_HOOK_DIR pointer at vendor/KIOU-Hook and -Ivendor/KIOU-Hook
in CFLAGS so future incremental adoption of the shared catalog
is drop-in.
* Sources/Chinlan/chinlan.m compiled in (IPAChinlanFindImage /
IPAChinlanResolveOrig — the generic runtime side of Chinlan;
currently unused by KEB, will be picked up as caves migrate).
* TARGET_VERSION default bumped to 1.0.2 (the current shipped
build) so a plain 'make ipa' targets the version most users
have.
- Renames the KEB-local KIOU_CHINLAN compile flag to the shared
IPA_CHINLAN flag that KIOU-Hook, Chinlan, and KiouForge already use.
Purely mechanical rename across Sources/KiouEngineBridge; no
behaviour change. Without this, dropping any KIOU-Hook or Chinlan
source file into the KEB tree would require rewriting its #if
guards, which defeats the point of the shared catalog.
Verified: make chinlan, make all, make jailed all link clean.
Picks up 'feat(build): --bundle-id-suffix flag on build_patched_ipa.sh' (IPA-Patch/Kanade feat/bundle-id-suffix branch, same commit KiouForge pins). Required by the make deploy path — the Makefile now passes --bundle-id-suffix through, but the previous shared pin (v0.1.2) didn't know that flag.
1.0.2's __TEXT,__eh_frame grew to 0x81ACE58..0x826F5E8, fully covering the inherited 1.0.1 CAVE_REGION (0x826A000..0x826C000). Writing caves there clobbered DWARF CFI bytes and verify_patches refused every site with 'cave was not zero-fill nor the matching payload'. Move CAVE_REGION to the verified-zero tail after __oslogstring at 0x8270040..0x8272040 (8 KB; UnityFramework section tail). lief-verified all-zero; B reach from the farthest site (0x6082AC0) is well within the +/-128 MB AArch64 limit. Verified end-to-end: make ipa TARGET_VERSION=1.0.2 now succeeds and produces Kiou-1.0.2-patched.ipa. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ENTRY_SLOT_BASE_RVA (0x091E91B8) inherited from 1.0.1 lands in __DATA,__common in 1.0.2 — that section is pre-initialised, so the recipe's 32-slot block is non-zero on disk. At runtime an entry cave's BLR through the slot loads that garbage as a function pointer and crashes (Login, AccountExists, ...). Relocate to the verified-zero tail of __DATA,__bss at 0x8F9D3B8 (0x100 = 32 slots * 8 B, fits ahead of PROBED_HOOK_SLOT_RVA). bss is guaranteed zero on launch, so cave -> BLR through an unpublished slot is harmless until the dylib publishes the hook fn ptr. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The prior fix/v1_0_2-cave-region cherry-picks relocated CAVE_REGION,
HOOK_SLOT_RVA, and ENTRY_SLOT_BASE_RVA on the Python side (recipes/
v1_0_2.py) but left the matching C-side constants pointing at the
1.0.1 offsets. That was silent-catastrophic:
* KIOU_BR_HOOK_SLOT_RVA — the recipe patches cave stubs to LDR from
unityBase + 0x8F9D4B8, but KEBBridgeChinlanPublish wrote the
dispatcher pointer to unityBase + 0x8F90CC0 (1.0.1's __bss slot,
which il2cpp overwrites during lazy init). Cave read NULL → BLR 0
→ SIGSEGV on the first SendAsync fire during login.
* KIOU_BR_ENTRY_SLOT_BASE_RVA — same story for the entry-slot table:
caves LDR from unityBase + 0x8F9D3B8, publish wrote to
unityBase + 0x091E91B8 (1.0.1's __common region, which carries
live KIOU data on 1.0.2). Every CAVE_ENTRY hook BLR'd garbage.
* KIOU_BR_CAVE_REGION_START — the cave-bypass entry addresses that
kiou_bridge_bypass_entry_for_hook() computes (used for injection
orig-chain fallbacks) landed in __eh_frame instead of the real
cave region. Any hook body that touched g_inject_entry[i] would
BLR into DWARF CFI bytes.
All three now match recipes/v1_0_2.py. Verified live on 1.0.2 build
12 (see the log line 'cave_start=0x8270040 cave_size=84 count=37').
…nfo* ABI
Two bugs in one path made 'switch account' silent-crash on 1.0.2:
1. RVA drift — the 1.0.1 RVA (0x5CF712C) was carried forward without
a version guard. On 1.0.2 that address is a different function,
so KEBNavigateToTitleScene's raw-address fallback (used on
chinlan, where the JB suppress hook isn't installed) BLR'd into
the wrong body. Updated to the 1.0.2 RVA (0x5CFC394), verified
against assets/1.0.2/dump.cs.
2. Missing MethodInfo* in the typedef — il2cpp-generated static
methods take (args..., MethodInfo *mi) with mi in the last arg
register. On JB the caller supplied a real mi in X1, which flowed
through MSHookFunction's trampoline verbatim, so the 1-arg
typedef 'happened to work' by silently ignoring X1. On chinlan
when we call the raw method directly, X1 is register garbage —
the method dereferences it early and faults with no .ips.
Both KEBNavigateToTitleScene and the JB suppress hook now use the
2-arg signature (ct, mi) and pass NULL for mi. RunAsync is a plain
static (not shared-generic), so NULL mi is safe — this matches
KIOU-Hook's KIOUNavigateToTitleScene (vendor/KIOU-Hook/Hook/
AccountObserve.m:352) which uses the same call shape.
Verified live: 'switch account' → 'BackToTitleSequence.RunAsync
invoked' → back-to-title dialog.
…s -40004)
On 1.0.2 build 12 the previous x-user-id swap site
(HttpMessageInvoker.SendAsync) is inside Yaha's borrow scope — even
just reading the request-headers dictionary crashes the process
silently (Rust panic → SIGABRT, no .ips). Without a working swap the
server rejects account-switch logins with -40004 because LoginArgs
now says 'deviceId=<new>' but the auth header still names the
previous user.
KIOU-Hook already ships the proven fix: swap at the managed-only
Project.Network.HeaderProvider.SetOrUpdateHeader site (called well
before HttpMessageInvoker) and keep SendAsync as a bare passthrough.
This commit ports the same pattern into KEB:
* enum + entry-slot for KIOU_BR_HOOK_HEADER_PROVIDER_SET_OR_UPDATE_HEADER
(Internal.h)
* recipe row wired for both 1.0.1 (0x5BD4C80) and 1.0.2 (0x5BD9EE8)
— CAVE_ENTRY, same 'f657bda9' prologue on both builds
* HookHeaderProviderSetOrUpdateEntry body — inspects the key
il2cpp-string, replaces the value with a fresh il2cpp-string
naming the pending account's user id, then forwards to bypass
* ChinlanDispatcher wires the new entry slot at publish time
* HookHttpMsgInvokerSendAsyncEntry drops swapUserIdHeader — it is
now a bare passthrough that never touches request/self
Verified live on 1.0.2 build 12: 'switch account' now logs
'[HEADER] x-user-id swapped → <target-user-id>' at 03:42:57 and
proceeds through login instead of dying with -40004.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
KiouForge/KIOU-Hook ツリーと足並みを揃える build/tooling 整合と、1.0.2 chinlan build を実機で完動させるための修正一式。 元は Makefile align だけの PR だったが、実機 deploy → login → account switch まで通す過程で 1.0.2 側の未解決バグ 3 系統を潰したので同じ PR に載せた。
Commits
1. Align 系(Makefile / submodule / rename)
51a6026—vendor/KIOU-Hookを submodule として追加(Chinlan / Kanade と同じ寄せ方)。 catalog 共有の下準備。a29b311— Makefile を KiouForge 形に整合:make deploytarget(scp →trollstorehelper install force→ 再起動)BUNDLE_ID_SUFFIX/IPA_OUT/--output/--bundle-id-suffixKIOU_HOOK_DIR+-Ivendor/KIOU-HookSources/Chinlan/chinlan.mを FILES に追加TARGET_VERSION ?= 1.0.2-DKIOU_CHINLAN=1→-DIPA_CHINLAN=1+ KEB 全 15 ソースのKIOU_CHINLAN→IPA_CHINLAN一括 rename(KIOU-Hook / Chinlan / KiouForge と共通化)fc5bfb7— Kanade submodule をc29a372に bump(--bundle-id-suffixサポートのため。 KiouForge と同じ pin)3df07bd/0aa727d—fix/v1_0_2-cave-regionの 2 fix を cherry-pick(recipes/v1_0_2.py の CAVE_REGION を__eh_frameから外し、ENTRY_SLOT_BASE を__bssに移す)2. 1.0.2 chinlan 完動化
36c375c—fix(chinlan/1.0.2): sync C-side slot/entry/cave RVAs with recipe fix—fix/v1_0_2-cave-regionが recipe だけ 1.0.2 に更新してた片手落ち fix。Internal.hのKIOU_BR_HOOK_SLOT_RVA/KIOU_BR_ENTRY_SLOT_BASE_RVA/KIOU_BR_CAVE_REGION_STARTを recipe と同じ 1.0.2 値に。 これがないと cave が publish 先を見つけられずに BLR NULL → SIGSEGV。76a6c03—fix(chinlan/1.0.2): update BackToTitleSequence.RunAsync RVA + MethodInfo* ABI— 2 バグ複合。 (a) 1.0.1 の0x5CF712Cを 1.0.2 の0x5CFC394に。 (b) il2cpp static method の hiddenMethodInfo *miを signature に追加 ((ct)→(ct, mi)) してfn(NULL, NULL)で呼ぶ。 chinlan では JB の trampoline を経由しないので X1 の register 残骸を渡すと即クラッシュしていた。768c9f7—feat(chinlan/1.0.2): port HeaderProvider hook to swap x-user-id (fixes -40004)— KEB の x-user-id swap はHttpMessageInvoker.SendAsynchook body 内で行っていたが、1.0.2 build 12 の Yaha (Cysharp) borrow-tracker と相互作用して silent Rust panic を起こす。 KIOU-Hook が既に採用している「managed 層のProject.Network.HeaderProvider.SetOrUpdateHeader(RVA0x5BD9EE8) で swap、SendAsync は passthrough」パターンを KEB へ移植:common.py/v1_0_1.py/v1_0_2.pyすべてに追加、1.0.1 用 RVA0x5BD4C80も同時追加)HookHeaderProviderSetOrUpdateEntry実装(value il2cpp-string を差し替える)ChinlanDispatcher.mに entry slot publish 行を追加HookHttpMsgInvokerSendAsyncEntryからswapUserIdHeaderを除去して bare passthrough にTest evidence(実機 1.0.2 build 12 chinlan / iPhone10,1 iOS 16.7.16 TrollStore)
make chinlan/make all/make jailed— link cleanmake deploy TARGET_VERSION=1.0.2 DECRYPTED_IPA=<path>— 完走[HEADER] x-user-id swapped → <target-user-id>livelog、-40004は 0 件.ipsなし(deploy 前のKIOU-2026-07-02-025417.ipsが最新のまま)What's still NOT in
KIOU_BR_HOOK_*catalog を KIOU-Hook 側の共有 catalog にマージする作業は別 PR(KIOU-Hook 側 catalog 拡張とセットで扱う話)。fix/v1_0_2-cave-region/feat/deploy-targetの open ブランチはこの PR に取り込み済みなので、マージ後 close で OK。🤖 Generated with Claude Code