frida-java-bridge 4.5.1 → 5.2.0

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
@@ -576,6 +576,6 @@ function initFactoryFromLoadedApk (factory, apk) {
576
576
  }
577
577
 
578
578
  const runtime = new Runtime();
579
- WeakRef.bind(runtime, () => { runtime._dispose(); });
579
+ Script.bindWeak(runtime, () => { runtime._dispose(); });
580
580
 
581
581
  module.exports = runtime;
package/lib/android.js CHANGED
@@ -22,6 +22,8 @@ const kAccCriticalNative = 0x00200000;
22
22
  const kAccFastInterpreterToInterpreterInvoke = 0x40000000;
23
23
  const kAccSkipAccessChecks = 0x00080000;
24
24
  const kAccSingleImplementation = 0x08000000;
25
+ const kAccNterpEntryPointFastPathFlag = 0x00100000;
26
+ const kAccNterpInvokeFastPathFlag = 0x00200000;
25
27
  const kAccPublicApi = 0x10000000;
26
28
  const kAccXposedHookedMethod = 0x10000000;
27
29
 
@@ -908,7 +910,7 @@ function _getArtMethodSpec (vm) {
908
910
  const entrypointFieldSize = (apiLevel <= 21) ? 8 : pointerSize;
909
911
 
910
912
  const expectedAccessFlags = kAccPublic | kAccStatic | kAccFinal | kAccNative;
911
- const allFlagsExceptPublicApi = ~kAccPublicApi >>> 0;
913
+ const relevantAccessFlagsMask = ~(kAccPublicApi | kAccNterpInvokeFastPathFlag) >>> 0;
912
914
 
913
915
  let jniCodeOffset = null;
914
916
  let accessFlagsOffset = null;
@@ -926,7 +928,7 @@ function _getArtMethodSpec (vm) {
926
928
 
927
929
  if (accessFlagsOffset === null) {
928
930
  const flags = field.readU32();
929
- if ((flags & allFlagsExceptPublicApi) === expectedAccessFlags) {
931
+ if ((flags & relevantAccessFlagsMask) === expectedAccessFlags) {
930
932
  accessFlagsOffset = offset;
931
933
  remaining--;
932
934
  }
@@ -1539,7 +1541,7 @@ set_replacement_method (gpointer original_method,
1539
1541
  g_mutex_lock (&lock);
1540
1542
 
1541
1543
  g_hash_table_insert (methods, original_method, replacement_method);
1542
- g_hash_table_add (replacements, replacement_method);
1544
+ g_hash_table_insert (replacements, replacement_method, original_method);
1543
1545
 
1544
1546
  g_mutex_unlock (&lock);
1545
1547
  }
@@ -1561,6 +1563,20 @@ delete_replacement_method (gpointer original_method)
1561
1563
  g_mutex_unlock (&lock);
1562
1564
  }
1563
1565
 
1566
+ gpointer
1567
+ translate_method (gpointer method)
1568
+ {
1569
+ gpointer translated_method;
1570
+
1571
+ g_mutex_lock (&lock);
1572
+
1573
+ translated_method = g_hash_table_lookup (replacements, method);
1574
+
1575
+ g_mutex_unlock (&lock);
1576
+
1577
+ return (translated_method != NULL) ? translated_method : method;
1578
+ }
1579
+
1564
1580
  gpointer
1565
1581
  find_replacement_method_from_quick_code (gpointer method,
1566
1582
  gpointer thread)
@@ -1689,6 +1705,7 @@ on_leave_gc_concurrent_copying_copying_phase (GumInvocationContext * ic)
1689
1705
  get: new NativeFunction(cm.get_replacement_method, 'pointer', ['pointer'], fastOptions),
1690
1706
  set: new NativeFunction(cm.set_replacement_method, 'void', ['pointer', 'pointer'], fastOptions),
1691
1707
  delete: new NativeFunction(cm.delete_replacement_method, 'void', ['pointer'], fastOptions),
1708
+ translate: new NativeFunction(cm.translate_method, 'pointer', ['pointer'], fastOptions),
1692
1709
  findReplacementFromQuickCode: cm.find_replacement_method_from_quick_code
1693
1710
  },
1694
1711
  getOatQuickMethodHeaderImpl,
@@ -1791,6 +1808,10 @@ function makeMethodMangler (methodId) {
1791
1808
  return new MethodMangler(methodId);
1792
1809
  }
1793
1810
 
1811
+ function translateMethod (methodId) {
1812
+ return artController.replacedMethods.translate(methodId);
1813
+ }
1814
+
1794
1815
  function revertGlobalPatches () {
1795
1816
  patchedClasses.forEach(entry => {
1796
1817
  entry.vtablePtr.writePointer(entry.vtable);
@@ -2316,14 +2337,14 @@ class ArtMethodMangler {
2316
2337
 
2317
2338
  patchArtMethod(replacementMethodId, {
2318
2339
  jniCode: impl,
2319
- accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative)) | kAccNative) >>> 0,
2340
+ accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative | kAccNterpEntryPointFastPathFlag)) | kAccNative) >>> 0,
2320
2341
  quickCode: api.artClassLinker.quickGenericJniTrampoline,
2321
2342
  interpreterCode: api.artInterpreterToCompiledCodeBridge
2322
2343
  }, vm);
2323
2344
 
2324
2345
  // Remove kAccFastInterpreterToInterpreterInvoke and kAccSkipAccessChecks to disable use_fast_path
2325
2346
  // in interpreter_common.h
