Dynamic code loading as a trojan horse

Dynamic code loading (DCL) allows an application to load additional libraries at runtime. It has its place, but can be abused. One study from 2017 showed how violation of Google Play's content policies and delivery of malware is possible this way, and highlighted the fact that DCL is often done by third-party SDKs, meaning that app developers may not be aware of what their app is doing if it uses such SDKs.(1) The ability to disable DCL via memory or storage on a per-app basis in GrapheneOS(2) allows you to see what applications are trying to do when attemping DCL. I will update this page over time to document the behaviour of various apps and which ones work with DCL disabled. This transparency has two goals: to educate smartphone users, and to encourage developers to be more ethical. A sufficient number of unhappy app store reviews can make a difference.

Forest

Forest(3) is a lovely app. Forest also uses DCL via memory to load Facebook ads and DCL via storage to load Google ads both upon opening and closing the app. Fortunately, it works with them disabled.

Details (memory)

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: cc.forestapp:49500000, targetSdk 35

package: cc.forestapp:49500000

DCL denial type: InMemoryDexFile
process: cc.forestapp
thread: Thread-25

java.lang.SecurityException
	at android.ext.dcl.DynCodeLoading.checkInMemoryDexFileOpen(DynCodeLoading.java:81)
	at dalvik.system.DexFile.openInMemoryDexFilesNative(Native Method)
	at dalvik.system.DexFile.openInMemoryDexFiles(DexFile.java:428)
	at dalvik.system.DexFile.(DexFile.java:136)
	at dalvik.system.DexPathList.initByteBufferDexPath(DexPathList.java:264)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:226)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:40)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:52)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:63)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.createInMemoryClassLoader(Unknown Source:98)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.makeAdsSdkClassLoader(Unknown Source:6)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.doMakeLoader(Unknown Source:35)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.access$000(Unknown Source:0)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory$1.run(Unknown Source:17)
	at java.lang.Thread.run(Thread.java:1119)
Details (storage)

type: storage_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: cc.forestapp:49500000, targetSdk 35

package: cc.forestapp:49500000

DCL denial type: DexFileOpen
process: cc.forestapp
thread: Thread-3

java.lang.SecurityException: DCL via storage, path: /data/user_de/0/com.google.android.gms/app_chimera/m/00000005/dl-AdsFdrDynamite.integ_251815204100000.apk
	at android.ext.dcl.DynCodeLoading.checkDexFileOpen(DynCodeLoading.java:131)
	at dalvik.system.DexFile.openDexFileNative(Native Method)
	at dalvik.system.DexFile.openDexFile(DexFile.java:406)
	at dalvik.system.DexFile.(DexFile.java:128)
	at dalvik.system.DexFile.(DexFile.java:101)
	at dalvik.system.DexPathList.loadDexFile(DexPathList.java:438)
	at dalvik.system.DexPathList.makeDexElements(DexPathList.java:397)
	at dalvik.system.DexPathList.(DexPathList.java:166)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:160)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:105)
	at dalvik.system.PathClassLoader.(PathClassLoader.java:71)
	at dalvik.system.DelegateLastClassLoader.(DelegateLastClassLoader.java:114)
	at m2.aa.c(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):58)
	at m2.aj.b(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):69)
	at com.google.android.gms.dynamiteloader.DynamiteLoaderV2.loadModule2NoCrashUtils(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):114)
	at m2.cn.a(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):73)
	at m2.p.onTransact(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):21)
	at android.os.Binder.transact(Binder.java:1297)
	at com.google.android.gms.internal.common.zza.zzB(Unknown Source:7)
	at com.google.android.gms.dynamite.zzq.zzf(Unknown Source:17)
	at com.google.android.gms.dynamite.DynamiteModule.load(Unknown Source:260)
	at com.google.android.gms.ads.internal.util.client.zzs.zzc(Unknown Source:4)
	at com.google.android.gms.ads.internal.util.client.zzs.zzb(Unknown Source:0)
	at com.google.android.gms.internal.ads.zzbov.run(Unknown Source:97)
	at java.lang.Thread.run(Thread.java:1119)

DragonVale

DragonVale tries to use DCL via memory to load Facebook ads. The app works if it is disabled.

Details

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: com.backflipstudios.android.dragonvale:2557001, targetSdk 34

package: com.backflipstudios.android.dragonvale:2557001

