frida-java-bridge 6.3.8 → 7.0.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.d.ts +779 -0
- package/index.js +11 -11
- package/lib/alloc.js +1 -3
- package/lib/android.js +47 -72
- package/lib/api.js +5 -3
- package/lib/class-factory.js +15 -17
- package/lib/class-model.js +9 -12
- package/lib/env.js +1 -3
- package/lib/jvm.js +22 -18
- package/lib/jvmti.js +4 -10
- package/lib/lru.js +1 -3
- package/lib/machine-code.js +1 -5
- package/lib/memoize.js +1 -3
- package/lib/mkdex.js +5 -4
- package/lib/result.js +2 -7
- package/lib/types.js +6 -14
- package/lib/vm.js +3 -7
- package/package.json +8 -10
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import getApi from './lib/api.js';
|
|
2
|
+
import {
|
|
3
3
|
getAndroidVersion,
|
|
4
4
|
withAllArtThreadsSuspended,
|
|
5
5
|
withRunnableArtThread,
|
|
@@ -9,13 +9,13 @@ const {
|
|
|
9
9
|
deoptimizeEverything,
|
|
10
10
|
deoptimizeBootImage,
|
|
11
11
|
deoptimizeMethod
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
} from './lib/android.js';
|
|
13
|
+
import ClassFactory from './lib/class-factory.js';
|
|
14
|
+
import ClassModel from './lib/class-model.js';
|
|
15
|
+
import Env from './lib/env.js';
|
|
16
|
+
import { initialize } from './lib/types.js';
|
|
17
|
+
import VM from './lib/vm.js';
|
|
18
|
+
import { checkJniResult } from './lib/result.js';
|
|
19
19
|
|
|
20
20
|
const jsizeSize = 4;
|
|
21
21
|
const pointerSize = Process.pointerSize;
|
|
@@ -78,7 +78,7 @@ class Runtime {
|
|
|
78
78
|
const vm = new VM(api);
|
|
79
79
|
this.vm = vm;
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
initialize(vm);
|
|
82
82
|
ClassFactory._initialize(vm, api);
|
|
83
83
|
this.classFactory = new ClassFactory();
|
|
84
84
|
|
|
@@ -594,4 +594,4 @@ function initFactoryFromLoadedApk (factory, apk) {
|
|
|
594
594
|
const runtime = new Runtime();
|
|
595
595
|
Script.bindWeak(runtime, () => { runtime._dispose(); });
|
|
596
596
|
|
|
597
|
-
|
|
597
|
+
export default runtime;
|
package/lib/alloc.js
CHANGED
package/lib/android.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import makeCodeAllocator from './alloc.js';
|
|
2
|
+
import {
|
|
3
3
|
jvmtiVersion,
|
|
4
4
|
jvmtiCapabilities,
|
|
5
5
|
EnvJvmti
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
} from './jvmti.js';
|
|
7
|
+
import { parseInstructionsAt } from './machine-code.js';
|
|
8
|
+
import memoize from './memoize.js';
|
|
9
|
+
import { checkJniResult, JNI_OK } from './result.js';
|
|
10
|
+
import VM from './vm.js';
|
|
11
11
|
|
|
12
12
|
const jsizeSize = 4;
|
|
13
13
|
const pointerSize = Process.pointerSize;
|
|
@@ -46,7 +46,7 @@ const ARM64_ADRP_MAX_DISTANCE = 0xfffff000;
|
|
|
46
46
|
const ENV_VTABLE_OFFSET_EXCEPTION_CLEAR = 17 * pointerSize;
|
|
47
47
|
const ENV_VTABLE_OFFSET_FATAL_ERROR = 18 * pointerSize;
|
|
48
48
|
|
|
49
|
-
const DVM_JNI_ENV_OFFSET_SELF = 12;
|
|
49
|
+
export const DVM_JNI_ENV_OFFSET_SELF = 12;
|
|
50
50
|
|
|
51
51
|
const DVM_CLASS_OBJECT_OFFSET_VTABLE_COUNT = 112;
|
|
52
52
|
const DVM_CLASS_OBJECT_OFFSET_VTABLE = 116;
|
|
@@ -81,13 +81,13 @@ const SOCK_STREAM = 1;
|
|
|
81
81
|
|
|
82
82
|
const getArtRuntimeSpec = memoize(_getArtRuntimeSpec);
|
|
83
83
|
const getArtInstrumentationSpec = memoize(_getArtInstrumentationSpec);
|
|
84
|
-
const getArtMethodSpec = memoize(_getArtMethodSpec);
|
|
85
|
-
const getArtThreadSpec = memoize(_getArtThreadSpec);
|
|
84
|
+
export const getArtMethodSpec = memoize(_getArtMethodSpec);
|
|
85
|
+
export const getArtThreadSpec = memoize(_getArtThreadSpec);
|
|
86
86
|
const getArtManagedStackSpec = memoize(_getArtManagedStackSpec);
|
|
87
87
|
const getArtThreadStateTransitionImpl = memoize(_getArtThreadStateTransitionImpl);
|
|
88
|
-
const getAndroidVersion = memoize(_getAndroidVersion);
|
|
88
|
+
export const getAndroidVersion = memoize(_getAndroidVersion);
|
|
89
89
|
const getAndroidCodename = memoize(_getAndroidCodename);
|
|
90
|
-
const getAndroidApiLevel = memoize(_getAndroidApiLevel);
|
|
90
|
+
export const getAndroidApiLevel = memoize(_getAndroidApiLevel);
|
|
91
91
|
const getArtQuickFrameInfoGetterThunk = memoize(_getArtQuickFrameInfoGetterThunk);
|
|
92
92
|
|
|
93
93
|
const makeCxxMethodWrapperReturningPointerByValue =
|
|
@@ -118,7 +118,7 @@ let socketpair = null;
|
|
|
118
118
|
|
|
119
119
|
let trampolineAllocator = null;
|
|
120
120
|
|
|
121
|
-
function getApi () {
|
|
121
|
+
export function getApi () {
|
|
122
122
|
if (cachedApi === null) {
|
|
123
123
|
cachedApi = _getApi();
|
|
124
124
|
}
|
|
@@ -570,7 +570,7 @@ function tryGetEnvJvmti (vm, runtime) {
|
|
|
570
570
|
return env;
|
|
571
571
|
}
|
|
572
572
|
|
|
573
|
-
function ensureClassInitialized (env, classRef) {
|
|
573
|
+
export function ensureClassInitialized (env, classRef) {
|
|
574
574
|
const api = getApi();
|
|
575
575
|
if (api.flavor !== 'art') {
|
|
576
576
|
return;
|
|
@@ -957,7 +957,7 @@ function tryGetArtClassLinkerSpec (runtime, runtimeSpec) {
|
|
|
957
957
|
return spec;
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
-
function getArtClassSpec (vm) {
|
|
960
|
+
export function getArtClassSpec (vm) {
|
|
961
961
|
let apiLevel;
|
|
962
962
|
try {
|
|
963
963
|
apiLevel = getAndroidApiLevel();
|
|
@@ -1056,7 +1056,7 @@ function _getArtMethodSpec (vm) {
|
|
|
1056
1056
|
return spec;
|
|
1057
1057
|
}
|
|
1058
1058
|
|
|
1059
|
-
function getArtFieldSpec (vm) {
|
|
1059
|
+
export function getArtFieldSpec (vm) {
|
|
1060
1060
|
const apiLevel = getAndroidApiLevel();
|
|
1061
1061
|
|
|
1062
1062
|
if (apiLevel >= 23) {
|
|
@@ -1250,7 +1250,7 @@ function parseArtQuickTrampolineArm64 (insn) {
|
|
|
1250
1250
|
return null;
|
|
1251
1251
|
}
|
|
1252
1252
|
|
|
1253
|
-
function getArtThreadFromEnv (env) {
|
|
1253
|
+
export function getArtThreadFromEnv (env) {
|
|
1254
1254
|
return env.handle.add(pointerSize).readPointer();
|
|
1255
1255
|
}
|
|
1256
1256
|
|
|
@@ -1278,7 +1278,7 @@ function getAndroidSystemProperty (name) {
|
|
|
1278
1278
|
return buf.readUtf8String();
|
|
1279
1279
|
}
|
|
1280
1280
|
|
|
1281
|
-
function withRunnableArtThread (vm, env, fn) {
|
|
1281
|
+
export function withRunnableArtThread (vm, env, fn) {
|
|
1282
1282
|
const perform = getArtThreadStateTransitionImpl(vm, env);
|
|
1283
1283
|
|
|
1284
1284
|
const id = getArtThreadFromEnv(env).toString();
|
|
@@ -1305,7 +1305,7 @@ function onThreadStateTransitionComplete (thread) {
|
|
|
1305
1305
|
fn(thread);
|
|
1306
1306
|
}
|
|
1307
1307
|
|
|
1308
|
-
function withAllArtThreadsSuspended (fn) {
|
|
1308
|
+
export function withAllArtThreadsSuspended (fn) {
|
|
1309
1309
|
const api = getApi();
|
|
1310
1310
|
|
|
1311
1311
|
const threadList = api.artThreadList;
|
|
@@ -1335,7 +1335,7 @@ class ArtClassVisitor {
|
|
|
1335
1335
|
}
|
|
1336
1336
|
}
|
|
1337
1337
|
|
|
1338
|
-
function makeArtClassVisitor (visit) {
|
|
1338
|
+
export function makeArtClassVisitor (visit) {
|
|
1339
1339
|
const api = getApi();
|
|
1340
1340
|
|
|
1341
1341
|
if (api['art::ClassLinker::VisitClasses'] instanceof NativeFunction) {
|
|
@@ -1364,7 +1364,7 @@ class ArtClassLoaderVisitor {
|
|
|
1364
1364
|
}
|
|
1365
1365
|
}
|
|
1366
1366
|
|
|
1367
|
-
function makeArtClassLoaderVisitor (visit) {
|
|
1367
|
+
export function makeArtClassLoaderVisitor (visit) {
|
|
1368
1368
|
return new ArtClassLoaderVisitor(visit);
|
|
1369
1369
|
}
|
|
1370
1370
|
|
|
@@ -1373,7 +1373,7 @@ const WalkKind = {
|
|
|
1373
1373
|
'skip-inlined-frames': 1
|
|
1374
1374
|
};
|
|
1375
1375
|
|
|
1376
|
-
class ArtStackVisitor {
|
|
1376
|
+
export class ArtStackVisitor {
|
|
1377
1377
|
constructor (thread, context, walkKind, numFrames = 0, checkSuspended = true) {
|
|
1378
1378
|
const api = getApi();
|
|
1379
1379
|
|
|
@@ -1452,7 +1452,7 @@ class ArtStackVisitor {
|
|
|
1452
1452
|
}
|
|
1453
1453
|
}
|
|
1454
1454
|
|
|
1455
|
-
class ArtMethod {
|
|
1455
|
+
export class ArtMethod {
|
|
1456
1456
|
constructor (handle) {
|
|
1457
1457
|
this.handle = handle;
|
|
1458
1458
|
}
|
|
@@ -1535,17 +1535,17 @@ function _getArtQuickFrameInfoGetterThunk (impl) {
|
|
|
1535
1535
|
}
|
|
1536
1536
|
|
|
1537
1537
|
const thunkRelocators = {
|
|
1538
|
-
ia32:
|
|
1539
|
-
x64:
|
|
1540
|
-
arm:
|
|
1541
|
-
arm64:
|
|
1538
|
+
ia32: globalThis.X86Relocator,
|
|
1539
|
+
x64: globalThis.X86Relocator,
|
|
1540
|
+
arm: globalThis.ThumbRelocator,
|
|
1541
|
+
arm64: globalThis.Arm64Relocator
|
|
1542
1542
|
};
|
|
1543
1543
|
|
|
1544
1544
|
const thunkWriters = {
|
|
1545
|
-
ia32:
|
|
1546
|
-
x64:
|
|
1547
|
-
arm:
|
|
1548
|
-
arm64:
|
|
1545
|
+
ia32: globalThis.X86Writer,
|
|
1546
|
+
x64: globalThis.X86Writer,
|
|
1547
|
+
arm: globalThis.ThumbWriter,
|
|
1548
|
+
arm64: globalThis.Arm64Writer
|
|
1549
1549
|
};
|
|
1550
1550
|
|
|
1551
1551
|
function makeThunk (size, write) {
|
|
@@ -2313,15 +2313,15 @@ function instrumentGetOatQuickMethodHeaderInlinedCopyArm64 ({ address, size, val
|
|
|
2313
2313
|
});
|
|
2314
2314
|
}
|
|
2315
2315
|
|
|
2316
|
-
function makeMethodMangler (methodId) {
|
|
2316
|
+
export function makeMethodMangler (methodId) {
|
|
2317
2317
|
return new MethodMangler(methodId);
|
|
2318
2318
|
}
|
|
2319
2319
|
|
|
2320
|
-
function translateMethod (methodId) {
|
|
2320
|
+
export function translateMethod (methodId) {
|
|
2321
2321
|
return artController.replacedMethods.translate(methodId);
|
|
2322
2322
|
}
|
|
2323
2323
|
|
|
2324
|
-
function backtrace (vm, options = {}) {
|
|
2324
|
+
export function backtrace (vm, options = {}) {
|
|
2325
2325
|
const { limit = 16 } = options;
|
|
2326
2326
|
|
|
2327
2327
|
const env = vm.getEnv();
|
|
@@ -2842,7 +2842,7 @@ class Backtrace {
|
|
|
2842
2842
|
}
|
|
2843
2843
|
}
|
|
2844
2844
|
|
|
2845
|
-
function revertGlobalPatches () {
|
|
2845
|
+
export function revertGlobalPatches () {
|
|
2846
2846
|
patchedClasses.forEach(entry => {
|
|
2847
2847
|
entry.vtablePtr.writePointer(entry.vtable);
|
|
2848
2848
|
entry.vtableCountPtr.writeS32(entry.vtableCount);
|
|
@@ -3660,15 +3660,15 @@ function cloneArtMethod (method, vm) {
|
|
|
3660
3660
|
return Memory.dup(method, getArtMethodSpec(vm).size);
|
|
3661
3661
|
}
|
|
3662
3662
|
|
|
3663
|
-
function deoptimizeMethod (vm, env, method) {
|
|
3663
|
+
export function deoptimizeMethod (vm, env, method) {
|
|
3664
3664
|
requestDeoptimization(vm, env, kSelectiveDeoptimization, method);
|
|
3665
3665
|
}
|
|
3666
3666
|
|
|
3667
|
-
function deoptimizeEverything (vm, env) {
|
|
3667
|
+
export function deoptimizeEverything (vm, env) {
|
|
3668
3668
|
requestDeoptimization(vm, env, kFullDeoptimization);
|
|
3669
3669
|
}
|
|
3670
3670
|
|
|
3671
|
-
function deoptimizeBootImage (vm, env) {
|
|
3671
|
+
export function deoptimizeBootImage (vm, env) {
|
|
3672
3672
|
const api = getApi();
|
|
3673
3673
|
|
|
3674
3674
|
if (getAndroidApiLevel() < 26) {
|
|
@@ -3791,8 +3791,7 @@ class JdwpSession {
|
|
|
3791
3791
|
try {
|
|
3792
3792
|
await output.writeAll(handshakePacket);
|
|
3793
3793
|
await input.readAll(handshakePacket.length);
|
|
3794
|
-
} catch (e) {
|
|
3795
|
-
}
|
|
3794
|
+
} catch (e) { /* empty */ }
|
|
3796
3795
|
}
|
|
3797
3796
|
}
|
|
3798
3797
|
|
|
@@ -4256,6 +4255,7 @@ function recompileExceptionClearForArm (buffer, pc, exceptionClearImpl, nextFunc
|
|
|
4256
4255
|
case 'beq.w':
|
|
4257
4256
|
case 'beq':
|
|
4258
4257
|
case 'bne':
|
|
4258
|
+
case 'bne.w':
|
|
4259
4259
|
case 'bgt':
|
|
4260
4260
|
branchTarget = ptr(insn.operands[0].value);
|
|
4261
4261
|
break;
|
|
@@ -4351,6 +4351,10 @@ function recompileExceptionClearForArm (buffer, pc, exceptionClearImpl, nextFunc
|
|
|
4351
4351
|
writer.putBCondLabelWide('eq', branchLabelFromOperand(insn.operands[0]));
|
|
4352
4352
|
keep = false;
|
|
4353
4353
|
break;
|
|
4354
|
+
case 'bne.w':
|
|
4355
|
+
writer.putBCondLabelWide('ne', branchLabelFromOperand(insn.operands[0]));
|
|
4356
|
+
keep = false;
|
|
4357
|
+
break;
|
|
4354
4358
|
case 'beq':
|
|
4355
4359
|
case 'bne':
|
|
4356
4360
|
case 'bgt':
|
|
@@ -4859,7 +4863,7 @@ class StdVector {
|
|
|
4859
4863
|
}
|
|
4860
4864
|
}
|
|
4861
4865
|
|
|
4862
|
-
class HandleVector extends StdVector {
|
|
4866
|
+
export class HandleVector extends StdVector {
|
|
4863
4867
|
static $new () {
|
|
4864
4868
|
const vector = new HandleVector(getApi().$new(STD_VECTOR_SIZE));
|
|
4865
4869
|
vector.init();
|
|
@@ -4932,7 +4936,7 @@ const VSHS_OFFSET_SELF = alignPointerOffset(BHS_SIZE);
|
|
|
4932
4936
|
const VSHS_OFFSET_CURRENT_SCOPE = VSHS_OFFSET_SELF + pointerSize;
|
|
4933
4937
|
const VSHS_SIZE = VSHS_OFFSET_CURRENT_SCOPE + pointerSize;
|
|
4934
4938
|
|
|
4935
|
-
class VariableSizedHandleScope extends BaseHandleScope {
|
|
4939
|
+
export class VariableSizedHandleScope extends BaseHandleScope {
|
|
4936
4940
|
static $new (thread, vm) {
|
|
4937
4941
|
const scope = new VariableSizedHandleScope(getApi().$new(VSHS_SIZE));
|
|
4938
4942
|
scope.init(thread, vm);
|
|
@@ -5124,7 +5128,7 @@ const objectVisitorPredicateFactories = {
|
|
|
5124
5128
|
}
|
|
5125
5129
|
};
|
|
5126
5130
|
|
|
5127
|
-
function makeObjectVisitorPredicate (needle, onMatch) {
|
|
5131
|
+
export function makeObjectVisitorPredicate (needle, onMatch) {
|
|
5128
5132
|
const factory = objectVisitorPredicateFactories[Process.arch] || makeGenericObjectVisitorPredicate;
|
|
5129
5133
|
return factory(needle, onMatch);
|
|
5130
5134
|
}
|
|
@@ -5145,32 +5149,3 @@ function alignPointerOffset (offset) {
|
|
|
5145
5149
|
}
|
|
5146
5150
|
return offset;
|
|
5147
5151
|
}
|
|
5148
|
-
|
|
5149
|
-
module.exports = {
|
|
5150
|
-
getApi,
|
|
5151
|
-
ensureClassInitialized,
|
|
5152
|
-
getAndroidVersion,
|
|
5153
|
-
getAndroidApiLevel,
|
|
5154
|
-
getArtClassSpec,
|
|
5155
|
-
getArtMethodSpec,
|
|
5156
|
-
getArtFieldSpec,
|
|
5157
|
-
getArtThreadSpec,
|
|
5158
|
-
getArtThreadFromEnv,
|
|
5159
|
-
withRunnableArtThread,
|
|
5160
|
-
withAllArtThreadsSuspended,
|
|
5161
|
-
makeArtClassVisitor,
|
|
5162
|
-
makeArtClassLoaderVisitor,
|
|
5163
|
-
ArtStackVisitor,
|
|
5164
|
-
ArtMethod,
|
|
5165
|
-
makeMethodMangler,
|
|
5166
|
-
translateMethod,
|
|
5167
|
-
backtrace,
|
|
5168
|
-
revertGlobalPatches,
|
|
5169
|
-
deoptimizeEverything,
|
|
5170
|
-
deoptimizeBootImage,
|
|
5171
|
-
deoptimizeMethod,
|
|
5172
|
-
HandleVector,
|
|
5173
|
-
VariableSizedHandleScope,
|
|
5174
|
-
makeObjectVisitorPredicate,
|
|
5175
|
-
DVM_JNI_ENV_OFFSET_SELF
|
|
5176
|
-
};
|
package/lib/api.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { getApi as androidGetApi, getAndroidVersion } from './android.js';
|
|
2
|
+
import { getApi as jvmGetApi } from './jvm.js';
|
|
3
|
+
let getApi = androidGetApi;
|
|
2
4
|
try {
|
|
3
5
|
getAndroidVersion();
|
|
4
6
|
} catch (e) {
|
|
5
|
-
getApi =
|
|
7
|
+
getApi = jvmGetApi;
|
|
6
8
|
}
|
|
7
|
-
|
|
9
|
+
export default getApi;
|
package/lib/class-factory.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import Env from './env.js';
|
|
2
|
+
import * as android from './android.js';
|
|
3
|
+
import { ensureClassInitialized as jvmEnsureClassInitialized, makeMethodMangler as jvmMakeMethodMangler } from './jvm.js';
|
|
4
|
+
import ClassModel from './class-model.js';
|
|
5
|
+
import LRU from './lru.js';
|
|
6
|
+
import mkdex from './mkdex.js';
|
|
7
|
+
import {
|
|
8
|
+
getType,
|
|
9
|
+
getPrimitiveType,
|
|
10
|
+
getArrayType,
|
|
11
|
+
makeJniObjectTypeName
|
|
12
|
+
} from './types.js';
|
|
4
13
|
const jsizeSize = 4;
|
|
5
14
|
let {
|
|
6
15
|
ensureClassInitialized,
|
|
7
16
|
makeMethodMangler
|
|
8
17
|
} = android;
|
|
9
|
-
const ClassModel = require('./class-model');
|
|
10
|
-
const LRU = require('./lru');
|
|
11
|
-
const mkdex = require('./mkdex');
|
|
12
|
-
const {
|
|
13
|
-
getType,
|
|
14
|
-
getPrimitiveType,
|
|
15
|
-
getArrayType,
|
|
16
|
-
makeJniObjectTypeName
|
|
17
|
-
} = require('./types');
|
|
18
18
|
|
|
19
19
|
const kAccStatic = 0x0008;
|
|
20
20
|
|
|
@@ -58,14 +58,14 @@ let cachedLoaderMethod = null;
|
|
|
58
58
|
|
|
59
59
|
const ignoredThreads = new Map();
|
|
60
60
|
|
|
61
|
-
class ClassFactory {
|
|
61
|
+
export default class ClassFactory {
|
|
62
62
|
static _initialize (_vm, _api) {
|
|
63
63
|
vm = _vm;
|
|
64
64
|
api = _api;
|
|
65
65
|
isArtVm = _api.flavor === 'art';
|
|
66
66
|
if (_api.flavor === 'jvm') {
|
|
67
|
-
ensureClassInitialized =
|
|
68
|
-
makeMethodMangler =
|
|
67
|
+
ensureClassInitialized = jvmEnsureClassInitialized;
|
|
68
|
+
makeMethodMangler = jvmMakeMethodMangler;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -2357,5 +2357,3 @@ function makeSourceFileName (className) {
|
|
|
2357
2357
|
const tokens = className.split('.');
|
|
2358
2358
|
return tokens[tokens.length - 1] + '.java';
|
|
2359
2359
|
}
|
|
2360
|
-
|
|
2361
|
-
module.exports = ClassFactory;
|
package/lib/class-model.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { withRunnableArtThread, getArtClassSpec, getArtMethodSpec, getArtFieldSpec, getApi } from './android.js';
|
|
2
|
+
|
|
1
3
|
const code = `#include <json-glib/json-glib.h>
|
|
2
4
|
#include <string.h>
|
|
3
5
|
|
|
@@ -1161,14 +1163,12 @@ std_string_c_str (StdString * self)
|
|
|
1161
1163
|
}
|
|
1162
1164
|
`;
|
|
1163
1165
|
|
|
1164
|
-
const android = require('./android');
|
|
1165
|
-
|
|
1166
1166
|
const methodQueryPattern = /(.+)!([^/]+)\/?([isu]+)?/;
|
|
1167
1167
|
|
|
1168
1168
|
let cm = null;
|
|
1169
1169
|
let unwrap = null;
|
|
1170
1170
|
|
|
1171
|
-
class Model {
|
|
1171
|
+
export default class Model {
|
|
1172
1172
|
static build (handle, env) {
|
|
1173
1173
|
ensureInitialized(env);
|
|
1174
1174
|
|
|
@@ -1215,7 +1215,7 @@ class Model {
|
|
|
1215
1215
|
cm.dealloc(json);
|
|
1216
1216
|
}
|
|
1217
1217
|
} else {
|
|
1218
|
-
|
|
1218
|
+
withRunnableArtThread(env.vm, env, thread => {
|
|
1219
1219
|
const json = cm.enumerateMethodsArt(classQuery, methodQuery,
|
|
1220
1220
|
boolToNative(includeSignature), boolToNative(ignoreCase), boolToNative(skipSystemClasses));
|
|
1221
1221
|
try {
|
|
@@ -1296,11 +1296,11 @@ function compileModule (env) {
|
|
|
1296
1296
|
|
|
1297
1297
|
const artApi = javaApi.add(javaApiSize);
|
|
1298
1298
|
const { vm } = env;
|
|
1299
|
-
const artClass =
|
|
1299
|
+
const artClass = getArtClassSpec(vm);
|
|
1300
1300
|
if (artClass !== null) {
|
|
1301
1301
|
const c = artClass.offset;
|
|
1302
|
-
const m =
|
|
1303
|
-
const f =
|
|
1302
|
+
const m = getArtMethodSpec(vm);
|
|
1303
|
+
const f = getArtFieldSpec(vm);
|
|
1304
1304
|
|
|
1305
1305
|
let s = artApi;
|
|
1306
1306
|
[
|
|
@@ -1314,7 +1314,7 @@ function compileModule (env) {
|
|
|
1314
1314
|
s = s.writeUInt(value).add(4);
|
|
1315
1315
|
});
|
|
1316
1316
|
|
|
1317
|
-
const api =
|
|
1317
|
+
const api = getApi();
|
|
1318
1318
|
[
|
|
1319
1319
|
api.artClassLinker.address,
|
|
1320
1320
|
api['art::ClassLinker::VisitClasses'],
|
|
@@ -1360,8 +1360,7 @@ function makeHandleUnwrapper (cm, vm) {
|
|
|
1360
1360
|
return nullUnwrap;
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
1363
|
-
const
|
|
1364
|
-
const decodeGlobal = android.getApi()['art::JavaVMExt::DecodeGlobal'];
|
|
1363
|
+
const decodeGlobal = getApi()['art::JavaVMExt::DecodeGlobal'];
|
|
1365
1364
|
|
|
1366
1365
|
return function (handle, env, fn) {
|
|
1367
1366
|
let result;
|
|
@@ -1382,5 +1381,3 @@ function nullUnwrap (handle, env, fn) {
|
|
|
1382
1381
|
function boolToNative (val) {
|
|
1383
1382
|
return val ? 1 : 0;
|
|
1384
1383
|
}
|
|
1385
|
-
|
|
1386
|
-
module.exports = Model;
|
package/lib/env.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function Env (handle, vm) {
|
|
1
|
+
export default function Env (handle, vm) {
|
|
2
2
|
this.handle = handle;
|
|
3
3
|
this.vm = vm;
|
|
4
4
|
}
|
|
@@ -947,5 +947,3 @@ Env.prototype.stringFromJni = function (str) {
|
|
|
947
947
|
this.releaseStringChars(str, utf);
|
|
948
948
|
}
|
|
949
949
|
};
|
|
950
|
-
|
|
951
|
-
module.exports = Env;
|
package/lib/jvm.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import {
|
|
2
2
|
jvmtiVersion,
|
|
3
3
|
jvmtiCapabilities,
|
|
4
4
|
EnvJvmti
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
} from './jvmti.js';
|
|
6
|
+
import { parseInstructionsAt } from './machine-code.js';
|
|
7
|
+
import memoize from './memoize.js';
|
|
8
|
+
import { checkJniResult } from './result.js';
|
|
9
|
+
import VM from './vm.js';
|
|
10
10
|
|
|
11
11
|
const jsizeSize = 4;
|
|
12
12
|
const { pointerSize } = Process;
|
|
@@ -31,7 +31,7 @@ let manglersScheduled = false;
|
|
|
31
31
|
const replaceManglers = new Map();
|
|
32
32
|
const revertManglers = new Map();
|
|
33
33
|
|
|
34
|
-
function getApi () {
|
|
34
|
+
export function getApi () {
|
|
35
35
|
if (cachedApi === null) {
|
|
36
36
|
cachedApi = _getApi();
|
|
37
37
|
}
|
|
@@ -105,6 +105,7 @@ function _getApi () {
|
|
|
105
105
|
_ZN6Method24restore_unshareable_infoEP10JavaThread: ['Method::restore_unshareable_info', 'void', ['pointer', 'pointer']],
|
|
106
106
|
// JDK < 17
|
|
107
107
|
_ZN6Method24restore_unshareable_infoEP6Thread: ['Method::restore_unshareable_info', 'void', ['pointer', 'pointer']],
|
|
108
|
+
_ZN6Method11link_methodERK12methodHandleP10JavaThread: ['Method::link_method', 'void', ['pointer', 'pointer', 'pointer']],
|
|
108
109
|
_ZN6Method10jmethod_idEv: ['Method::jmethod_id', 'pointer', ['pointer']],
|
|
109
110
|
_ZN6Method10clear_codeEv: function (address) {
|
|
110
111
|
const clearCode = new NativeFunction(address, 'void', ['pointer'], nativeFunctionOptions);
|
|
@@ -236,6 +237,7 @@ function _getApi () {
|
|
|
236
237
|
optionals: [
|
|
237
238
|
'_ZN6Method24restore_unshareable_infoEP10JavaThread',
|
|
238
239
|
'_ZN6Method24restore_unshareable_infoEP6Thread',
|
|
240
|
+
'_ZN6Method11link_methodERK12methodHandleP10JavaThread',
|
|
239
241
|
'_ZN6Method10clear_codeEv',
|
|
240
242
|
'_ZN6Method10clear_codeEb',
|
|
241
243
|
|
|
@@ -398,7 +400,7 @@ function makeThreadFromJniHelper (api) {
|
|
|
398
400
|
if (tryParse !== undefined) {
|
|
399
401
|
const vm = new VM(api);
|
|
400
402
|
const findClassImpl = vm.perform(env => env.handle.readPointer().add(6 * pointerSize).readPointer());
|
|
401
|
-
offset = parseInstructionsAt(findClassImpl, tryParse, { limit:
|
|
403
|
+
offset = parseInstructionsAt(findClassImpl, tryParse, { limit: 11 });
|
|
402
404
|
}
|
|
403
405
|
|
|
404
406
|
if (offset === null) {
|
|
@@ -425,7 +427,7 @@ function parseX64ThreadOffset (insn) {
|
|
|
425
427
|
return disp;
|
|
426
428
|
}
|
|
427
429
|
|
|
428
|
-
function ensureClassInitialized (env, classRef) {
|
|
430
|
+
export function ensureClassInitialized (env, classRef) {
|
|
429
431
|
}
|
|
430
432
|
|
|
431
433
|
class JvmMethodMangler {
|
|
@@ -663,7 +665,7 @@ function _getJvmThreadSpec () {
|
|
|
663
665
|
};
|
|
664
666
|
}
|
|
665
667
|
|
|
666
|
-
function makeMethodMangler (methodId) {
|
|
668
|
+
export function makeMethodMangler (methodId) {
|
|
667
669
|
return new JvmMethodMangler(methodId);
|
|
668
670
|
}
|
|
669
671
|
|
|
@@ -758,6 +760,15 @@ function nativeJvmMethod (method, impl, thread) {
|
|
|
758
760
|
|
|
759
761
|
api['Method::restore_unshareable_info'](newMethod.method, thread);
|
|
760
762
|
|
|
763
|
+
if (api.version >= 17) {
|
|
764
|
+
// Only certain JDK versions of restore_unshareable_info() call
|
|
765
|
+
// link_method(). Manually call if necessary.
|
|
766
|
+
const methodHandle = Memory.alloc(2 * pointerSize);
|
|
767
|
+
methodHandle.writePointer(newMethod.method);
|
|
768
|
+
methodHandle.add(pointerSize).writePointer(thread);
|
|
769
|
+
api['Method::link_method'](newMethod.method, methodHandle, thread);
|
|
770
|
+
}
|
|
771
|
+
|
|
761
772
|
return newMethod;
|
|
762
773
|
}
|
|
763
774
|
|
|
@@ -974,12 +985,5 @@ function parseX64VTableOffset (insn) {
|
|
|
974
985
|
return defaultVtableIndicesOffset + 16;
|
|
975
986
|
}
|
|
976
987
|
|
|
977
|
-
function deoptimizeEverything (vm, env) {
|
|
988
|
+
export function deoptimizeEverything (vm, env) {
|
|
978
989
|
}
|
|
979
|
-
|
|
980
|
-
module.exports = {
|
|
981
|
-
getApi,
|
|
982
|
-
ensureClassInitialized,
|
|
983
|
-
makeMethodMangler,
|
|
984
|
-
deoptimizeEverything
|
|
985
|
-
};
|
package/lib/jvmti.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { checkJniResult } from './result.js';
|
|
2
2
|
|
|
3
|
-
const jvmtiVersion = {
|
|
3
|
+
export const jvmtiVersion = {
|
|
4
4
|
v1_0: 0x30010000,
|
|
5
5
|
v1_2: 0x30010200
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
const jvmtiCapabilities = {
|
|
8
|
+
export const jvmtiCapabilities = {
|
|
9
9
|
canTagObjects: 1
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@ const nativeFunctionOptions = {
|
|
|
14
14
|
exceptions: 'propagate'
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
function EnvJvmti (handle, vm) {
|
|
17
|
+
export function EnvJvmti (handle, vm) {
|
|
18
18
|
this.handle = handle;
|
|
19
19
|
this.vm = vm;
|
|
20
20
|
this.vtable = handle.readPointer();
|
|
@@ -54,9 +54,3 @@ function proxy (offset, retType, argTypes, wrapper) {
|
|
|
54
54
|
return wrapper.apply(this, args);
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
module.exports = {
|
|
59
|
-
jvmtiVersion,
|
|
60
|
-
jvmtiCapabilities,
|
|
61
|
-
EnvJvmti
|
|
62
|
-
};
|
package/lib/lru.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Based on https://stackoverflow.com/a/46432113
|
|
2
2
|
|
|
3
|
-
class LRU {
|
|
3
|
+
export default class LRU {
|
|
4
4
|
constructor (capacity, destroy) {
|
|
5
5
|
this.items = new Map();
|
|
6
6
|
this.capacity = capacity;
|
|
@@ -42,5 +42,3 @@ class LRU {
|
|
|
42
42
|
items.set(key, val);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
module.exports = LRU;
|
package/lib/machine-code.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function parseInstructionsAt (address, tryParse, { limit }) {
|
|
1
|
+
export function parseInstructionsAt (address, tryParse, { limit }) {
|
|
2
2
|
let cursor = address;
|
|
3
3
|
let prevInsn = null;
|
|
4
4
|
|
|
@@ -16,7 +16,3 @@ function parseInstructionsAt (address, tryParse, { limit }) {
|
|
|
16
16
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
module.exports = {
|
|
21
|
-
parseInstructionsAt
|
|
22
|
-
};
|