frida-java-bridge 6.3.6 → 6.3.8

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
@@ -214,29 +214,23 @@ class Runtime {
214
214
  const { vm, api } = this;
215
215
  const env = vm.getEnv();
216
216
 
217
- const classHandles = [];
218
217
  const addGlobalReference = api['art::JavaVMExt::AddGlobalRef'];
219
218
  const { vm: vmHandle } = api;
220
219
  withRunnableArtThread(vm, env, thread => {
221
220
  const collectClassHandles = makeArtClassVisitor(klass => {
222
- classHandles.push(addGlobalReference(vmHandle, thread, klass));
221
+ const handle = addGlobalReference(vmHandle, thread, klass);
222
+ try {
223
+ const className = env.getClassName(handle);
224
+ callbacks.onMatch(className, handle);
225
+ } finally {
226
+ env.deleteGlobalRef(handle);
227
+ }
223
228
  return true;
224
229
  });
225
230
 
226
231
  api['art::ClassLinker::VisitClasses'](api.artClassLinker.address, collectClassHandles);
227
232
  });
228
233
 
229
- try {
230
- classHandles.forEach(handle => {
231
- const className = env.getClassName(handle);
232
- callbacks.onMatch(className, handle);
233
- });
234
- } finally {
235
- classHandles.forEach(handle => {
236
- env.deleteGlobalRef(handle);
237
- });
238
- }
239
-
240
234
  callbacks.onComplete();
241
235
  }
242
236
 
