frida-java-bridge 6.1.2 → 6.2.1

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 +74 -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 = 0x02000000;
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',
@@ -2270,6 +2275,7 @@ typedef struct _ArtStackFrame ArtStackFrame;
2270
2275
  typedef struct _ArtStackVisitor ArtStackVisitor;
2271
2276
  typedef struct _ArtStackVisitorVTable ArtStackVisitorVTable;
2272
2277
 
2278
+ typedef struct _ArtClass ArtClass;
2273
2279
  typedef struct _ArtMethod ArtMethod;
2274
2280
  typedef struct _ArtThread ArtThread;
2275
2281
  typedef struct _ArtContext ArtContext;
@@ -2340,6 +2346,12 @@ struct _ArtStackVisitor
2340
2346
  ArtBacktrace * backtrace;
2341
2347
  };
2342
2348
 
2349
+ struct _ArtMethod
2350
+ {
2351
+ guint32 declaring_class;
2352
+ guint32 access_flags;
2353
+ };
2354
+
2343
2355
  extern GumTlsKey current_backtrace;
2344
2356
 
2345
2357
  extern void (* perform_art_thread_state_transition) (JNIEnv * env);
@@ -2353,6 +2365,7 @@ extern ArtMethod * art_stack_visitor_get_method (ArtStackVisitor * visitor);
2353
2365
  extern void art_stack_visitor_describe_location (StdString * description, ArtStackVisitor * visitor);
2354
2366
  extern ArtMethod * translate_method (ArtMethod * method);
2355
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);
2356
2369
  extern void cxx_delete (void * mem);
2357
2370
  extern unsigned long strtoul (const char * str, char ** endptr, int base);
2358
2371
 
@@ -2495,6 +2508,7 @@ _get_frames (ArtBacktrace * backtrace)
2495
2508
  GString * signature;
2496
2509
  gchar * cursor;
2497
2510
  ArtMethod * translated_method;
2511
+ StdString location;
2498
2512
  gsize dexpc;
2499
2513
  const gchar * source_file;
2500
2514
  gint32 line_number;
@@ -2559,6 +2573,8 @@ _get_frames (ArtBacktrace * backtrace)
2559
2573
  translated_method = translate_method (frame->method);
2560
2574
  dexpc = (translated_method == frame->method) ? frame->dexpc : 0;
2561
2575
 
2576
+ get_class_location (&location, GSIZE_TO_POINTER (translated_method->declaring_class));
2577
+
2562
2578
  translate_location (translated_method, dexpc, &source_file, &line_number);
2563
2579
 
2564
2580
  json_builder_begin_object (b);
@@ -2566,12 +2582,18 @@ _get_frames (ArtBacktrace * backtrace)
2566
2582
  json_builder_set_member_name (b, "signature");
2567
2583
  json_builder_add_string_value (b, signature->str);
2568
2584
 
2585
+ json_builder_set_member_name (b, "origin");
2586
+ json_builder_add_string_value (b, std_string_get_data (&location));
2587
+
2569
2588
  json_builder_set_member_name (b, "className");
2570
2589
  json_builder_add_string_value (b, class_name);
2571
2590
 
2572
2591
  json_builder_set_member_name (b, "methodName");
2573
2592
  json_builder_add_string_value (b, method_name);
2574
2593
 
2594
+ json_builder_set_member_name (b, "methodFlags");
2595
+ json_builder_add_int_value (b, translated_method->access_flags);
2596
+
2575
2597
  json_builder_set_member_name (b, "fileName");
2576
2598
  json_builder_add_string_value (b, source_file);
2577
2599
 
@@ -2580,6 +2602,7 @@ _get_frames (ArtBacktrace * backtrace)
2580
2602
 
2581
2603
  json_builder_end_object (b);
2582
2604
 
2605
+ std_string_destroy (&location);
2583
2606
  g_string_free (signature, TRUE);
2584
2607
  }
2585
2608
 
@@ -2691,6 +2714,7 @@ std_string_get_data (StdString * str)
2691
2714
  art_stack_visitor_describe_location: api['art::StackVisitor::DescribeLocation'],
2692
2715
  translate_method: artController.replacedMethods.translate,
2693
2716
  translate_location: api['art::Monitor::TranslateLocation'],
2717
+ get_class_location: api['art::mirror::Class::GetLocation'],
2694
2718
  cxx_delete: api.$delete,
2695
2719
  strtoul: Module.getExportByName('libc.so', 'strtoul')
2696
2720
  });
@@ -2786,7 +2810,7 @@ const artQuickCodeReplacementTrampolineWriters = {
2786
2810
  arm64: writeArtQuickCodeReplacementTrampolineArm64
2787
2811
  };
2788
2812
 
