Skip to content

Add LoadedApk callers to deoptimize list#414

Merged
JingMatrix merged 1 commit intomasterfrom
deopt
Nov 11, 2025
Merged

Add LoadedApk callers to deoptimize list#414
JingMatrix merged 1 commit intomasterfrom
deopt

Conversation

@JingMatrix
Copy link
Copy Markdown
Owner

This commit attempts to resolve an issue reported by users on recent OnePlus software updates where LSPosed modules are no longer able to hook the Application#attach method.

The prevailing theory is that the Android Runtime (ART) on these devices has become more aggressive with method inlining. This optimization can cause the relatively small Application#attach method to be directly embedded into its calling methods, which makes it invisible to the hooking framework.

This approach is adapted from a reportedly successful commit in a community fork (LSPosed-Irena). It identifies makeApplication and makeApplicationInner within the android.app.LoadedApk class as the key callers to deoptimize. By adding these methods to the BOOT_IMAGE list, the goal is to prevent ART from inlining them, thus preserving Application#attach as a distinct and hookable method.

@JingMatrix
Copy link
Copy Markdown
Owner Author

This commit is taken from re-zero001/LSPosed-Irena@33067fe.

It could possibly solve the issues #388 #396 #406.

@JingMatrix

This comment was marked as outdated.

This commit attempts to resolve an issue reported by users on recent OnePlus software updates where LSPosed modules are no longer able to hook the `Application#attach` method.

The prevailing theory is that the Android Runtime (ART) on these devices has become more aggressive with method inlining. This optimization can cause the relatively small `Application#attach` method to be directly embedded into its calling methods, which makes it invisible to the hooking framework.

This approach is adapted from a reportedly successful commit in a community fork (LSPosed-Irena). It identifies `makeApplication` and `makeApplicationInner` within the `android.app.LoadedApk` class as the key callers to deoptimize. By adding these methods to the `BOOT_IMAGE` list, the goal is to prevent ART from inlining them, thus preserving `Application#attach` as a distinct and hookable method.

Co-authored-by: Irena <140869597+re-zero001@users.noreply.github.com>
@JingMatrix
Copy link
Copy Markdown
Owner Author

JingMatrix commented Nov 10, 2025

To verify the inlining status of methods after OAT, we check the output of the following command:

adb shell '/apex/com.android.art/bin/oatdump --oat-file=/system/framework/arm64/boot-framework.oat' 

For example, the following section implies that android.app.Application.attach(method_index=6456) is inlined into android.app.Instrumentation.newApplication.

  76: android.app.Application android.app.Instrumentation.newApplication(java.lang.ClassLoader, java.lang.String, android.content.Context) (dex_method_idx=14096)
    DEX CODE:
      0x0000: 6e10 9987 0400           	| invoke-virtual {v4}, java.lang.String android.content.Context.getPackageName() // method@34713
      0x0003: 0c00                     	| move-result-object v0
      0x0004: 7020 ff36 0100           	| invoke-direct {v1, v0}, android.app.AppComponentFactory android.app.Instrumentation.getFactory(java.lang.String) // method@14079
      0x0007: 0c00                     	| move-result-object v0
      0x0008: 6e30 1816 2003           	| invoke-virtual {v0, v2, v3}, android.app.Application android.app.AppComponentFactory.instantiateApplication(java.lang.ClassLoader, java.lang.String) // method@5656
      0x000b: 0c00                     	| move-result-object v0
      0x000c: 6e20 3819 4000           	| invoke-virtual {v0, v4}, void android.app.Application.attach(android.content.Context) // method@6456
      0x000f: 1100                     	| return-object v0

