Skip to content

Social Club: the renderer bridge for helper build 2.4.0.296 - #559

Merged
125hz merged 1 commit into
willfaust:mainfrom
125hz:fix/sc-helper-2.4.0.296
Nov 4, 2026
Merged

125hz merged 1 commit into
willfaust:mainfrom
125hz:fix/sc-helper-2.4.0.296

Conversation

@125hz

@125hz 125hz commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

Social Club updated to 2.4.0.296 on 2026-11-03 and its launcher stopped loading its pages under Madeira: [sc-rph] recognised one helper build only (TimeDateStamp 0x6a86d563), so SocialClubHelper.exe ran unpatched under --single-process, the launcher's UI waited for a page that never became ready and gave up with a website-load-failed error. The launcher reinstalls the current client, so there is no going back.

What changed

  • The patch is now a table of analysed builds (ios_sch_builds): per build its RVAs, the SHA-256 of every code range relied on, the code it installs, its hook sites and the .data ranges that must be zero. The first build's entry writes exactly the bytes it wrote before.
  • 2.4.0.296's entry installs the same bridge: the GetRenderProcessHandler thunk, the renderer MessageLoop adapter with its task callbacks, the renderer drain and the IPC split (separate renderer manager, retained page channels, 64-slot bound).
  • That build leaves 792 bytes past .text's VirtualSize (the first build 3.2 KB), so its variant carries no diagnostic traces, uses compact Win64 forms for the manager getter, destructor and direct-load hooks, and places the four small task callbacks and two 15-byte IPC stubs in int3 padding between functions (a RET before, the next .pdata function after, checked as all-int3 and by digest before anything is written).
  • Build selection is by TimeDateStamp and SizeOfImage; a mismatch logs the stamp, the size and the reason and writes nothing. No helper bytes are in the source, only digests. MADEIRA_SC_RENDER_HANDLER=0, MADEIRA_SC_CEF=0 and MADEIRA_SC_IPC_SPLIT=0 apply to both builds.

Tests

  • check-sc-render-loop, -ipc-split and -render-handler run once per build (sc-render-handler.S is the thunk's source); check-sc-runstate, -ui-close and -ipc-rebind confirm the 2.4.0.296 build has no trace.
  • New check-sc-helper-binary.py maps a real helper the way the loader does (never runs it), checks every digest, and runs the guard and the patch on the copy in both bases with the IPC split on and off, then checks that switches, another image name and one-byte changes in any window write nothing. MADEIRA_SC_HELPER_EXE names the helper; without it the test is skipped. The 2.4.0.296 helper passes.

Device-tested in the sc-1103 build on top of main.

🤖 Generated with Claude Code

Social Club updated to 2.4.0.296 on 2026-11-03 and its launcher no longer
loaded its pages under Madeira: [sc-rph] recognised one helper build only
(TimeDateStamp 0x6a86d563), so SocialClubHelper.exe ran unpatched under
--single-process, the launcher's UI waited for a page that never became
ready and gave up with a website-load-failed error. The launcher
reinstalls the current client, so there is no going back to the old one.

The patch is now a table of analysed builds (ios_sch_builds): per build
its RVAs, the SHA-256 of every code range relied on, the code it installs,
its hook sites and the .data ranges that must be zero. The first build's
entry writes exactly the bytes it wrote before. 2.4.0.296's entry
installs the same bridge: the GetRenderProcessHandler thunk, the renderer
MessageLoop adapter with its task callbacks, the renderer drain and the
IPC split (separate renderer manager, retained page channels, 64-slot
bound). That build leaves 792 bytes past .text's VirtualSize (the first
3.2 KB), so its variant carries no diagnostic traces (RunState, IPC
rebind, UI notifications), uses compact Win64 forms for the manager
getter, destructor and direct-load hooks, and places the four 5-11 byte
task callbacks and two 15-byte IPC stubs in int3 padding between
functions (a RET before, the next .pdata function after, checked as
all-int3 and by digest before anything is written). Where 2.4.0.296's
code differs (browser-only handler registration in Initialize, Channel
Response skipping a Connect to the current channel, the capture site's
displaced instruction), the digests cover the new bytes and the stubs
replay the new form.

