fix(grpc): forward IL2CPP MethodInfo* and contain swap failures - #2
Merged
Merged
Conversation
IL2CPP instance methods take a trailing MethodInfo* in the next free arg
register (x3 on ARM64). Dropping it leaves x3 polluted from the caller
and orig SendAsync / HttpHeadersRemove / TryAdd crash the moment orig
dereferences MethodInfo->methodPointer.
* Add trailing `void *mi` to HttpHeadersTryAdd_t, HttpHeadersRemove_t,
and GenericSendAsync_t — lockstep with AnalysisTune.m's convention.
* KFHookHttpMsgInvokerSendAsync now receives mi and forwards it to orig.
* Header swap callers pass NULL for mi (we don't have one to forward).
Also harden swapUserIdHeader against unexpected throws so login can
proceed with a stale x-user-id instead of aborting the process:
* Add `@catch (id e)` alongside `@catch (NSException *e)` to catch
non-NSException throws (e.g. C++ exceptions bridged as id).
* Wrap the swapUserIdHeader call site in its own @try/@catch so any
escape still falls through to orig SendAsync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR hardens the gRPC header swap hook by aligning IL2CPP instance method ABI (forwarding the trailing MethodInfo*) and containing swap failures so the original HttpMessageInvoker.SendAsync is always invoked.
Changes:
- Update function pointer typedefs and the
KFHookHttpMsgInvokerSendAsynchook signature to include/forward the trailingvoid *mi(IL2CPPMethodInfo*). - Add defensive
@try/@catchcontainment aroundswapUserIdHeaderand broaden catch handling for non-NSExceptionthrows.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+35
to
+38
| // IL2CPP instance methods are called with a trailing MethodInfo* in x3 (or | ||
| // the next available arg register). Omitting it leaves x3 polluted, and | ||
| // orig crashes the moment it dereferences MethodInfo. Keep these signatures | ||
| // in lockstep with AnalysisTune.m's `..., void *mi` convention. |
2 tasks
tkgstrator
added a commit
to IPA-Patch/KiouForge
that referenced
this pull request
Jun 26, 2026
) Picks up IPA-Patch/KIOU-Hook#2: fix(grpc): forward IL2CPP MethodInfo* and contain swap failures Resolves crashes around HttpMessageInvoker.SendAsync / HttpHeaders.Remove / HttpHeaders.TryAdd by adding the trailing MethodInfo* arg expected by IL2CPP, and hardens the x-user-id swap path with extra @try/@catch (id e) so login degrades to a stale x-user-id instead of aborting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
tkgstrator
added a commit
that referenced
this pull request
Jul 27, 2026
IL2CPP instance methods take a trailing MethodInfo* in the next free arg
register (x3 on ARM64). Dropping it leaves x3 polluted from the caller
and orig SendAsync / HttpHeadersRemove / TryAdd crash the moment orig
dereferences MethodInfo->methodPointer.
* Add trailing `void *mi` to HttpHeadersTryAdd_t, HttpHeadersRemove_t,
and GenericSendAsync_t — lockstep with AnalysisTune.m's convention.
* KFHookHttpMsgInvokerSendAsync now receives mi and forwards it to orig.
* Header swap callers pass NULL for mi (we don't have one to forward).
Also harden swapUserIdHeader against unexpected throws so login can
proceed with a stale x-user-id instead of aborting the process:
* Add `@catch (id e)` alongside `@catch (NSException *e)` to catch
non-NSException throws (e.g. C++ exceptions bridged as id).
* Wrap the swapUserIdHeader call site in its own @try/@catch so any
escape still falls through to orig SendAsync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
tkgstrator
added a commit
to IPA-Patch/KiouForge
that referenced
this pull request
Jul 27, 2026
) Picks up IPA-Patch/KIOU-Hook#2: fix(grpc): forward IL2CPP MethodInfo* and contain swap failures Resolves crashes around HttpMessageInvoker.SendAsync / HttpHeaders.Remove / HttpHeaders.TryAdd by adding the trailing MethodInfo* arg expected by IL2CPP, and hardens the x-user-id swap path with extra @try/@catch (id e) so login degrades to a stale x-user-id instead of aborting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
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
Fixes a class of crashes around
HttpMessageInvoker.SendAsync/HttpHeaders.Remove/HttpHeaders.TryAddcaused by missing IL2CPP ABI alignment, and adds defensive containment around the x-user-id swap so the login flow degrades gracefully instead of aborting the process.IL2CPP ABI (root cause)
IL2CPP instance methods take a trailing
MethodInfo*in the next free arg register (x3 on ARM64). Dropping it leaves x3 polluted from the caller, and orig SendAsync / HttpHeadersRemove / TryAdd crash the moment orig dereferencesMethodInfo->methodPointer.void *mitoHttpHeadersTryAdd_t,HttpHeadersRemove_t, andGenericSendAsync_t— lockstep withAnalysisTune.m's..., void *miconvention.KFHookHttpMsgInvokerSendAsyncnow receivesmiand forwards it to orig.NULLformi(we don't have one to forward).Crash containment
@catch (id e)alongside@catch (NSException *e)to catch non-NSExceptionthrows (e.g. C++ exceptions bridged asid).swapUserIdHeadercall site in its own@try/@catchso any escape still falls through to orig SendAsync — login can proceed with a stalex-user-idinstead of aborting the process.Behavior
Verified locally by tkgstrator.
🤖 Generated with Claude Code