DCL denial type: InMemoryDexFile
process: com.backflipstudios.android.dragonvale
thread: Thread-7

java.lang.SecurityException
	at android.ext.dcl.DynCodeLoading.checkInMemoryDexFileOpen(DynCodeLoading.java:81)
	at dalvik.system.DexFile.openInMemoryDexFilesNative(Native Method)
	at dalvik.system.DexFile.openInMemoryDexFiles(DexFile.java:428)
	at dalvik.system.DexFile.(DexFile.java:136)
	at dalvik.system.DexPathList.initByteBufferDexPath(DexPathList.java:264)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:226)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:40)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:52)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:63)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.createInMemoryClassLoader(DynamicLoaderFactory.java:14)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.makeAdsSdkClassLoader(DynamicLoaderFactory.java:2)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.doMakeLoader(DynamicLoaderFactory.java:6)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.access$000(DynamicLoaderFactory.java:1)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory$1.run(DynamicLoaderFactory.java:3)
	at java.lang.Thread.run(Thread.java:1119)

Caffè Nero

Caffè Nero's app uses DCL via storage for integration of Google Maps into the app. I consider this to be an acceptable use of DCL. If it is disabled, store information pages on the search tab will say "Google Play services are updating", and the location of the store will not be shown in the usual embedded Google Maps box. If you wish to use the Caffè Nero app but avoid Google Maps, now you know how to.

Details

type: storage_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: com.yoyowallet.caffenero:402421050, targetSdk 35

package: com.yoyowallet.caffenero:402421050

DCL denial type: DexFileOpen
process: com.yoyowallet.caffenero
thread: main

