Fix SIGILL during remote execution by clearing PSTATE.BTYPE on AArch64#133
Open
JingMatrix wants to merge 2 commits intomasterfrom
Open
Fix SIGILL during remote execution by clearing PSTATE.BTYPE on AArch64#133JingMatrix wants to merge 2 commits intomasterfrom
JingMatrix wants to merge 2 commits intomasterfrom
Conversation
We implement a connection check to bypass process flag retrieval and module execution for isolated processes when the zygisk daemon is unreachable.
1 task
1 task
During the entry point hijack phase on ARMv9 hardware with Branch Target Identification (BTI) enabled, dispatching remote calls to bionic functions (such as `dlopen`) resulted in an immediate Branch Target Exception (SIGILL). This crash is caused by a stale Branch Type (`BTYPE`) state. When the Android dynamic linker transfers control to the target's `AT_ENTRY`, it uses an indirect branch instruction (`BR`). This hardware action updates the CPU's `PSTATE` register, setting the `BTYPE` field to `0b11` (Indirect Jump). When the tracer pauses the process and redirects execution to `dlopen`, the CPU inherits this `PSTATE`. Modern Android bionic libraries are compiled with BTI and start with `PACIASP` or `BTI c` landing pads. These landing pads strictly require the incoming `BTYPE` to be `0b01` (Direct Call) or `0b10` (Indirect Call). Confronted with `0b11`, the CPU assumes a JOP (Jump-Oriented Programming) exploit and raises a SIGILL. This commit resolves the issue by clearing the `BTYPE` field (bits 10 and 11) in the `pstate` register structure prior to initiating any remote calls. Resetting the field to `0b00` prevents the hardware from enforcing BTI validation on the immediate next instruction. The original `PSTATE` is preserved in the register backup, ensuring that the target executable can securely validate its own BTI landing pad when execution is fully restored. References: https://developer.android.com/ndk/guides/abis#armv9_enabling_pac_and_bti_for_cc
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.
During the entry point hijack phase on ARMv9 hardware with Branch Target Identification (BTI) enabled, dispatching remote calls to bionic functions (such as
dlopen) resulted in an immediate Branch Target Exception (SIGILL).This crash is caused by a stale Branch Type (
BTYPE) state. When the Android dynamic linker transfers control to the target'sAT_ENTRY, it uses an indirect branch instruction (BR). This hardware action updates the CPU'sPSTATEregister, setting theBTYPEfield to0b11(Indirect Jump).When the tracer pauses the process and redirects execution to
dlopen, the CPU inherits thisPSTATE. Modern Android bionic libraries are compiled with BTI and start withPACIASPorBTI clanding pads. These landing pads strictly require the incomingBTYPEto be0b01(Direct Call) or0b10(Indirect Call). Confronted with0b11, the CPU assumes a JOP (Jump-Oriented Programming) exploit and raises a SIGILL.This commit resolves the issue by clearing the
BTYPEfield (bits 10 and 11) in thepstateregister structure prior to initiating any remote calls. Resetting the field to0b00prevents the hardware from enforcing BTI validation on the immediate next instruction. The originalPSTATEis preserved in the register backup, ensuring that the target executable can securely validate its own BTI landing pad when execution is fully restored.References: https://developer.android.com/ndk/guides/abis#armv9_enabling_pac_and_bti_for_cc