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.
- package/index.js +13 -0
- package/lib/android.js +78 -16
- 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
|
-
|
|
3068
|
-
writer.
|
|
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
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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;
|