java.lang.SecurityException: DCL via storage, path: /data/user_de/0/com.google.android.gms/app_chimera/m/00000014/dl-MapsCoreDynamite.integ_252725201100400.apk
	at android.ext.dcl.DynCodeLoading.checkDexFileOpen(DynCodeLoading.java:131)
	at dalvik.system.DexFile.openDexFileNative(Native Method)
	at dalvik.system.DexFile.openDexFile(DexFile.java:406)
	at dalvik.system.DexFile.(DexFile.java:128)
	at dalvik.system.DexFile.(DexFile.java:101)
	at dalvik.system.DexPathList.loadDexFile(DexPathList.java:438)
	at dalvik.system.DexPathList.makeDexElements(DexPathList.java:397)
	at dalvik.system.DexPathList.(DexPathList.java:166)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:160)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:105)
	at dalvik.system.PathClassLoader.(PathClassLoader.java:71)
	at dalvik.system.DelegateLastClassLoader.(DelegateLastClassLoader.java:114)
	at m2.aa.c(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):58)
	at m2.aj.b(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):69)
	at com.google.android.gms.dynamiteloader.DynamiteLoaderV2.loadModule2NoCrashUtils(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):114)
	at m2.cn.a(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):73)
	at m2.p.onTransact(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):21)
	at android.os.Binder.transact(Binder.java:1297)
	at com.google.android.gms.internal.common.zza.zzB(SourceFile:8)
	at com.google.android.gms.dynamite.zzq.zzf(SourceFile:18)
	at com.google.android.gms.dynamite.DynamiteModule.load(SourceFile:258)
	at com.google.android.gms.maps.internal.zzcc.zzc(SourceFile:16)
	at com.google.android.gms.maps.internal.zzcc.zzd(SourceFile:8)
	at com.google.android.gms.maps.internal.zzcc.zza(SourceFile:32)
	at com.google.android.gms.maps.MapsInitializer.initialize(SourceFile:5)
	at com.google.android.gms.maps.MapsInitializer.initialize(SourceFile:1)
	at com.google.android.gms.maps.zzaw.zzc(SourceFile:17)
	at com.google.android.gms.maps.zzaw.createDelegate(SourceFile:3)
	at com.google.android.gms.dynamic.DeferredLifecycleHelper.zaf(SourceFile:45)
	at com.google.android.gms.dynamic.DeferredLifecycleHelper.onCreate(SourceFile:6)
	at com.google.android.gms.maps.SupportMapFragment.onCreate(SourceFile:26)
	at androidx.fragment.app.Fragment.performCreate(SourceFile:22)
	at androidx.fragment.app.FragmentStateManager.create(SourceFile:60)
	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(SourceFile:133)
	at androidx.fragment.app.FragmentManager.executeOpsTogether(SourceFile:350)
	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(SourceFile:82)
	at androidx.fragment.app.FragmentManager.execPendingActions(SourceFile:22)
	at androidx.fragment.app.FragmentManager.dispatchStateChange(SourceFile:41)
	at androidx.fragment.app.FragmentManager.dispatchViewCreated(SourceFile:2)
	at androidx.fragment.app.Fragment.performViewCreated(SourceFile:20)
	at androidx.fragment.app.FragmentStateManager.createView(SourceFile:318)
	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(SourceFile:128)
	at androidx.fragment.app.FragmentManager.executeOpsTogether(SourceFile:350)
	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(SourceFile:82)
	at androidx.fragment.app.FragmentManager.execSingleAction(SourceFile:32)
	at androidx.fragment.app.BackStackRecord.commitNow(SourceFile:7)
	at androidx.viewpager2.adapter.FragmentStateAdapter.placeFragmentInViewHolder(SourceFile:140)
	at androidx.viewpager2.adapter.FragmentStateAdapter.onViewAttachedToWindow(SourceFile:2)
	at androidx.viewpager2.adapter.FragmentStateAdapter.onViewAttachedToWindow(SourceFile:1)
	at androidx.recyclerview.widget.RecyclerView.dispatchChildAttached(SourceFile:14)
	at androidx.recyclerview.widget.RecyclerView$6.addView(SourceFile:8)
	at androidx.recyclerview.widget.ChildHelper.addView(SourceFile:6)
	at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(SourceFile:124)
	at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(SourceFile:2)
	at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(SourceFile:1)
	at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(SourceFile:34)
	at androidx.recyclerview.widget.LinearLayoutManager.fill(SourceFile:39)
	at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(SourceFile:358)
	at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(SourceFile:67)
	at androidx.recyclerview.widget.RecyclerView.dispatchLayout(SourceFile:72)
	at androidx.recyclerview.widget.RecyclerView.onLayout(SourceFile:6)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at androidx.viewpager2.widget.ViewPager2.onLayout(SourceFile:71)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at androidx.coordinatorlayout.widget.CoordinatorLayout.layoutChild(SourceFile:142)
	at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayoutChild(SourceFile:29)
	at com.google.android.material.appbar.ViewOffsetBehavior.layoutChild(SourceFile:1)
	at com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild(SourceFile:149)
	at com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild(SourceFile:1)
	at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild(SourceFile:1)
	at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(SourceFile:43)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
	at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
	at com.android.internal.policy.DecorView.onLayout(DecorView.java:775)
	at android.view.View.layout(View.java:25626)
	at android.view.ViewGroup.layout(ViewGroup.java:6460)
	at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:5074)
	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4218)
	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3076)
	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10643)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1570)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1579)
	at android.view.Choreographer.doCallbacks(Choreographer.java:1179)
	at android.view.Choreographer.doFrame(Choreographer.java:1108)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1553)
	at android.os.Handler.handleCallback(Handler.java:995)
	at android.os.Handler.dispatchMessage(Handler.java:103)
	at android.os.Looper.loopOnce(Looper.java:248)
	at android.os.Looper.loop(Looper.java:338)
	at android.app.ActivityThread.main(ActivityThread.java:9106)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
	at com.android.internal.os.ExecInit.main(ExecInit.java:50)
	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:371)

Citymapper

Citymapper tries to use DCL via memory to load Facebook ads. The app works if it is disabled.

Details

type: memory_DCL
osVersion: google/cheetah/cheetah:15/BP1A.250505.005.B1/2025052800:user/release-keys
flags: dev options enabled
package: com.citymapper.app.release:1134060, targetSdk 34

package: com.citymapper.app.release:1134060

DCL denial type: InMemoryDexFile
process: com.citymapper.app.release
thread: Thread-9

java.lang.SecurityException
	at android.ext.dcl.DynCodeLoading.checkInMemoryDexFileOpen(DynCodeLoading.java:81)
	at dalvik.system.DexFile.openInMemoryDexFilesNative(Native Method)
	at dalvik.system.DexFile.openInMemoryDexFiles(DexFile.java:428)
	at dalvik.system.DexFile.(DexFile.java:136)
	at dalvik.system.DexPathList.initByteBufferDexPath(DexPathList.java:264)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:226)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:40)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:52)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:63)
	at com.facebook.ads.internal.dynamicloading.a.a(SourceFile:1)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.createInMemoryClassLoader(SourceFile:103)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.makeAdsSdkClassLoader(SourceFile:7)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.doMakeLoader(SourceFile:35)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory.access$000(SourceFile:1)
	at com.facebook.ads.internal.dynamicloading.DynamicLoaderFactory$a.run(SourceFile:18)
	at java.lang.Thread.run(Thread.java:1119)