...
      0x002c7cb0: b9407380	ldr w0, [x28, #112]
        StackMap[11] (native_pc=0x2c7cb4, dex_pc=0xc, register_mask=0x0, stack_mask=0b)
        InlineInfo[7] (depth=0, dex_pc=0x3, method_index=6456)
        InlineInfo[8] (depth=1, dex_pc=0x4, method_index=6508)
      0x002c7cb4: b9002340	str w0, [x26, #32]
      0x002c7cb8: 34000080	cbz w0, #+0x10 (addr 0x002c7cc8)
      0x002c7cbc: f9404a70	ldr x16, [tr, #144] ; card_table
      0x002c7cc0: 530a7f51	lsr w17, w26, #10
      0x002c7cc4: 38316a10	strb w16, [x16, x17]
      0x002c7cc8: aa1a03e0	mov x0, x26
      0x002c7ccc: a9425ff6	ldp x22, x23, [sp, #32]
      0x002c7cd0: a94367f8	ldp x24, x25, [sp, #48]
      0x002c7cd4: a9446ffa	ldp x26, x27, [sp, #64]
      0x002c7cd8: a9457bfc	ldp x28, lr, [sp, #80]
      0x002c7cdc: 910183ff	add sp, sp, #0x60 (96)
      0x002c7ce0: d65f03c0	ret
      0x002c7ce4: aa0003e1	mov x1, x0
      0x002c7ce8: aa1c03e0	mov x0, x28
      0x002c7cec: 97f120b1	bl #-0x3b7d3c (addr -0x000f0050)
        StackMap[12] (native_pc=0x2c7cf0, dex_pc=0xc, register_mask=0x0, stack_mask=0b)
        InlineInfo[9] (depth=0, dex_pc=0x3, method_index=6456)
        InlineInfo[10] (depth=1, dex_pc=0x0, method_index=6508)
        InlineInfo[11] (depth=2, dex_pc=0x12, method_index=7662)

@JingMatrix
Copy link
Copy Markdown
Owner Author

JingMatrix commented Nov 11, 2025

While in certain OnePlus devices, we can see in addition that android.app.Instrumentation.newApplication is inlined into android.app.LoadedApk.makeApplicationInner(boolean, android.app.Instrumentation, boolean) (dex_method_idx=14031):

  25: android.app.Application android.app.LoadedApk.makeApplicationInner(boolean, android.app.Instrumentation, boolean) (dex_method_idx=14420)
    DEX CODE:
      0x0000: 54c0 ee33                	| iget-object v0, v12, Landroid/app/Application; android.app.LoadedApk.mApplication // field@13294
      0x0002: 3800 0500                	| if-eqz v0, +5
      0x0004: 54c0 ee33                	| iget-object v0, v12, Landroid/app/Application; android.app.LoadedApk.mApplication // field@13294
      0x0006: 1100                     	| return-object v0
      0x0007: 1600 4000                	| const-wide/16 v0, #+64
      0x0009: 7120 2bf1 1000           	| invoke-static {v0, v1}, boolean android.os.Trace.isTagEnabled(long) // method@61739
      0x000c: 0a02                     	| move-result v2
      0x000d: 3802 0800                	| if-eqz v2, +8
      0x000f: 1b02 2e26 0100           	| const-string/jumbo v2, "makeApplication" // string@75310
      0x0012: 7130 2df1 1002           	| invoke-static {v0, v1, v2}, void android.os.Trace.traceBegin(long, java.lang.String) // method@61741
      0x0015: 6202 0d34                	| sget-object  v2, Landroid/util/ArrayMap; android.app.LoadedApk.sApplications // field@13325
      0x0017: 1d02                     	| monitor-enter v2
      0x0018: 6203 0d34                	| sget-object  v3, Landroid/util/ArrayMap; android.app.LoadedApk.sApplications // field@13325
      0x001a: 54c4 fe33                	| iget-object v4, v12, Ljava/lang/String; android.app.LoadedApk.mPackageName // field@13310
...
      0x00f8: 54cb eb33                	| iget-object v11, v12, Landroid/app/ActivityThread; android.app.LoadedApk.mActivityThread // field@13291
      0x00fa: 54bb de25                	| iget-object v11, v11, Landroid/app/IActivityThreadExt; android.app.ActivityThread.mOplusActivityThreadExt // field@9694
      0x00fc: 7240 932b ab97           	| invoke-interface {v11, v10, v7, v9}, void android.app.IActivityThreadExt.applyConfigurationToAppResourcesLocked(android.app.ResourcesManager, android.content.Context, android.content.res.Configuration) // method@11155
      0x00ff: 7110 e6f1 0700           	| invoke-static {v7}, void android.security.net.config.NetworkSecurityConfigProvider.handleNewApplication(android.content.Context) // method@61926
      0x0102: 54cb eb33                	| iget-object v11, v12, Landroid/app/ActivityThread; android.app.LoadedApk.mActivityThread // field@13291
      0x0104: 54bb c825                	| iget-object v11, v11, Landroid/app/Instrumentation; android.app.ActivityThread.mInstrumentation // field@9672
      0x0106: 6e40 cf36 5b74           	| invoke-virtual {v11, v5, v4, v7}, android.app.Application android.app.Instrumentation.newApplication(java.lang.ClassLoader, java.lang.String, android.content.Context) // method@14031
      0x0109: 0c0b                     	| move-result-object v11
      0x010a: 07b2                     	| move-object v2, v11
      0x010b: 6e20 8b1d 2700           	| invoke-virtual {v7, v2}, void android.app.ContextImpl.setOuterContext(android.content.Context) // method@7563
...
      0x003e4054: 340000c0	cbz w0, #+0x18 (addr 0x3e406c)
      0x003e4058: b9403ff8	ldr w24, [sp, #60]
      0x003e405c: b94037e1	ldr w1, [sp, #52]
      0x003e4060: f94002b5	ldr x21, [x21]
        StackMap[106] (native_pc=0x3e4064, dex_pc=0x106, register_mask=0x37c00003, stack_mask=0b1010000000000000000000000000001111011101100000000)
          v3:sp+44 v4:r28 v5:sp+32 v6:sp+64 v7:r25 v9:r24 v10:sp+48 v11:r29 v12:sp+184 v14:sp+192 
        InlineInfo[75] (depth=0, dex_pc=0xc, method_index=14031)
          v0:r22 v1:r29 v2:sp+32 v3:r28 v4:r25 
        InlineInfo[76] (depth=1, dex_pc=0x3, method_index=6302)
          v1:r22 v2:r25 
        InlineInfo[77] (depth=2, dex_pc=0x1, method_index=7452)
          v2:r0 
      0x003e4064: 17ffffe9	b #-0x5c (addr 0x3e4008)
      0x003e4068: aa0003f8	mov x24, x0
      0x003e406c: 340000f8	cbz w24, #+0x1c (addr 0x3e4088)
      0x003e4070: b9400300	ldr w0, [x24]
      0x003e4074: 6b17001f	cmp w0, w23
      0x003e4078: 54000080	b.eq #+0x10 (addr 0x3e4088)
      0x003e407c: b9402000	ldr w0, [x0, #32]
      0x003e4080: 35ffffa0	cbnz w0, #-0xc (addr 0x3e4074)
...

@JingMatrix JingMatrix merged commit f5af569 into master Nov 11, 2025
1 check passed
JingMatrix added a commit to JingMatrix/LSPatch that referenced this pull request Nov 19, 2025
See JingMatrix/Vector#414 for details
Close #52 as fixed.

Also update few gradle dependencies.
JingMatrix added a commit to JingMatrix/LSPatch that referenced this pull request Nov 19, 2025
See JingMatrix/Vector#414 for details
Close #52 as fixed.

Also update few gradle dependencies.
Dawid2849 pushed a commit to Dawid2849/ReLSPosed that referenced this pull request Nov 21, 2025
This commit attempts to resolve an issue reported by users on recent OnePlus software updates where LSPosed modules are no longer able to hook the `Application#attach` method.

Android Runtime (ART) on these devices has become more aggressive with method inlining. This optimization can cause the relatively small `Application#attach` method to be directly embedded into its (indirect) calling methods, which makes it invisible to the hooking framework.

This approach is adapted from a reportedly successful commit in a community fork (LSPosed-Irena). It identifies `makeApplication` and `makeApplicationInner` within the `android.app.LoadedApk` class as the key callers to deoptimize. By adding these methods to the `BOOT_IMAGE` list, the goal is to prevent ART from inlining them, thus preserving `Application#attach` as a distinct and hookable method.

Co-authored-by: Irena <140869597+re-zero001@users.noreply.github.com>
@JingMatrix JingMatrix deleted the deopt branch January 24, 2026 02:29
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.

Latest OnePlus August update renders modules unusable Few modules no longer work after Android 15 system update

1 participant