diff --git a/lib/android.js b/lib/android.js index 06b2adc..d696b89 100644 --- a/lib/android.js +++ b/lib/android.js @@ -618,6 +618,7 @@ function _getArtRuntimeSpec (api) { const apiLevel = getAndroidApiLevel(); const codename = getAndroidCodename(); + const isApiLevel34OrApexEquivalent = Module.findExportByName('libart.so', '_ZN3art7AppInfo29GetPrimaryApkReferenceProfileEv') !== null; let spec = null; @@ -645,7 +646,7 @@ function _getArtRuntimeSpec (api) { const threadListOffset = internTableOffset - pointerSize; let heapOffset; - if (apiLevel >= 34) { + if (isApiLevel34OrApexEquivalent) { heapOffset = threadListOffset - (9 * pointerSize); } else if (apiLevel >= 24) { heapOffset = threadListOffset - (8 * pointerSize); @@ -1807,6 +1808,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 } } } @@ -1884,19 +1888,22 @@ 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 mayUseCollector = (apiLevel > 28) + ? new NativeFunction(Module.getExportByName('libart.so', '_ZNK3art2gc4Heap15MayUseCollectorENS0_13CollectorTypeE'), 'bool', ['pointer', 'int']) + : () => false; + const kCollectorTypeCMC = 3; - const collectorCMC = Module.findExportByName('libart.so', '_ZN3art2gc9collector11MarkCompact15CompactionPhaseEv'); - if (collectorCMC !== null) { - Interceptor.attach(collectorCMC, artController.hooks.Gc.copyingPhase); + if (mayUseCollector(getApi().artHeap, kCollectorTypeCMC)) { + Interceptor.attach(Module.getExportByName('libart.so', '_ZN3art6Thread15RunFlipFunctionEPS0_b'), artController.hooks.Gc.runFlip); + } else { + 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); } } }