Build selection is by TimeDateStamp and SizeOfImage; a mismatch logs the
stamp, the size and the reason and writes nothing. No helper bytes are in
the source, only digests. MADEIRA_SC_RENDER_HANDLER=0, MADEIRA_SC_CEF=0
and MADEIRA_SC_IPC_SPLIT=0 apply to both builds.

Tests: check-sc-render-loop, -ipc-split and -render-handler run once per
build (sc-render-handler.S is the thunk's source); check-sc-runstate,
-ui-close and -ipc-rebind confirm the 2.4.0.296 build has no trace. New
check-sc-helper-binary.py maps a real helper the way the loader does
(never runs it), checks every digest, and runs the guard and the patch on
the copy, in both bases with the IPC split on and off, then checks that
switches, another image name and one-byte changes in any window write
nothing: MADEIRA_SC_HELPER_EXE names the helper; without it the test is
skipped. The 2.4.0.296 helper passes it; the device run is still to come.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
125hz added a commit that referenced this pull request Nov 4, 2026
Social Club updated to 2.4.0.296 on 2026-11-03 and its launcher no longer
loaded its pages under Madeira: [sc-rph] recognised one helper build only
(TimeDateStamp 0x6a86d563), so SocialClubHelper.exe ran unpatched under
--single-process, the launcher's UI waited for a page that never became
ready and gave up with a website-load-failed error. The launcher
reinstalls the current client, so there is no going back to the old one.

The patch is now a table of analysed builds (ios_sch_builds): per build
its RVAs, the SHA-256 of every code range relied on, the code it installs,
its hook sites and the .data ranges that must be zero. The first build's
entry writes exactly the bytes it wrote before. 2.4.0.296's entry
installs the same bridge: the GetRenderProcessHandler thunk, the renderer
MessageLoop adapter with its task callbacks, the renderer drain and the
IPC split (separate renderer manager, retained page channels, 64-slot
bound). That build leaves 792 bytes past .text's VirtualSize (the first
3.2 KB), so its variant carries no diagnostic traces (RunState, IPC
rebind, UI notifications), uses compact Win64 forms for the manager
getter, destructor and direct-load hooks, and places the four 5-11 byte
task callbacks and two 15-byte IPC stubs in int3 padding between
functions (a RET before, the next .pdata function after, checked as
all-int3 and by digest before anything is written). Where 2.4.0.296's
code differs (browser-only handler registration in Initialize, Channel
Response skipping a Connect to the current channel, the capture site's
displaced instruction), the digests cover the new bytes and the stubs
replay the new form.

Build selection is by TimeDateStamp and SizeOfImage; a mismatch logs the
stamp, the size and the reason and writes nothing. No helper bytes are in
the source, only digests. MADEIRA_SC_RENDER_HANDLER=0, MADEIRA_SC_CEF=0
and MADEIRA_SC_IPC_SPLIT=0 apply to both builds.

Tests: check-sc-render-loop, -ipc-split and -render-handler run once per
build (sc-render-handler.S is the thunk's source); check-sc-runstate,
-ui-close and -ipc-rebind confirm the 2.4.0.296 build has no trace. New
check-sc-helper-binary.py maps a real helper the way the loader does
(never runs it), checks every digest, and runs the guard and the patch on
the copy, in both bases with the IPC split on and off, then checks that
switches, another image name and one-byte changes in any window write
nothing: MADEIRA_SC_HELPER_EXE names the helper; without it the test is
skipped. The 2.4.0.296 helper passes it; the device run is still to come.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@125hz
125hz merged commit 5fda6a0 into willfaust:main Nov 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant