From 1cf98b7becb7cc2b7a4710b37ef098b5a8b10366 Mon Sep 17 00:00:00 2001 From: mbricchi Date: Tue, 16 Jul 2024 15:46:32 +0200 Subject: [PATCH] android: Handle correctly the CMC GC strategy Fixes https://github.com/frida/frida-java-bridge/issues/323. --- lib/android.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/android.js b/lib/android.js index 06b2adc..befad7c 100644 --- a/lib/android.js +++ b/lib/android.js @@ -645,7 +645,7 @@ function _getArtRuntimeSpec (api) { const threadListOffset = internTableOffset - pointerSize; let heapOffset; - if (apiLevel >= 34) { + if (Module.findExportByName("libart.so", '_ZN3art7AppInfo29GetPrimaryApkReferenceProfileEv') !== null) {//with apex updates apiLevel!=libart version heapOffset = threadListOffset - (9 * pointerSize); } else if (apiLevel >= 24) { heapOffset = threadListOffset - (8 * pointerSize); @@ -1807,6 +1807,9 @@ on_leave_gc_concurrent_copying_copying_phase (GumInvocationContext * ic) Gc: { copyingPhase: { onLeave: cm.on_leave_gc_concurrent_copying_copying_phase + }, + runFlip: { + onEnter: cm.on_leave_gc_concurrent_copying_copying_phase } } } @@ -1885,18 +1888,23 @@ function ensureArtKnowsHowToHandleReplacementMethods (vm) { const apiLevel = getAndroidApiLevel(); let exportName = null; - if (apiLevel > 28) { - exportName = '_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv'; - } else if (apiLevel > 22) { - exportName = '_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv'; - } - - if (exportName !== null) { - Interceptor.attach(Module.getExportByName('libart.so', exportName), artController.hooks.Gc.copyingPhase); + const api = getApi(); + const kCollectorTypeCMC = 3; + let mayUseCollector = new NativeFunction(Module.findExportByName('libart.so', "_ZNK3art2gc4Heap15MayUseCollectorENS0_13CollectorTypeE"), "int", ["pointer", "int"]) + + if (mayUseCollector !== null && mayUseCollector(api.artHeap, 3)) { + console.log("hooking runflip"); + exportName = '_ZN3art6Thread15RunFlipFunctionEPS0_b'; + Interceptor.attach(Module.getExportByName('libart.so', exportName), artController.hooks.Gc.runFlip); + } else { + if (apiLevel > 28) { + exportName = '_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv'; + } else if (apiLevel > 22) { + exportName = '_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv'; + } - const collectorCMC = Module.findExportByName('libart.so', '_ZN3art2gc9collector11MarkCompact15CompactionPhaseEv'); - if (collectorCMC !== null) { - Interceptor.attach(collectorCMC, artController.hooks.Gc.copyingPhase); + if (exportName !== null) { + Interceptor.attach(Module.getExportByName('libart.so', exportName), artController.hooks.Gc.copyingPhase); } } }