Mobile Development 24 min read

How a Hidden iOS 16 Keyboard Crash Was Discovered, Analyzed, and Patched

An Ant Group engineer reverse‑engineered a severe iOS 16 keyboard crash affecting the Alipay app, traced it to a faulty lock in UIKeyboardTaskQueue, and implemented an assembly‑level patch that eliminated the bug across millions of devices.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
How a Hidden iOS 16 Keyboard Crash Was Discovered, Analyzed, and Patched

Background

Ant Group launched a technical challenge to solve a high‑frequency keyboard crash on iOS 16 observed in the Alipay app (version 10.5.0.6000). The crash caused SIGSEGV at address 0x2ab3106e0, originating from _objc_retain in the system keyboard task queue.

Crash Information

Key crash details include hardware model iPhone 12 Pro Max, iOS 16.6, and the stack trace showing UIKeyboardTaskQueue methods such as performDeferredTaskIfIdle and continueExecutionOnMainThread. The crash is caused by a dangling pointer when the array _deferredTasks is accessed.

Analysis Process

Collected crash logs and identified the offending function offsets.

Used lldb commands (breakpoints, backtrace, frame select) to locate the exact code paths.

Extracted all methods of UIKeyboardTaskQueue via a custom script and examined the assembly.

Mapped reads and writes of the _deferredTasks and _lock members, discovering six read and four write methods.

Found that -[UIKeyboardTaskQueue continueExecutionOnMainThread] calls tryLockWhenReadyForMainThread but does not return when the lock fails, leading to unsafe array access and a dangling pointer.

Root Cause

The bug lies in -[UIKeyboardTaskQueue continueExecutionOnMainThread]: after a failed tryLockWhenReadyForMainThread, the code continues to read _deferredTasks and later calls _objc_retain, causing a crash. This lock‑failure path is only present in iOS 16; iOS 15 and iOS 17 correctly return early.

Solution

Two patch strategies were considered. The chosen approach rewrites -[UIKeyboardTaskQueue tryLockWhenReadyForMainThread] in assembly to return early on lock failure, preventing the unsafe execution path.

#ifdef __arm64__
// Assembly implementation of the fixed method
_fix_UIKeyboardTaskQueue_tryLockWhenReadyForMainThread:
    ...
    cbz    x0, 1f   // If lock fails, jump to early return
    ret               // Lock succeeded, continue normally
1:
    // Simulate return to caller without executing unsafe code
    ldp    x29, x30, [sp, #0x20]
    ldp    x20, x19, [sp, #0x10]
    add    sp, sp, #0x30
    ret
#endif

The patch is injected at app launch using class_replaceMethod for iOS 16 devices.

Results

After enabling the patch in Alipay version 10.5.16.6000, daily crash PV dropped to zero, reducing overall crash volume by ~90% across all versions.

mobile developmentiOSAssemblyKeyboardReverse engineeringCrashBug Fix
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.