frida-java-bridge 6.2.1 → 6.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -440,9 +440,13 @@ class Runtime {
440
440
  handleBindApplication.apply(this, arguments);
441
441
  };
442
442
 
443
- const getPackageInfoNoCheck = ActivityThread.getPackageInfoNoCheck;
444
- getPackageInfoNoCheck.implementation = function (appInfo) {
445
- const apk = getPackageInfoNoCheck.apply(this, arguments);
443
+ const getPackageInfoCandidates = ActivityThread.getPackageInfo.overloads
444
+ .map(m => [m.argumentTypes.length, m])
445
+ .sort(([arityA,], [arityB,]) => arityB - arityA)
446
+ .map(([_, method]) => method);
447
+ const getPackageInfo = getPackageInfoCandidates[0];
448
+ getPackageInfo.implementation = function (...args) {
449
+ const apk = getPackageInfo.call(this, ...args);
446
450
 
447
451
  if (!initialized && hookpoint === 'early') {
448
452
  initialized = true;
package/lib/android.js CHANGED
@@ -30,7 +30,6 @@ const kAccSkipAccessChecks = 0x00080000;
30
30
  const kAccSingleImplementation = 0x08000000;
31
31
  const kAccNterpEntryPointFastPathFlag = 0x00100000;
32
32
  const kAccNterpInvokeFastPathFlag = 0x00200000;
33
- const kAccCompileDontBother = 0x02000000;
34
33
  const kAccPublicApi = 0x10000000;
35
34
  const kAccXposedHookedMethod = 0x10000000;
36
35
 
@@ -82,7 +81,6 @@ const SOCK_STREAM = 1;
82
81
 
83
82
  const getArtRuntimeSpec = memoize(_getArtRuntimeSpec);
84
83
  const getArtInstrumentationSpec = memoize(_getArtInstrumentationSpec);
85
- const getArtClassLinkerSpec = memoize(_getArtClassLinkerSpec);
86
84
  const getArtMethodSpec = memoize(_getArtMethodSpec);
87
85
  const getArtThreadSpec = memoize(_getArtThreadSpec);
88
86
  const getArtManagedStackSpec = memoize(_getArtManagedStackSpec);
@@ -104,6 +102,7 @@ const nativeFunctionOptions = {
104
102
  const artThreadStateTransitions = {};
105
103
 
106
104
  let cachedApi = null;
105
+ let cachedArtClassLinkerSpec = null;
107
106
  let MethodMangler = null;
108
107
  let artController = null;
109
108
  const inlineHooks = [];
@@ -435,9 +434,22 @@ function _getApi () {
435
434
  temporaryApi.vm = vms.readPointer();
436
435
 
437
436
  if (isArt) {
437
+ const apiLevel = getAndroidApiLevel();
438
+
439
+ let kAccCompileDontBother;
440
+ if (apiLevel >= 27) {
441
+ kAccCompileDontBother = 0x02000000;
442
+ } else if (apiLevel >= 24) {
443
+ kAccCompileDontBother = 0x01000000;
444
+ } else {
445
+ kAccCompileDontBother = 0;
446
+ }
447
+ temporaryApi.kAccCompileDontBother = kAccCompileDontBother;
448
+
438
449
  const artRuntime = temporaryApi.vm.add(pointerSize).readPointer();
439
450
  temporaryApi.artRuntime = artRuntime;
440
- const runtimeOffset = getArtRuntimeSpec(temporaryApi).offset;
451
+ const runtimeSpec = getArtRuntimeSpec(temporaryApi);
452
+ const runtimeOffset = runtimeSpec.offset;
441
453
  const instrumentationOffset = runtimeOffset.instrumentation;
442
454
  temporaryApi.artInstrumentation = (instrumentationOffset !== null) ? artRuntime.add(instrumentationOffset) : null;
443
455
 
@@ -452,7 +464,7 @@ function _getApi () {
452
464
  */
453
465
  const classLinker = artRuntime.add(runtimeOffset.classLinker).readPointer();
454
466
 
455
- const classLinkerOffsets = getArtClassLinkerSpec(temporaryApi).offset;
467
+ const classLinkerOffsets = getArtClassLinkerSpec(artRuntime, runtimeSpec).offset;
456
468
  const quickResolutionTrampoline = classLinker.add(classLinkerOffsets.quickResolutionTrampoline).readPointer();
457
469
  const quickImtConflictTrampoline = classLinker.add(classLinkerOffsets.quickImtConflictTrampoline).readPointer();
458
470
  const quickGenericJniTrampoline = classLinker.add(classLinkerOffsets.quickGenericJniTrampoline).readPointer();
@@ -602,49 +614,57 @@ function _getArtRuntimeSpec (api) {
602
614
  const endOffset = startOffset + (100 * pointerSize);
603
615
 
604
616
  const apiLevel = getAndroidApiLevel();
617
+ const codename = getAndroidCodename();
605
618
 
606
619
  let spec = null;
607
620
 
608
621
  for (let offset = startOffset; offset !== endOffset; offset += pointerSize) {
609
622
  const value = runtime.add(offset).readPointer();
610
623
  if (value.equals(vm)) {
611
- let classLinkerOffset = null;
624
+ let classLinkerOffsets;
612
625
  let jniIdManagerOffset = null;
613
- if (apiLevel >= 33 || getAndroidCodename() === 'Tiramisu') {
614
- classLinkerOffset = offset - (4 * pointerSize);
626
+ if (apiLevel >= 33 || codename === 'Tiramisu') {
627
+ classLinkerOffsets = [offset - (4 * pointerSize)];
615
628
  jniIdManagerOffset = offset - pointerSize;
616
- } else if (apiLevel >= 30 || getAndroidCodename() === 'R') {
617
- classLinkerOffset = offset - (3 * pointerSize);
629
+ } else if (apiLevel >= 30 || codename === 'R') {
630
+ classLinkerOffsets = [offset - (3 * pointerSize), offset - (4 * pointerSize)];
618
631
  jniIdManagerOffset = offset - pointerSize;
619
632
  } else if (apiLevel >= 29) {
620
- classLinkerOffset = offset - (2 * pointerSize);
633
+ classLinkerOffsets = [offset - (2 * pointerSize)];
621
634
  } else if (apiLevel >= 27) {
622
- classLinkerOffset = offset - STD_STRING_SIZE - (3 * pointerSize);
635
+ classLinkerOffsets = [offset - STD_STRING_SIZE - (3 * pointerSize)];
623
636
  } else {
624
- classLinkerOffset = offset - STD_STRING_SIZE - (2 * pointerSize);
637
+ classLinkerOffsets = [offset - STD_STRING_SIZE - (2 * pointerSize)];
625
638
  }
626
639
 
627
- const internTableOffset = classLinkerOffset - pointerSize;
628
- const threadListOffset = internTableOffset - pointerSize;
640
+ for (const classLinkerOffset of classLinkerOffsets) {
641
+ const internTableOffset = classLinkerOffset - pointerSize;
642
+ const threadListOffset = internTableOffset - pointerSize;
629
643
 
630
- let heapOffset;
631
- if (apiLevel >= 24) {
632
- heapOffset = threadListOffset - (8 * pointerSize);
633
- } else if (apiLevel >= 23) {
634
- heapOffset = threadListOffset - (7 * pointerSize);
635
- } else {
636
- heapOffset = threadListOffset - (4 * pointerSize);
637
- }
644
+ let heapOffset;
645
+ if (apiLevel >= 24) {
646
+ heapOffset = threadListOffset - (8 * pointerSize);
647
+ } else if (apiLevel >= 23) {
648
+ heapOffset = threadListOffset - (7 * pointerSize);
649
+ } else {
650
+ heapOffset = threadListOffset - (4 * pointerSize);
651
+ }
638
652
 
639
- spec = {
640
- offset: {
641
- heap: heapOffset,
642
- threadList: threadListOffset,
643
- internTable: internTableOffset,
644
- classLinker: classLinkerOffset,
645
- jniIdManager: jniIdManagerOffset
653
+ const candidate = {
654
+ offset: {
655
+ heap: heapOffset,
656
+ threadList: threadListOffset,
657
+ internTable: internTableOffset,
658
+ classLinker: classLinkerOffset,
659
+ jniIdManager: jniIdManagerOffset
660
+ }
661
+ };
662
+ if (tryGetArtClassLinkerSpec(runtime, candidate) !== null) {
663
+ spec = candidate;
664
+ break;
646
665
  }
647
- };
666
+ }
667
+
648
668
  break;
649
669
  }
650
670
  }
@@ -822,7 +842,19 @@ function _getArtInstrumentationSpec () {
822
842
  };
823
843
  }
824
844
 
825
- function _getArtClassLinkerSpec (api) {
845
+ function getArtClassLinkerSpec (runtime, runtimeSpec) {
846
+ const spec = tryGetArtClassLinkerSpec(runtime, runtimeSpec);
847
+ if (spec === null) {
848
+ throw new Error('Unable to determine ClassLinker field offsets');
849
+ }
850
+ return spec;
851
+ }
852
+
853
+ function tryGetArtClassLinkerSpec (runtime, runtimeSpec) {
854
+ if (cachedArtClassLinkerSpec !== null) {
855
+ return cachedArtClassLinkerSpec;
856
+ }
857
+
826
858
  /*
827
859
  * On Android 5.x:
828
860
  *
@@ -851,11 +883,9 @@ function _getArtClassLinkerSpec (api) {
851
883
  * }
852
884
  */
853
885
 
854
- const runtime = api.artRuntime;
855
- const runtimeSpec = getArtRuntimeSpec(api);
856
-
857
- const classLinker = runtime.add(runtimeSpec.offset.classLinker).readPointer();
858
- const internTable = runtime.add(runtimeSpec.offset.internTable).readPointer();
886
+ const { classLinker: classLinkerOffset, internTable: internTableOffset } = runtimeSpec.offset;
887
+ const classLinker = runtime.add(classLinkerOffset).readPointer();
888
+ const internTable = runtime.add(internTableOffset).readPointer();
859
889
 
860
890
  const startOffset = (pointerSize === 4) ? 100 : 200;
861
891
  const endOffset = startOffset + (100 * pointerSize);
@@ -900,8 +930,8 @@ function _getArtClassLinkerSpec (api) {
900
930
  }
901
931
  }
902
932
 
903
- if (spec === null) {
904
- throw new Error('Unable to determine ClassLinker field offsets');
933
+ if (spec !== null) {
934
+ cachedArtClassLinkerSpec = spec;
905
935
  }
906
936
 
907
937
  return spec;
@@ -3314,6 +3344,8 @@ class ArtMethodMangler {
3314
3344
  }
3315
3345
 
3316
3346
  replace (impl, isInstanceMethod, argTypes, vm, api) {
3347
+ const { kAccCompileDontBother, artNterpEntryPoint } = api;
3348
+
3317
3349
  this.originalMethod = fetchArtMethod(this.methodId, vm);
3318
3350
 
3319
3351
  const originalFlags = this.originalMethod.accessFlags;
@@ -3351,8 +3383,6 @@ class ArtMethodMangler {
3351
3383
 
3352
3384
  // Replace Nterp quick entrypoints with art_quick_to_interpreter_bridge to force stepping out
3353
3385
  // of ART's next-generation interpreter and use the quick stub instead.
3354
- const { artNterpEntryPoint } = api;
3355
-
3356
3386
  if (artNterpEntryPoint !== undefined && quickCode.equals(artNterpEntryPoint)) {
3357
3387
  patchArtMethod(hookedMethodId, {
3358
3388
  quickCode: api.artQuickToInterpreterBridge
@@ -390,7 +390,10 @@ model_add_method (Model * self,
390
390
  gchar * key, type;
391
391
  const gchar * value;
392
392
 
393
- key = g_strdup (name);
393
+ if (name[0] == '$')
394
+ key = g_strdup_printf ("_%s", name);
395
+ else
396
+ key = g_strdup (name);
394
397
 
395
398
  type = (modifiers & kAccStatic) != 0 ? 's' : 'i';
396
399
 
@@ -410,7 +413,10 @@ model_add_field (Model * self,
410
413
  GHashTable * members = self->members;
411
414
  gchar * key, type;
412
415
 
413
- key = g_strdup (name);
416
+ if (name[0] == '$')
417
+ key = g_strdup_printf ("_%s", name);
418
+ else
419
+ key = g_strdup (name);
414
420
  while (g_hash_table_contains (members, key))
415
421
  {
416
422
  gchar * new_key = g_strdup_printf ("_%s", key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frida-java-bridge",
3
- "version": "6.2.1",
3
+ "version": "6.2.3",
4
4
  "description": "Java runtime interop from Frida",
5
5
  "main": "index.js",
6
6
  "files": [