First Bus

First Bus does not work without DCL. When attempting to open the app with both disabled, being unable to, re-enabling both, and then opening the app again, it had the effect of actually resetting user data entirely, meaning I had to log back in and the history of places I had searched for was lost. You can technically open the app with just DCL via storage disabled, but the breaking of Google Maps that this brings about would basically defeat the purpose of using the app. While the app design could be improved, the use of DCL via memory seems to be related to Play Services, which is okay.

Details

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: com.firstgroup.first.bus:2026040009, targetSdk 34

package: com.firstgroup.first.bus:2026040009

DCL denial type: InMemoryDexFile
process: com.firstgroup.first.bus
thread: main

java.lang.SecurityException
	at android.ext.dcl.DynCodeLoading.checkInMemoryDexFileOpen(DynCodeLoading.java:81)
	at dalvik.system.DexFile.openInMemoryDexFilesNative(Native Method)
	at dalvik.system.DexFile.openInMemoryDexFiles(DexFile.java:428)
	at dalvik.system.DexFile.(DexFile.java:136)
	at dalvik.system.DexPathList.initByteBufferDexPath(DexPathList.java:264)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:226)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:40)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:52)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:63)
	at java.lang.reflect.Constructor.newInstance0(Native Method)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
	at o.registerClient.(Unknown Source:7000)
	at com.firstgroup.app.di.AppModule.read(:259)
	at o.convertJSONcredentials_play_services_auth_release.get(:2041)
	at o.getClientCreatedAt.get(:1052)
	at o.AFb1iSDK.get(:47)
	at o.DevicePayload.get(:1094)
	at o.AFb1iSDK.get(:47)
	at o.LogoutPayload.get(:1052)
	at o.AFb1iSDK.get(:47)
	at o.includeContainerKeyapptentive_feedback_release.get(:1041)
	at o.AFb1iSDK.get(:47)
	at o.MessageCenterModel.get(:1040)
	at o.setToken.get(:1042)
	at o.AFb1iSDK.get(:47)
	at o.NotificationUtilsWhenMappings.get(:1119)
	at o.AFb1iSDK.get(:47)
	at o.PayloadQueue.get(:1041)
	at o.AFb1iSDK.get(:47)
	at o.getJSON_KEY_SIGNATUREcredentials_play_services_auth_release$MediaBrowserCompatCustomActionResultReceiver.RemoteActionCompatParcelizer(:24562)
	at com.firstgroup.app.App.dependencyInjection(:125)
	at com.firstgroup.app.App.onCreate(:99)
	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1391)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7869)
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2555)
	at android.os.Handler.dispatchMessage(Handler.java:110)
	at android.os.Looper.loopOnce(Looper.java:248)
	at android.os.Looper.loop(Looper.java:338)
	at android.app.ActivityThread.main(ActivityThread.java:9106)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
	at com.android.internal.os.ExecInit.main(ExecInit.java:50)
	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:371)

EE

The EE app does not function without DCL via memory and storage enabled. It uses it to load the Flutter framework. Enabling memory tagging works.

Details (memory)

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090800:user/release-keys
package: uk.co.ee.myee:2514969, targetSdk 36

package: uk.co.ee.myee:2514969

DCL denial type: InMemoryDexFile
process: uk.co.ee.myee
thread: flutter-worker-0

java.lang.SecurityException
	at android.ext.dcl.DynCodeLoading.checkInMemoryDexFileOpen(DynCodeLoading.java:81)
	at dalvik.system.DexFile.openInMemoryDexFilesNative(Native Method)
	at dalvik.system.DexFile.openInMemoryDexFiles(DexFile.java:428)
	at dalvik.system.DexFile.(DexFile.java:136)
	at dalvik.system.DexPathList.initByteBufferDexPath(DexPathList.java:264)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:226)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:40)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:52)
	at dalvik.system.InMemoryDexClassLoader.(InMemoryDexClassLoader.java:63)
	at java.lang.reflect.Constructor.newInstance0(Native Method)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
	at o.ArtificialStackFrames.(Unknown Source:7758)
	at io.flutter.embedding.engine.FlutterJNI.a(:61)
	at io.flutter.embedding.engine.FlutterJNI.CoroutineDebuggingKt(:65354)
	at io.flutter.embedding.engine.FlutterJNI.loadLibrary(:147)
	at io.flutter.embedding.engine.loader.FlutterLoader$1.call(:187)
	at io.flutter.embedding.engine.loader.FlutterLoader$1.call(:180)
	at java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
	at java.lang.Thread.run(Thread.java:1119)