2789
- function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, vm) {
2813
+ function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirectSize, constraints, vm) {
2790
2814
  const threadOffsets = getArtThreadSpec(vm).offset;
2791
2815
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2792
2816
 
@@ -2849,7 +2873,7 @@ function writeArtQuickCodeReplacementTrampolineIA32 (trampoline, target, redirec
2849
2873
  return offset;
2850
2874
  }
2851
2875
 
2852
- function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, vm) {
2876
+ function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirectSize, constraints, vm) {
2853
2877
  const threadOffsets = getArtThreadSpec(vm).offset;
2854
2878
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2855
2879
 
@@ -2912,7 +2936,7 @@ function writeArtQuickCodeReplacementTrampolineX64 (trampoline, target, redirect
2912
2936
  return offset;
2913
2937
  }
2914
2938
 
2915
- function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, vm) {
2939
+ function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirectSize, constraints, vm) {
2916
2940
  const artMethodOffsets = getArtMethodSpec(vm).offset;
2917
2941
 
2918
2942
  const targetAddress = target.and(THUMB_BIT_REMOVAL_MASK);
@@ -2999,7 +3023,7 @@ function writeArtQuickCodeReplacementTrampolineArm (trampoline, target, redirect
2999
3023
  return offset;
3000
3024
  }
3001
3025
 
3002
- function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, vm) {
3026
+ function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redirectSize, { availableScratchRegs }, vm) {
3003
3027
  const artMethodOffsets = getArtMethodSpec(vm).offset;
3004
3028
 
3005
3029
  let offset;
@@ -3068,8 +3092,9 @@ function writeArtQuickCodeReplacementTrampolineArm64 (trampoline, target, redire
3068
3092
  relocator.writeAll();
3069
3093
 
3070
3094
  if (!relocator.eoi) {
3071
- writer.putLdrRegAddress('x17', target.add(offset));
3072
- writer.putBrReg('x17');
3095
+ const scratchReg = Array.from(availableScratchRegs)[0];
3096
+ writer.putLdrRegAddress(scratchReg, target.add(offset));
3097
+ writer.putBrReg(scratchReg);
3073
3098
  }
3074
3099
 
3075
3100
  writer.putLabel('invoke_replacement');
@@ -3146,7 +3171,7 @@ class ArtQuickCodeInterceptor {
3146
3171
  this.overwrittenPrologueLength = 0;
3147
3172
  }
3148
3173
 
3149
- _canRelocateCode (relocationSize) {
3174
+ _canRelocateCode (relocationSize, constraints) {
3150
3175
  const Writer = thunkWriters[Process.arch];
3151
3176
  const Relocator = thunkRelocators[Process.arch];
3152
3177
 
@@ -3156,14 +3181,44 @@ class ArtQuickCodeInterceptor {
3156
3181
  const relocator = new Relocator(quickCodeAddress, writer);
3157
3182
 
3158
3183
  let offset;
3159
- do {
3160
- offset = relocator.readOne();
3161
- } 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
+ }
3162
3217
 
3163
3218
  return offset >= relocationSize;
3164
3219
  }
3165
3220
 
3166
- _createTrampoline () {
3221
+ _allocateTrampoline () {
3167
3222
  if (trampolineAllocator === null) {
3168
3223
  const trampolineSize = (pointerSize === 4) ? 128 : 256;
3169
3224
  trampolineAllocator = makeCodeAllocator(trampolineSize);
@@ -3173,7 +3228,8 @@ class ArtQuickCodeInterceptor {
3173
3228
 
3174
3229
  let redirectSize, spec;
3175
3230
  let alignment = 1;
3176
- if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize)) {
3231
+ const constraints = {};
3232
+ if (pointerSize === 4 || this._canRelocateCode(maxRedirectSize, constraints)) {
3177
3233
  redirectSize = maxRedirectSize;
3178
3234
 
3179
3235
  spec = {};
@@ -3193,6 +3249,8 @@ class ArtQuickCodeInterceptor {
3193
3249
 
3194
3250
  this.redirectSize = redirectSize;
3195
3251
  this.trampoline = trampolineAllocator.allocateSlice(spec, alignment);
3252
+
3253
+ return constraints;
3196
3254
  }
3197
3255
 
3198
3256
  _destroyTrampoline () {
@@ -3200,12 +3258,12 @@ class ArtQuickCodeInterceptor {
3200
3258
  }
3201
3259
 
3202
3260
  activate (vm) {
3203
- this._createTrampoline();
3261
+ const constraints = this._allocateTrampoline();
3204
3262
 
3205
3263
  const { trampoline, quickCode, redirectSize } = this;
3206
3264
 
3207
3265
  const writeTrampoline = artQuickCodeReplacementTrampolineWriters[Process.arch];
3208
- const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, vm);
3266
+ const prologueLength = writeTrampoline(trampoline, quickCode, redirectSize, constraints, vm);
3209
3267
  this.overwrittenPrologueLength = prologueLength;
3210
3268
 
3211
3269
  this.overwrittenPrologue = Memory.dup(this.quickCodeAddress, prologueLength);
@@ -3273,7 +3331,7 @@ class ArtMethodMangler {
3273
3331
 
3274
3332
  patchArtMethod(replacementMethodId, {
3275
3333
  jniCode: impl,
3276
- accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative | kAccNterpEntryPointFastPathFlag)) | kAccNative) >>> 0,
3334
+ accessFlags: ((originalFlags & ~(kAccCriticalNative | kAccFastNative | kAccNterpEntryPointFastPathFlag)) | kAccNative | kAccCompileDontBother) >>> 0,
3277
3335
  quickCode: api.artClassLinker.quickGenericJniTrampoline,
3278
3336
  interpreterCode: api.artInterpreterToCompiledCodeBridge
3279
3337
  }, vm);
@@ -3286,7 +3344,7 @@ class ArtMethodMangler {
3286
3344
  }
3287
3345
 
3288
3346
  patchArtMethod(hookedMethodId, {
3289
- accessFlags: (originalFlags & ~(hookedMethodRemovedFlags)) >>> 0
3347
+ accessFlags: ((originalFlags & ~(hookedMethodRemovedFlags)) | kAccCompileDontBother) >>> 0
3290
3348
  }, vm);
3291
3349
 
3292
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.2",
3
+ "version": "6.2.1",
4
4
  "description": "Java runtime interop from Frida",
5
5
  "main": "index.js",
6
6
  "files": [