2326
- let hookedMethodRemovedFlags = kAccFastInterpreterToInterpreterInvoke | kAccSingleImplementation;
2347
+ let hookedMethodRemovedFlags = kAccFastInterpreterToInterpreterInvoke | kAccSingleImplementation | kAccNterpEntryPointFastPathFlag;
2327
2348
  if ((originalFlags & kAccNative) === 0) {
2328
2349
  hookedMethodRemovedFlags |= kAccSkipAccessChecks;
2329
2350
  }
@@ -4043,6 +4064,7 @@ module.exports = {
4043
4064
  ArtStackVisitor,
4044
4065
  ArtMethod,
4045
4066
  makeMethodMangler,
4067
+ translateMethod,
4046
4068
  revertGlobalPatches,
4047
4069
  deoptimizeEverything,
4048
4070
  deoptimizeBootImage,
@@ -265,7 +265,7 @@ class ClassFactory {
265
265
  wrap (handle, klass, env) {
266
266
  const C = klass.$C;
267
267
  const wrapper = new C(handle, STRATEGY_VIRTUAL, env, false);
268
- wrapper.$r = WeakRef.bind(wrapper, vm.makeHandleDestructor(handle));
268
+ wrapper.$r = Script.bindWeak(wrapper, vm.makeHandleDestructor(handle));
269
269
  return wrapper;
270
270
  }
271
271
 
@@ -746,7 +746,7 @@ function Wrapper (handle, strategy, env, owned = true) {
746
746
  if (owned) {
747
747
  const h = env.newGlobalRef(handle);
748
748
  this.$h = h;
749
- this.$r = WeakRef.bind(this, vm.makeHandleDestructor(h));
749
+ this.$r = Script.bindWeak(this, vm.makeHandleDestructor(h));
750
750
  } else {
751
751
  this.$h = handle;
752
752
  this.$r = null;
@@ -834,7 +834,7 @@ Object.defineProperties(Wrapper.prototype, {
834
834
  const ref = this.$r;
835
835
  if (ref !== null) {
836
836
  this.$r = null;
837
- WeakRef.unbind(ref);
837
+ Script.unbindWeak(ref);
838
838
  }
839
839
 
840
840
  if (this.$h !== null) {
package/lib/env.js CHANGED
@@ -229,7 +229,7 @@ Env.prototype.throwIfExceptionPending = function () {
229
229
 
230
230
  const error = new Error(descriptionStr);
231
231
  error.$h = handle;
232
- WeakRef.bind(error, makeErrorHandleDestructor(this.vm, handle));
232
+ Script.bindWeak(error, makeErrorHandleDestructor(this.vm, handle));
233
233
 
234
234
  throw error;
235
235
  };
@@ -531,6 +531,10 @@ Env.prototype.monitorExit = proxy(218, 'int32', ['pointer', 'pointer'], function
531
531
  return impl(this.handle, obj);
532
532
  });
533
533
 
534
+ Env.prototype.getDirectBufferAddress = proxy(230, 'pointer', ['pointer', 'pointer'], function (impl, obj) {
535
+ return impl(this.handle, obj);
536
+ });
537
+
534
538
  Env.prototype.getObjectRefType = proxy(232, 'int32', ['pointer', 'pointer'], function (impl, ref) {
535
539
  return impl(this.handle, ref);
536
540
  });
package/lib/types.js CHANGED
@@ -446,7 +446,15 @@ function getArrayType (typeName, unbox, factory) {
446
446
  }
447
447
  }
448
448
 
449
- result.$w = factory.cast(arr, factory.use(typeName), owned);
449
+ // The type name we get is not always the correct representation of the type so we make it so here.
450
+ const internalTypeName = '[L' + elementTypeName.replace(/\./g, '/') + ';';
451
+ try {
452
+ result.$w = factory.cast(arr, factory.use(internalTypeName), owned);
453
+ } catch (e) {
454
+ // We need to load the array type before using it.
455
+ factory.use('java.lang.reflect.Array').newInstance(factory.use(elementTypeName).class, 0);
456
+ result.$w = factory.cast(arr, factory.use(internalTypeName), owned);
457
+ }
450
458
 
451
459
  result.$dispose = disposeObjectArray;
452
460
 
@@ -580,7 +588,7 @@ function PrimitiveArray (handle, spec, type, length, env, owned = true) {
580
588
  if (owned) {
581
589
  const h = env.newGlobalRef(handle);
582
590
  this.$h = h;
583
- this.$r = WeakRef.bind(this, env.vm.makeHandleDestructor(h));
591
+ this.$r = Script.bindWeak(this, env.vm.makeHandleDestructor(h));
584
592
  } else {
585
593
  this.$h = handle;
586
594
  this.$r = null;
@@ -654,7 +662,7 @@ Object.defineProperties(PrimitiveArray.prototype, {
654
662
  const ref = this.$r;
655
663
  if (ref !== null) {
656
664
  this.$r = null;
657
- WeakRef.unbind(ref);
665
+ Script.unbindWeak(ref);
658
666
  }
659
667
  }
660
668
  },
@@ -726,6 +734,11 @@ Object.defineProperties(PrimitiveArray.prototype, {
726
734
  return values;
727
735
  });
728
736
  }
737
+ },
738
+ toString: {
739
+ value () {
740
+ return this.toJSON().toString();
741
+ }
729
742
  }
730
743
  });
731
744
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frida-java-bridge",
3
- "version": "4.5.1",
3
+ "version": "5.2.0",
4
4
  "description": "Java runtime interop from Frida",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -48,7 +48,6 @@
48
48
  "ThumbWriter",
49
49
  "UnixInputStream",
50
50
  "UnixOutputStream",
51
- "WeakRef",
52
51
  "X86Relocator",
53
52
  "X86Writer",
54
53
  "ptr",