Details (storage)

type: storage_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090800:user/release-keys
package: uk.co.ee.myee:2514969, targetSdk 36

package: uk.co.ee.myee:2514969

DCL denial type: DexFileOpen
process: uk.co.ee.myee
thread: flutter-worker-0

java.lang.SecurityException: DCL via storage, path: /data/user/0/uk.co.ee.myee/code_cache/.      , canonicalPath: /data/data/uk.co.ee.myee/code_cache/.      
	at android.ext.dcl.DynCodeLoading.checkDexFileOpen(DynCodeLoading.java:131)
	at dalvik.system.DexFile.openDexFileNative(Native Method)
	at dalvik.system.DexFile.openDexFile(DexFile.java:406)
	at dalvik.system.DexFile.(DexFile.java:171)
	at dalvik.system.DexFile.loadDex(DexFile.java:231)
	at dalvik.system.DexFile.loadDex(DexFile.java:198)
	at java.lang.reflect.Method.invoke(Native Method)
	at o.ArtificialStackFrames.(Unknown Source:145)
	at io.flutter.embedding.engine.FlutterJNI.a(:61)
	at io.flutter.embedding.engine.FlutterJNI.CoroutineDebuggingKt(:65354)
	at io.flutter.embedding.engine.FlutterJNI.loadLibrary(:147)
	at io.flutter.embedding.engine.loader.FlutterLoader$1.call(:187)
	at io.flutter.embedding.engine.loader.FlutterLoader$1.call(:180)
	at java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
	at java.lang.Thread.run(Thread.java:1119)

Trainline

The Trainline app uses DCL via storage to try to load Google ads. It works fine if it's diabled. I also disabled DCL via memory, but haven't received any notifications that it tried to use it. It also works fine with memory tagging enabled.

Details

type: storage_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090800:user/release-keys
package: com.thetrainline:1255202, targetSdk 34

package: com.thetrainline:1255202

DCL denial type: DexFileOpen
process: com.thetrainline
thread: DefaultDispatcher-worker-1

