frida-java-bridge 6.1.1 → 6.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.
Files changed (3) hide show
  1. package/index.js +13 -0
  2. package/lib/android.js +78 -16
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -21,6 +21,19 @@ const jsizeSize = 4;
21
21
  const pointerSize = Process.pointerSize;
22
22
 
23
23
  class Runtime {
24
+ ACC_PUBLIC = 0x0001;
25
+ ACC_PRIVATE = 0x0002;
26
+ ACC_PROTECTED = 0x0004;
27
+ ACC_STATIC = 0x0008;
28
+ ACC_FINAL = 0x0010;
29
+ ACC_SYNCHRONIZED = 0x0020;
30
+ ACC_BRIDGE = 0x0040;
31
+ ACC_VARARGS = 0x0080;
32
+ ACC_NATIVE = 0x0100;
33
+ ACC_ABSTRACT = 0x0400;
34
+ ACC_STRICT = 0x0800;
35
+ ACC_SYNTHETIC = 0x1000;
36
+
24
37
  constructor () {
25
38
  this.classFactory = null;
26
39
  this.ClassFactory = ClassFactory;
package/lib/android.js CHANGED
@@ -30,6 +30,7 @@ const kAccSkipAccessChecks = 0x00080000;
30
30
  const kAccSingleImplementation = 0x08000000;
31
31
  const kAccNterpEntryPointFastPathFlag = 0x00100000;
32
32
  const kAccNterpInvokeFastPathFlag = 0x00200000;
33
+ const kAccCompileDontBother = 0x01000000;
33
34
  const kAccPublicApi = 0x10000000;
34
35
  const kAccXposedHookedMethod = 0x10000000;
35
36
 
@@ -242,6 +243,9 @@ function _getApi () {
242
243
  _ZN3art6mirror5Class13GetDescriptorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE: function (address) {
243
244
  this['art::mirror::Class::GetDescriptor'] = address;
244
245
  },
246
+ _ZN3art6mirror5Class11GetLocationEv: function (address) {
247
+ this['art::mirror::Class::GetLocation'] = makeCxxMethodWrapperReturningStdStringByValue(address, ['pointer']);
248
+ },
245
249
 
246
250
  _ZN3art9ArtMethod12PrettyMethodEb: function (address) {
247
251
  this['art::ArtMethod::PrettyMethod'] = makeCxxMethodWrapperReturningStdStringByValue(address, ['pointer', 'bool']);
@@ -332,6 +336,7 @@ function _getApi () {
332
336
  '_ZNK3art12StackVisitor24GetCurrentQuickFrameInfoEv',
333
337
  '_ZN3art6Thread18GetLongJumpContextEv',
334
338
  '_ZN3art6mirror5Class13GetDescriptorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE',
339
+ '_ZN3art6mirror5Class11GetLocationEv',
335
340
  '_ZN3art9ArtMethod12PrettyMethodEb',
336
341
  '_ZN3art12PrettyMethodEPNS_9ArtMethodEb',
337
342
  '_ZN3art3Dbg13ConfigureJdwpERKNS_4JDWP11JdwpOptionsE',
@@ -2062,6 +2067,10 @@ function maybeInstrumentGetOatQuickMethodHeaderInlineCopies () {
2062
2067
  }
2063
2068
  }
2064
2069
 
2070
+ if (impls.length === 0) {
2071
+ return false;
2072
+ }
2073
+
2065
2074
  impls.forEach(handler.instrument);
2066
2075
 
2067
2076
  return true;
@@ -2266,6 +2275,7 @@ typedef struct _ArtStackFrame ArtStackFrame;
2266
2275
  typedef struct _ArtStackVisitor ArtStackVisitor;
2267
2276
  typedef struct _ArtStackVisitorVTable ArtStackVisitorVTable;
2268
2277
 
2278
+ typedef struct _ArtClass ArtClass;
2269
2279
  typedef struct _ArtMethod ArtMethod;
2270
2280
  typedef struct _ArtThread ArtThread;
2271
2281
  typedef struct _ArtContext ArtContext;
@@ -2336,6 +2346,12 @@ struct _ArtStackVisitor
2336
2346
  ArtBacktrace * backtrace;
2337
2347
  };
2338
2348
 
2349
+ struct _ArtMethod
2350
+ {
2351
+ guint32 declaring_class;
2352
+ guint32 access_flags;
2353
+ };
2354
+
2339
2355
  extern GumTlsKey current_backtrace;
2340
2356
 
2341
2357
  extern void (* perform_art_thread_state_transition) (JNIEnv * env);
@@ -2349,6 +2365,7 @@ extern ArtMethod * art_stack_visitor_get_method (ArtStackVisitor * visitor);
2349
2365
  extern void art_stack_visitor_describe_location (StdString * description, ArtStackVisitor * visitor);
2350
2366
  extern ArtMethod * translate_method (ArtMethod * method);
2351
2367
  extern void translate_location (ArtMethod * method, guint32 pc, const gchar ** source_file, gint32 * line_number);
2368
+ extern void get_class_location (StdString * result, ArtClass * klass);
2352
2369
  extern void cxx_delete (void * mem);
2353
2370
  extern unsigned long strtoul (const char * str, char ** endptr, int base);
2354
2371
 
@@ -2491,6 +2508,7 @@ _get_frames (ArtBacktrace * backtrace)
2491
2508
  GString * signature;
2492
2509
  gchar * cursor;
2493
2510
  ArtMethod * translated_method;
2511
+ StdString location;
2494
2512
  gsize dexpc;
2495
2513
  const gchar * source_file;
2496
2514
  gint32 line_number;
@@ -2555,6 +2573,8 @@ _get_frames (ArtBacktrace * backtrace)
2555
2573
  translated_method = translate_method (frame->method);
2556
2574
  dexpc = (translated_method == frame->method) ? frame->dexpc : 0;
2557
2575
 
2576
+ get_class_location (&location, GSIZE_TO_POINTER (translated_method->declaring_class));
2577
+
2558
2578
  translate_location (translated_method, dexpc, &source_file, &line_number);
2559
2579
 
2560
2580
  json_builder_begin_object (b);
@@ -2562,12 +2582,18 @@ _get_frames (ArtBacktrace * backtrace)
2562
2582
  json_builder_set_member_name (b, "signature");
2563
2583
  json_builder_add_string_value (b, signature->str);
2564
2584
 
2585
+ json_builder_set_member_name (b, "origin");
2586
+ json_builder_add_string_value (b, std_string_get_data (&location));
2587
+
2565
2588
  json_builder_set_member_name (b, "className");
2566
2589
  json_builder_add_string_value (b, class_name);
2567
2590
 
2568
2591
  json_builder_set_member_name (b, "methodName");
2569
2592
  json_builder_add_string_value (b, method_name);
2570
2593
 
2594
+ json_builder_set_member_name (b, "methodFlags");
2595
+ json_builder_add_int_value (b, translated_method->access_flags);
2596
+
2571
2597
  json_builder_set_member_name (b, "fileName");
2572
2598
  json_builder_add_string_value (b, source_file);
2573
2599
 
@@ -2576,6 +2602,7 @@ _get_frames (ArtBacktrace * backtrace)
2576
2602
 
2577
2603
  json_builder_end_object (b);
2578
2604
 
2605
+ std_string_destroy (&location);
2579
2606
  g_string_free (signature, TRUE);
2580
2607
  }
2581
2608
 
@@ -2687,6 +2714,7 @@ std_string_get_data (StdString * str)
2687
2714
  art_stack_visitor_describe_location: api['art::StackVisitor::DescribeLocation'],
2688
2715
  translate_method: artController.replacedMethods.translate,
2689
2716
  translate_location: api['art::Monitor::TranslateLocation'],
2717
+ get_class_location: api['art::mirror::Class::GetLocation'],
2690
2718
  cxx_delete: api.$delete,
2691
2719
  strtoul: Module.getExportByName('libc.so', 'strtoul')
2692
2720
  });