package/lib/android.js CHANGED
@@ -139,13 +139,25 @@ function _getApi () {
139
139
 
140
140
  const temporaryApi = {
141
141
  module: vmModule,
142
+ find (name) {
143
+ const { module } = this;
144
+ let address = module.findExportByName(name);
145
+ if (address === null) {
146
+ address = module.findSymbolByName(name);
147
+ }
148
+ return address;
149
+ },
142
150
  flavor,
143
151
  addLocalReference: null
144
152
  };
145
153
 
154
+ temporaryApi.isApiLevel34OrApexEquivalent = isArt && (
155
+ temporaryApi.find('_ZN3art7AppInfo29GetPrimaryApkReferenceProfileEv') !== null ||
156
+ temporaryApi.find('_ZN3art6Thread15RunFlipFunctionEPS0_') !== null
157
+ );
158
+
146
159
  const pending = isArt
147
- ? [{
148
- module: vmModule.path,
160
+ ? {
149
161
  functions: {
150
162
  JNI_GetCreatedJavaVMs: ['JNI_GetCreatedJavaVMs', 'int', ['pointer', 'int', 'pointer']],
151
163
 
@@ -312,7 +324,7 @@ function _getApi () {
312
324
  this.isDebuggerActive = () => !!address.readU8();
313
325
  }
314
326
  },
315
- optionals: [
327
+ optionals: new Set([
316
328
  'artInterpreterToCompiledCodeBridge',
317
329
  '_ZN3art9JavaVMExt12AddGlobalRefEPNS_6ThreadENS_6ObjPtrINS_6mirror6ObjectEEE',
318
330
  '_ZN3art9JavaVMExt12AddGlobalRefEPNS_6ThreadEPNS_6mirror6ObjectE',
@@ -360,10 +372,9 @@ function _getApi () {
360
372
  '_ZN3art3jni12JniIdManager14DecodeMethodIdEP10_jmethodID',
361
373
  '_ZN3art11interpreter18GetNterpEntryPointEv',
362
374
  '_ZN3art7Monitor17TranslateLocationEPNS_9ArtMethodEjPPKcPi'
363
- ]
364
- }]
365
- : [{
366
- module: vmModule.path,
375
+ ])
376
+ }
377
+ : {
367
378
  functions: {
368
379
  _Z20dvmDecodeIndirectRefP6ThreadP8_jobject: ['dvmDecodeIndirectRef', 'pointer', ['pointer', 'pointer']],
369
380
  _Z15dvmUseJNIBridgeP6MethodPv: ['dvmUseJNIBridge', 'void', ['pointer', 'pointer']],
@@ -380,52 +391,41 @@ function _getApi () {
380
391
  this.gDvm = address;
381
392
  }
382
393
  }
383
- }];
394
+ };
395
+
396
+ const {
397
+ functions = {},
398
+ variables = {},
399
+ optionals = new Set()
400
+ } = pending;
384
401
 
385
402
  const missing = [];
386
403
 
387
- pending.forEach(function (api) {
388
- const functions = api.functions || {};
389
- const variables = api.variables || {};
390
- const optionals = new Set(api.optionals || []);
391
-
392
- const exportByName = Module
393
- .enumerateExports(api.module)
394
- .reduce(function (result, exp) {
395
- result[exp.name] = exp;
396
- return result;
397
- }, {});
398
-
399
- Object.keys(functions)
400
- .forEach(function (name) {
401
- const exp = exportByName[name];
402
- if (exp !== undefined && exp.type === 'function') {
403
- const signature = functions[name];
404
- if (typeof signature === 'function') {
405
- signature.call(temporaryApi, exp.address);
406
- } else {
407
- temporaryApi[signature[0]] = new NativeFunction(exp.address, signature[1], signature[2], nativeFunctionOptions);
408
- }
409
- } else {
410
- if (!optionals.has(name)) {
411
- missing.push(name);
412
- }
413
- }
414
- });
404
+ for (const [name, signature] of Object.entries(functions)) {
405
+ const address = temporaryApi.find(name);
406
+ if (address !== null) {
407
+ if (typeof signature === 'function') {
408
+ signature.call(temporaryApi, address);
409
+ } else {
410
+ temporaryApi[signature[0]] = new NativeFunction(address, signature[1], signature[2], nativeFunctionOptions);
411
+ }
412
+ } else {
413
+ if (!optionals.has(name)) {
414
+ missing.push(name);
415
+ }
416
+ }
417
+ }
415
418
 
416
- Object.keys(variables)
417
- .forEach(function (name) {
418
- const exp = exportByName[name];
419
- if (exp !== undefined && exp.type === 'variable') {
420
- const handler = variables[name];
421
- handler.call(temporaryApi, exp.address);
422
- } else {
423
- if (!optionals.has(name)) {
424
- missing.push(name);
425
- }
426
- }
427
- });
428
- });
419
+ for (const [name, handler] of Object.entries(variables)) {
420
+ const address = temporaryApi.find(name);
421
+ if (address !== null) {
422
+ handler.call(temporaryApi, address);
423
+ } else {
424
+ if (!optionals.has(name)) {
425
+ missing.push(name);
426
+ }
427
+ }
428
+ }
429
429
 
430
430
  if (missing.length > 0) {
431
431
  throw new Error('Java API only partially available; please file a bug. Missing: ' + missing.join(', '));
@@ -501,9 +501,11 @@ function _getApi () {
501
501
  }
502
502
  if (temporaryApi['art::interpreter::GetNterpEntryPoint'] !== undefined) {
503
503
  temporaryApi.artNterpEntryPoint = temporaryApi['art::interpreter::GetNterpEntryPoint']();
504
+ } else {
505
+ temporaryApi.artNterpEntryPoint = temporaryApi.find('ExecuteNterpImpl');
504
506
  }
505
507
 
506
- artController = makeArtController(vm);
508
+ artController = makeArtController(temporaryApi, vm);
507
509
 
508
510
  fixupArtQuickDeliverExceptionBug(temporaryApi);
509
511
 
@@ -518,7 +520,7 @@ function _getApi () {
518
520
  });
519
521
  }
520
522
 
521
- const cxxImports = Module.enumerateImports(vmModule.path)
523
+ const cxxImports = vmModule.enumerateImports()
522
524
  .filter(imp => imp.name.indexOf('_Z') === 0)
523
525
  .reduce((result, imp) => {
524
526
  result[imp.name] = imp.address;
@@ -536,8 +538,11 @@ function tryGetEnvJvmti (vm, runtime) {
536
538
  let env = null;
537
539
 
538
540
  vm.perform(() => {
539
- const ensurePluginLoaded = new NativeFunction(
540
- Module.getExportByName('libart.so', '_ZN3art7Runtime18EnsurePluginLoadedEPKcPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE'),
541
+ const ensurePluginLoadedAddr = getApi().find('_ZN3art7Runtime18EnsurePluginLoadedEPKcPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE');
542
+ if (ensurePluginLoadedAddr === null) {
543
+ return;
544
+ }
545
+ const ensurePluginLoaded = new NativeFunction(ensurePluginLoadedAddr,
541
546
  'bool',
542
547
  ['pointer', 'pointer', 'pointer']);
543
548
  const errorPtr = Memory.alloc(pointerSize);
@@ -623,7 +628,7 @@ function _getArtRuntimeSpec (api) {
623
628
 
624
629
  const apiLevel = getAndroidApiLevel();
625
630
  const codename = getAndroidCodename();
626
- const isApiLevel34OrApexEquivalent = Module.findExportByName('libart.so', '_ZN3art7AppInfo29GetPrimaryApkReferenceProfileEv') !== null;
631
+ const { isApiLevel34OrApexEquivalent } = api;
627
632
 
628
633
  let spec = null;
629
634
 
@@ -632,7 +637,7 @@ function _getArtRuntimeSpec (api) {
632
637
  if (value.equals(vm)) {
633
638
  let classLinkerOffsets;
634
639
  let jniIdManagerOffset = null;
635
- if (apiLevel >= 33 || codename === 'Tiramisu') {
640
+ if (apiLevel >= 33 || codename === 'Tiramisu' || isApiLevel34OrApexEquivalent) {
636
641
  classLinkerOffsets = [offset - (4 * pointerSize)];
637
642
  jniIdManagerOffset = offset - pointerSize;
638
643
  } else if (apiLevel >= 30 || codename === 'R') {
@@ -685,7 +690,7 @@ function _getArtRuntimeSpec (api) {
685
690
  }
686
691
 
687
692
  spec.offset.instrumentation = tryDetectInstrumentationOffset(api);
688
- spec.offset.jniIdsIndirection = tryDetectJniIdsIndirectionOffset();
693
+ spec.offset.jniIdsIndirection = tryDetectJniIdsIndirectionOffset(api);
689
694
 
690
695
  return spec;
691
696
  }
@@ -771,8 +776,8 @@ const jniIdsIndirectionOffsetParsers = {
771
776
  arm64: parseArm64JniIdsIndirectionOffset
772
777
  };
773
778
 
774
- function tryDetectJniIdsIndirectionOffset () {
775
- const impl = Module.findExportByName('libart.so', '_ZN3art7Runtime12SetJniIdTypeENS_9JniIdTypeE');
779
+ function tryDetectJniIdsIndirectionOffset (api) {
780
+ const impl = api.find('_ZN3art7Runtime12SetJniIdTypeENS_9JniIdTypeE');
776
781
  if (impl === null) {
777
782
  return null;
778
783
  }
@@ -828,6 +833,7 @@ function _getArtInstrumentationSpec () {
828
833
  '4-28': 212,
829
834
  '4-29': 172,
830
835
  '4-30': 180,
836
+ '4-31': 180,
831
837
  '8-21': 224,
832
838
  '8-22': 224,
833
839
  '8-23': 296,
@@ -837,7 +843,8 @@ function _getArtInstrumentationSpec () {
837
843
  '8-27': 352,
838
844
  '8-28': 392,
839
845
  '8-29': 328,
840
- '8-30': 336
846
+ '8-30': 336,
847
+ '8-31': 336
841
848
  };
842
849
 
843
850
  const deoptEnabledOffset = deoptimizationEnabledOffsets[`${pointerSize}-${getAndroidApiLevel()}`];
@@ -943,6 +950,8 @@ function tryGetArtClassLinkerSpec (runtime, runtimeSpec) {
943
950
 
944
951
  if (spec !== null) {
945
952
  cachedArtClassLinkerSpec = spec;
953
+ } else {
954
+ throw new Error('Unable to determine ClassLinker field offsets');
946
955
  }
947
956
 
948
957
  return spec;
@@ -1568,7 +1577,7 @@ function notifyArtMethodHooked (method, vm) {
1568
1577
  ensureArtKnowsHowToHandleReplacementMethods(vm);
1569
1578
  }
1570
1579
 
1571
- function makeArtController (vm) {
1580
+ function makeArtController (api, vm) {
1572
1581
  const threadOffsets = getArtThreadSpec(vm).offset;
1573
1582
  const managedStackOffsets = getArtManagedStackSpec().offset;
1574
1583
 
@@ -1776,10 +1785,9 @@ on_leave_gc_concurrent_copying_copying_phase (GumInvocationContext * ic)
1776
1785
  const replacements = methods.add(methodsSize);
1777
1786
  const lastSeenArtMethod = replacements.add(replacementsSize);
1778
1787
 
1779
- const getOatQuickMethodHeaderImpl = Module.findExportByName('libart.so',
1780
- (pointerSize === 4)
1781
- ? '_ZN3art9ArtMethod23GetOatQuickMethodHeaderEj'
1782
- : '_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm');
1788
+ const getOatQuickMethodHeaderImpl = api.find((pointerSize === 4)
1789
+ ? '_ZN3art9ArtMethod23GetOatQuickMethodHeaderEj'
1790
+ : '_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm');
1783
1791
 
1784
1792
  const cm = new CModule(code, {
1785
1793
  lock,
@@ -1853,19 +1861,31 @@ function instrumentArtQuickEntrypoints (vm) {
1853
1861
  }
1854
1862
 
1855
1863
  function instrumentArtMethodInvocationFromInterpreter () {
1864
+ const api = getApi();
1865
+
1856
1866
  const apiLevel = getAndroidApiLevel();
1867
+ const { isApiLevel34OrApexEquivalent } = api;
1857
1868
 
1858
1869
  let artInterpreterDoCallExportRegex;
1859
1870
  if (apiLevel <= 22) {
1860
1871
  artInterpreterDoCallExportRegex = /^_ZN3art11interpreter6DoCallILb[0-1]ELb[0-1]EEEbPNS_6mirror9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE$/;
1861
- } else if (apiLevel <= 33) {
1872
+ } else if (apiLevel <= 33 && !isApiLevel34OrApexEquivalent) {
1862
1873
  artInterpreterDoCallExportRegex = /^_ZN3art11interpreter6DoCallILb[0-1]ELb[0-1]EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE$/;
1863
- } else {
1874
+ } else if (isApiLevel34OrApexEquivalent) {
1864
1875
  artInterpreterDoCallExportRegex = /^_ZN3art11interpreter6DoCallILb[0-1]EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtbPNS_6JValueE$/;
1876
+ } else {
1877
+ throw new Error('Unable to find method invocation in ART; please file a bug');
1878
+ }
1879
+
1880
+ const art = api.module;
1881
+ const entries = [...art.enumerateExports(), ...art.enumerateSymbols()].filter(entry => artInterpreterDoCallExportRegex.test(entry.name));
1882
+
1883
+ if (entries.length === 0) {
1884
+ throw new Error('Unable to find method invocation in ART; please file a bug');
1865
1885
  }
1866
1886
 
1867
- for (const exp of Module.enumerateExports('libart.so').filter(exp => artInterpreterDoCallExportRegex.test(exp.name))) {
1868
- Interceptor.attach(exp.address, artController.hooks.Interpreter.doCall);
1887
+ for (const entry of entries) {
1888
+ Interceptor.attach(entry.address, artController.hooks.Interpreter.doCall);
1869
1889
  }
1870
1890
  }
1871
1891
 
@@ -1893,29 +1913,24 @@ function ensureArtKnowsHowToHandleReplacementMethods (vm) {
1893
1913
 
1894
1914
  const apiLevel = getAndroidApiLevel();
1895
1915
 
1896
- const mayUseCollector = (apiLevel > 28)
1897
- ? (type) => {
1898
- const impl = Module.findExportByName('libart.so', '_ZNK3art2gc4Heap15MayUseCollectorENS0_13CollectorTypeE');
1899
- if (impl === null) {
1900
- return false;
1901
- }
1902
- return new NativeFunction(impl, 'bool', ['pointer', 'int'])(getApi().artHeap, type);
1903
- }
1904
- : () => false;
1905
- const kCollectorTypeCMC = 3;
1916
+ let copyingPhase = null;
1917
+ const api = getApi();
1918
+ if (apiLevel > 28) {
1919
+ copyingPhase = api.find('_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv');
1920
+ } else if (apiLevel > 22) {
1921
+ copyingPhase = api.find('_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv');
1922
+ }
1923
+ if (copyingPhase !== null) {
1924
+ Interceptor.attach(copyingPhase, artController.hooks.Gc.copyingPhase);
1925
+ }
1906
1926
 
1907
- if (mayUseCollector(kCollectorTypeCMC)) {
1908
- Interceptor.attach(Module.getExportByName('libart.so', '_ZN3art6Thread15RunFlipFunctionEPS0_b'), artController.hooks.Gc.runFlip);
1909
- } else {
1910
- let copyingPhase = null;
1911
- if (apiLevel > 28) {
1912
- copyingPhase = Module.findExportByName('libart.so', '_ZN3art2gc9collector17ConcurrentCopying12CopyingPhaseEv');
1913
- } else if (apiLevel > 22) {
1914
- copyingPhase = Module.findExportByName('libart.so', '_ZN3art2gc9collector17ConcurrentCopying12MarkingPhaseEv');
1915
- }
1916
- if (copyingPhase !== null) {
1917
- Interceptor.attach(copyingPhase, artController.hooks.Gc.copyingPhase);
1918
- }
1927
+ let runFlip = null;
1928
+ runFlip = api.find('_ZN3art6Thread15RunFlipFunctionEPS0_');
1929
+ if (runFlip === null) {
1930
+ runFlip = api.find('_ZN3art6Thread15RunFlipFunctionEPS0_b');
1931
+ }
1932
+ if (runFlip !== null) {
1933
+ Interceptor.attach(runFlip, artController.hooks.Gc.runFlip);
1919
1934
  }
1920
1935
  }
1921
1936
 
@@ -3414,7 +3429,7 @@ class ArtMethodMangler {
3414
3429
 
3415
3430
  // Replace Nterp quick entrypoints with art_quick_to_interpreter_bridge to force stepping out
3416
3431
  // of ART's next-generation interpreter and use the quick stub instead.
3417
- if (artNterpEntryPoint !== undefined && quickCode.equals(artNterpEntryPoint)) {
3432
+ if (artNterpEntryPoint !== null && quickCode.equals(artNterpEntryPoint)) {
3418
3433
  patchArtMethod(hookedMethodId, {
3419
3434
  quickCode: api.artQuickToInterpreterBridge
3420
3435
  }, vm);
@@ -3925,9 +3940,24 @@ const threadStateTransitionRecompilers = {
3925
3940
  };
3926
3941
 
3927
3942
  function makeArtThreadStateTransitionImpl (vm, env, callback) {
3943
+ const api = getApi();
3928
3944
  const envVtable = env.handle.readPointer();
3929
- const exceptionClearImpl = envVtable.add(ENV_VTABLE_OFFSET_EXCEPTION_CLEAR).readPointer();
3930
- const nextFuncImpl = envVtable.add(ENV_VTABLE_OFFSET_FATAL_ERROR).readPointer();
3945
+
3946
+ let exceptionClearImpl;
3947
+ const innerExceptionClearImpl = api.find('_ZN3art3JNIILb1EE14ExceptionClearEP7_JNIEnv');
3948
+ if (innerExceptionClearImpl !== null) {
3949
+ exceptionClearImpl = innerExceptionClearImpl;
3950
+ } else {
3951
+ exceptionClearImpl = envVtable.add(ENV_VTABLE_OFFSET_EXCEPTION_CLEAR).readPointer();
3952
+ }
3953
+
3954
+ let nextFuncImpl;
3955
+ const innerNextFuncImpl = api.find('_ZN3art3JNIILb1EE10FatalErrorEP7_JNIEnvPKc');
3956
+ if (innerNextFuncImpl !== null) {
3957
+ nextFuncImpl = innerNextFuncImpl;
3958
+ } else {
3959
+ nextFuncImpl = envVtable.add(ENV_VTABLE_OFFSET_FATAL_ERROR).readPointer();
3960
+ }
3931
3961
 
3932
3962
  const recompile = threadStateTransitionRecompilers[Process.arch];
3933
3963
  if (recompile === undefined) {
@@ -16,6 +16,8 @@ const {
16
16
  makeJniObjectTypeName
17
17
  } = require('./types');
18
18
 
19
+ const kAccStatic = 0x0008;
20
+
19
21
  const CONSTRUCTOR_METHOD = 1;
20
22
  const STATIC_METHOD = 2;
21
23
  const INSTANCE_METHOD = 3;
@@ -450,6 +452,9 @@ class ClassFactory {
450
452
  impl = methodValue;
451
453
  }
452
454
  } else {
455
+ if (methodValue.isStatic) {
456
+ type = STATIC_METHOD;
457
+ }
453
458
  returnType = this._getType(methodValue.returnType || 'void');
454
459
  argumentTypes = (methodValue.argumentTypes || []).map(name => this._getType(name));
455
460
  impl = methodValue.implementation;
@@ -479,7 +484,7 @@ class ClassFactory {
479
484
  const argumentTypeNames = argumentTypes.map(t => t.name);
480
485
  const signature = '(' + argumentTypeNames.join('') + ')' + returnTypeName;
481
486
 
482
- dexMethods.push([name, returnTypeName, argumentTypeNames, thrownTypeNames]);
487
+ dexMethods.push([name, returnTypeName, argumentTypeNames, thrownTypeNames, (type === STATIC_METHOD) ? kAccStatic : 0]);
483
488
  implMethods.push([name, signature, type, returnType, argumentTypes, impl]);
484
489
  });
485
490
 
@@ -566,15 +571,16 @@ class ClassFactory {
566
571
  const JVMTI_HEAP_OBJECT_EITHER = 3;
567
572
 
568
573
  const h = classWrapper.$borrowClassHandle(env);
574
+ const tag = int64(h.value.toString());
569
575
  try {
570
576
  const heapObjectCallback = new NativeCallback((classTag, size, tagPtr, userData) => {
571
- tagPtr.writePointer(h.value);
577
+ tagPtr.writeS64(tag);
572
578
  return JVMTI_ITERATION_CONTINUE;
573
- }, 'int', ['long', 'long', 'pointer', 'pointer']);
579
+ }, 'int', ['int64', 'int64', 'pointer', 'pointer']);
574
580
  jvmti.iterateOverInstancesOfClass(h.value, JVMTI_HEAP_OBJECT_EITHER, heapObjectCallback, h.value);
575
581
 
576
- const tagPtr = Memory.alloc(pointerSize);
577
- tagPtr.writePointer(h.value);
582
+ const tagPtr = Memory.alloc(8);
583
+ tagPtr.writeS64(tag);
578
584
  const countPtr = Memory.alloc(jsizeSize);
579
585
  const objectsPtr = Memory.alloc(pointerSize);
580
586
  jvmti.getObjectsWithTags(1, tagPtr, countPtr, objectsPtr, NULL);
package/lib/mkdex.js CHANGED
@@ -530,7 +530,7 @@ function computeModel (classes) {
530
530
  }
531
531
 
532
532
  klass.methods.forEach(method => {
533
- const [methodName, retType, argTypes, thrownTypes = []] = method;
533
+ const [methodName, retType, argTypes, thrownTypes = [], accessFlags] = method;
534
534
 
535
535
  strings.add(methodName);
536
536
 
@@ -563,13 +563,13 @@ function computeModel (classes) {
563
563
  strings.add('value');
564
564
  }
565
565
 
566
- methods.push([klass.name, protoId, methodName, throwsAnnotationId]);
566
+ methods.push([klass.name, protoId, methodName, throwsAnnotationId, accessFlags]);
567
567
 
568
568
  if (methodName === '<init>') {
569
569
  superConstructors.add(name + '|' + protoId);
570
570
  const superConstructorId = superClass + '|' + protoId;
571
571
  if (javaConstructors.has(name) && !superConstructors.has(superConstructorId)) {
572
- methods.push([superClass, protoId, methodName, null]);
572
+ methods.push([superClass, protoId, methodName, null, 0]);
573
573
  superConstructors.add(superConstructorId);
574
574
  }
575
575
  }
@@ -658,12 +658,13 @@ function computeModel (classes) {
658
658
  fieldItems.sort(compareFieldItems);
659
659
 
660
660
  const methodItems = methods.map(method => {
661
- const [klass, protoId, name, annotationsId] = method;
661
+ const [klass, protoId, name, annotationsId, accessFlags] = method;
662
662
  return [
663
663
  typeToIndex[klass],
664
664
  protoToIndex[protoId],
665
665
  stringToIndex[name],
666
- annotationsId
666
+ annotationsId,
667
+ accessFlags
667
668
  ];
668
669
  });
669
670
  methodItems.sort(compareMethodItems);
@@ -719,9 +720,9 @@ function computeModel (classes) {
719
720
  const sourceFileIndex = stringToIndex[klass.sourceFileName];
720
721
 
721
722
  const classMethods = methodItems.reduce((result, method, index) => {
722
- const [holder, protoIndex, name, annotationsId] = method;
723
+ const [holder, protoIndex, name, annotationsId, accessFlags] = method;
723
724
  if (holder === classIndex) {
724
- result.push([index, name, annotationsId, protoIndex]);
725
+ result.push([index, name, annotationsId, protoIndex, accessFlags]);
725
726
  }
726
727
  return result;
727
728
  }, []);
@@ -771,8 +772,8 @@ function computeModel (classes) {
771
772
  });
772
773
  const virtualMethods = compressClassMethodIndexes(classMethods
773
774
  .filter(([, name]) => name !== constructorNameIndex)
774
- .map(([index]) => {
775
- return [index, kAccPublic | kAccNative];
775
+ .map(([index, , , , accessFlags]) => {
776
+ return [index, accessFlags | kAccPublic | kAccNative];
776
777
  }));
777
778
 
778
779
  const classData = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frida-java-bridge",
3
- "version": "6.3.6",
3
+ "version": "6.3.8",
4
4
  "description": "Java runtime interop from Frida",
5
5
  "main": "index.js",
6
6
  "files": [