java.lang.SecurityException: DCL via storage, path: /data/user_de/0/com.google.android.gms/app_chimera/m/00000005/dl-AdsFdrDynamite.integ_251815204100000.apk
	at android.ext.dcl.DynCodeLoading.checkDexFileOpen(DynCodeLoading.java:131)
	at dalvik.system.DexFile.openDexFileNative(Native Method)
	at dalvik.system.DexFile.openDexFile(DexFile.java:406)
	at dalvik.system.DexFile.(DexFile.java:128)
	at dalvik.system.DexFile.(DexFile.java:101)
	at dalvik.system.DexPathList.loadDexFile(DexPathList.java:438)
	at dalvik.system.DexPathList.makeDexElements(DexPathList.java:397)
	at dalvik.system.DexPathList.(DexPathList.java:166)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:160)
	at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:105)
	at dalvik.system.PathClassLoader.(PathClassLoader.java:71)
	at dalvik.system.DelegateLastClassLoader.(DelegateLastClassLoader.java:114)
	at m2.aa.c(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):58)
	at m2.aj.b(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):69)
	at com.google.android.gms.dynamiteloader.DynamiteLoaderV2.loadModule2NoCrashUtils(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):114)
	at m2.cn.a(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):73)
	at m2.p.onTransact(:com.google.android.gms.dynamite_dynamiteloader@253133035@25.31.33 (260400-0):21)
	at android.os.Binder.transact(Binder.java:1297)
	at vnn.hT(:com.google.android.gms@253133035@25.31.33 (260400-795226510):8)
	at biiw.loadModule2NoCrashUtils(:com.google.android.gms@253133035@25.31.33 (260400-795226510):18)
	at biir.f(:com.google.android.gms@253133035@25.31.33 (260400-795226510):259)
	at avgg.a(:com.google.android.gms@253133035@25.31.33 (260400-795226510):3)
	at aaln.(:com.google.android.gms@253133035@25.31.33 (260400-795226510):11)
	at aaln.a(:com.google.android.gms@253133035@25.31.33 (260400-795226510):17)
	at com.google.android.gms.ads.MobileAdsSettingManagerCreatorImpl.getMobileAdsSettingManager(:com.google.android.gms@253133035@25.31.33 (260400-795226510):24)
	at com.google.android.gms.ads.internal.client.bc.fl(:com.google.android.gms@253133035@25.31.33 (260400-795226510):39)
	at vno.onTransact(:com.google.android.gms@253133035@25.31.33 (260400-795226510):102)
	at android.os.Binder.transact(Binder.java:1297)
	at com.google.android.gms.internal.ads.zzaya.B4(SourceFile:8)
	at com.google.android.gms.ads.internal.client.zzda.t6(SourceFile:15)
	at com.google.android.gms.ads.internal.client.zzfe.a(SourceFile:15)
	at com.google.android.gms.ads.internal.client.zzav.c(SourceFile:113)
	at com.google.android.gms.ads.internal.client.zzbb.f(SourceFile:1)
	at com.google.android.gms.ads.internal.client.zzbb.d(SourceFile:94)
	at com.google.android.gms.ads.internal.client.zzex.c(SourceFile:15)
	at com.google.android.gms.ads.internal.client.zzex.s(SourceFile:53)
	at com.google.android.gms.ads.MobileAds.f(SourceFile:6)
	at com.thetrainline.ads.google_ad.initialisation.MobileAdsWrapper.a(SourceFile:3)
	at com.thetrainline.ads.google_ad.initialisation.InitialiseAdsUseCase$invoke$1$1$1.invokeSuspend(SourceFile:17)
	at com.thetrainline.ads.google_ad.initialisation.InitialiseAdsUseCase$invoke$1$1$1.invoke(SourceFile:2)
	at com.thetrainline.ads.google_ad.initialisation.InitialiseAdsUseCase$invoke$1$1$1.invoke(SourceFile:1)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.b(SourceFile:19)
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.g(SourceFile:54)
	at kotlinx.coroutines.BuildersKt.h(SourceFile:1)
	at com.thetrainline.ads.google_ad.initialisation.InitialiseAdsUseCase$invoke$1.invokeSuspend(SourceFile:55)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:12)
	at kotlinx.coroutines.DispatchedTask.run(SourceFile:126)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(SourceFile:4)
	at kotlinx.coroutines.scheduling.TaskImpl.run(SourceFile:3)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.v0(SourceFile:1)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.b(SourceFile:34)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.r(SourceFile:29)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(SourceFile:1)

HSBC

The HSBC UK app requires both DCLs enabled to work. Apprently, DCL via storage is used to load libcrypto. Enabling memory tagging seems to work fine.

Details (memory)

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: uk.co.hsbc.hsbcukmobilebanking:3108556, targetSdk 35

package: uk.co.hsbc.hsbcukmobilebanking:3108556

DCL denial type: DENY_EXECMEM
Details (storage)

type: storage_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025090600:user/release-keys
package: uk.co.hsbc.hsbcukmobilebanking:3108556, targetSdk 35

package: uk.co.hsbc.hsbcukmobilebanking:3108556

DCL denial type: DENY_EXECUTE_APP_DATA_FILE
thread: DefaultDispatch
targetPath: /data/data/uk.co.hsbc.hsbcukmobilebanking/cache/libcrypto-lib.so

SimpleX Chat

SimpleX is fantastic (obviously) and works with both DCLs disabled and memory tagging enabled.

Proton: Mail, VPN, Calendar, Drive, Pass, Lumo, Authenticator

All of these applications by Proton do not require DCL and function with memory tagging enabled.

Proton Wallet

DCL via memory (but not storage) is required for this app to work. Memory tagging can be enabled.

Details (memory)

type: memory_DCL
osVersion: google/komodo/komodo:16/BP2A.250805.005/2025091000:user/release-keys
package: me.proton.wallet.android:107, targetSdk 35

package: me.proton.wallet.android:107

DCL denial type: DENY_EXECMEM

Further reading

  1. https://developer.android.com/privacy-and-security/risks/dynamic-code-loading
  2. https://en.wikipedia.org/wiki/Dynamic_loading
  3. https://www.geeksforgeeks.org/operating-systems/difference-between-static-anddynamic-loading-in-operating-system/