@@ -2782,7 +2810,7 @@ const artQuickCodeReplacementTrampolineWriters = {
2782
2810
  arm64: writeArtQuickCodeReplacementTrampolineArm64
2783
2811
  };
2784
2812
 
2785
- function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, vm) {
2813
+ function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, constraints, vm) {
2786
2814
  const threadOffsets = getArtThreadSpec(vm).offset;
2787
2815
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2788
2816
 
@@ -2845,7 +2873,7 @@ function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirec
2845
2873
  return offset;
2846
2874
  }
2847
2875
 
2848
- function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, vm) {
2876
+ function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, constraints, vm) {
2849
2877
  const threadOffsets = getArtThreadSpec(vm).offset;
2850
2878
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2851
2879
 
@@ -2908,7 +2936,7 @@ function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirect
2908
2936
  return offset;
2909
2937
  }
2910
2938
 
2911
- function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, vm) {
2939
+ function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, constraints, vm) {
2912
2940
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2913
2941
 
2914
2942
  const targetAddress = target.and(THUMB_BIT_REMOVAL_MASK);
@@ -2995,7 +3023,7 @@ function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirect
2995
3023
  return offset;
2996
3024
  }
2997
3025
 
2998
- function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, vm) {
3026
+ function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, { availableScratchRegs }, vm) {
2999
3027
  const artMethodOffsets = getArtMethodSpec(vm).offset;
3000
3028
 
3001
3029
  let offset;
@@ -3064,8 +3092,9 @@ function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redire
3064
3092
  relocator.writeAll();
3065
3093
 
3066
3094
  if (!relocator.eoi) {
3067
- writer.putLdrRegAddress('x17', target.add(offset));
3068
- writer.putBrReg('x17');
3095
+ const scratchReg = Array.from(availableScratchRegs)[0];
3096
+ writer.putLdrRegAddress(scratchReg, target.add(offset));
3097
+ writer.putBrReg(scratchReg);
3069
3098
  }
3070
3099
 
3071
3100
  writer.putLabel('invoke_replacement');
@@ -3142,7 +3171,7 @@ class ArtQuickCodeInterceptor {
3142
3171
  this.overwrittenPrologueLength = 0;
3143
3172
  }
3144
3173
 
3145
- _canRelocateCode (relocationSize) {
3174
+ _canRelocateCode (relocationSize, constraints) {
3146
3175
  const Writer = thunkWriters[Process.arch];
3147
3176
  const Relocator = thunkRelocators[Process.arch];
3148
3177
 
@@ -3152,14 +3181,44 @@ class ArtQuickCodeInterceptor {
3152
3181
  const relocator = new Relocator(quickCodeAddress, writer);
3153
3182
 
3154
3183
  let offset;
3155
- do {
3156
- offset = relocator.readOne();
3157
- } while (offset < relocationSize && !relocator.eoi);
3184
+ if (Process.arch === 'arm64') {
3185
+ let availableScratchRegs = new Set(['x16', 'x17']);
3186
+
3187
+ do {
3188
+ const nextOffset = relocator.readOne();
3189
+
3190
+ const nextScratchRegs = new Set(availableScratchRegs);
3191
+ const { read, written } = relocator.input.regsAccessed;
3192
+ for (const regs of [read, written]) {
3193
+ for (const reg of regs) {
3194
+ let name;
3195
+ if (reg.startsWith('w')) {
3196
+ name = 'x' + reg.substring(1);
3197
+ } else {
3198
+ name = reg;
3199
+ }
3200
+ nextScratchRegs.delete(name);
3201
+ }
3202
+ }
3203
+ if (nextScratchRegs.size === 0) {
3204
+ break;
3205
+ }
3206
+
3207
+ offset = nextOffset;
3208
+ availableScratchRegs = nextScratchRegs;
3209
+ } while (offset < relocationSize && !relocator.eoi);
3210
+
3211
+ constraints.availableScratchRegs = availableScratchRegs;
3212
+ } else {
3213
+ do {
3214
+ offset = relocator.readOne();
3215
+ } while (offset < relocationSize && !relocator.eoi);
3216
+ }
3158
3217
 
3159
3218
  return offset >= relocationSize;
3160
3219
  }
3161
3220
 
3162
- _createTrampoline () {
3221
+ _allocateTrampoline () {
3163
3222
  if (trampolineAllocator === null) {
3164
3223
  const trampolineSize = (pointerSize === 4) ? 128 : 256;
3165
3224
  trampolineAllocator = makeCodeAllocator(trampolineSize);
@@ -3169,7 +3228,8 @@ class ArtQuickCodeInterceptor {
3169
3228
 
3170
3229
  let redirectSize, spec;
3171
3230
  let alignment = 1;
3172
- if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize)) {
3231
+ const constraints = {};
3232
+ if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize, constraints)) {
3173
3233
  redirectSize = maxRedirectSize;
3174
3234
 
3175
3235
  spec = {};
@@ -3189,6 +3249,8 @@ class ArtQuickCodeInterceptor {
3189
3249
 
3190
3250
  this.redirectSize = redirectSize;
3191
3251
  this.trampoline = trampolineAllocator.allocateSlice(spec, alignment);
3252
+
3253
+ return constraints;
3192
3254
  }
3193
3255
 
3194
3256
  _destroyTrampoline () {
@@ -3196,12 +3258,12 @@ class ArtQuickCodeInterceptor {
3196
3258
  }
3197
3259
 
3198
3260
  activate (vm) {
3199
- this._createTrampoline();
3261
+ const constraints = this._allocateTrampoline();
3200
3262
 
3201
3263
  const { trampoline, quickCode, redirectSize } = this;
3202
3264
 
3203
3265
  const writeTrampoline = artQuickCodeReplacementTrampolineWriters[Process.arch];
3204
- const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, vm);
3266
+ const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, constraints, vm);
3205
3267
  this.overwrittenPrologueLength = prologueLength;
3206
3268
 
3207
3269
  this.overwrittenPrologue = Memory.dup(this.quickCodeAddress, prologueLength);
@@ -3269,7 +3331,7 @@ class ArtMethodMangler {
3269
3331
 
3270
3332
  patchArtMethod(replacementMethodId, {
3271
3333
  jniCode: impl,
3272
- accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative | kAccNterpEntryPointFastPathFlag)) | kAccNative) >>> 0,
3334
+ accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative | kAccNterpEntryPointFastPathFlag)) | kAccNative | kAccCompileDontBother) >>> 0,
3273
3335
  quickCode: api.artClassLinker.quickGenericJniTrampoline,
3274
3336
  interpreterCode: api.artInterpreterToCompiledCodeBridge
3275
3337
  }, vm);
@@ -3282,7 +3344,7 @@ class ArtMethodMangler {
3282
3344
  }
3283
3345
 
3284
3346
  patchArtMethod(hookedMethodId, {
3285
- accessFlags: (originalFlags & ~(hookedMethodRemovedFlags)) >>> 0
3347
+ accessFlags: ((originalFlags & ~(hookedMethodRemovedFlags)) | kAccCompileDontBother) >>> 0
3286
3348
  }, vm);
3287
3349
 
3288
3350
  const quickCode = this.originalMethod.quickCode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frida-java-bridge",
3
- "version": "6.1.1",
3
+ "version": "6.2.0",
4
4
  "description": "Java runtime interop from Frida",
5
5
  "main": "index.js",
6
6
  "files": [