frida 16.7.14 → 16.7.15
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/README.md +1 -10
- package/build/BSDmakefile +6 -0
- package/build/Makefile +10 -0
- package/build/src/frida.d.ts +364 -0
- package/build/src/frida.js +962 -0
- package/build/src/frida_binding.d.ts +938 -0
- package/meson.build +34 -67
- package/package.json +30 -20
- package/scripts/fetch-abi-bits.py +15 -65
- package/scripts/install.js +5 -4
- package/src/addon.def +3 -0
- package/src/addon.symbols +2 -1
- package/src/addon.version +4 -0
- package/src/frida_bindgen/__init__.py +0 -0
- package/src/frida_bindgen/__main__.py +4 -0
- package/src/frida_bindgen/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/__main__.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/cli.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/codegen.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/customization.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/loader.cpython-312.pyc +0 -0
- package/src/frida_bindgen/__pycache__/model.cpython-312.pyc +0 -0
- package/src/frida_bindgen/assets/codegen_helpers.c +1970 -0
- package/src/frida_bindgen/assets/codegen_helpers.ts +100 -0
- package/src/frida_bindgen/assets/codegen_prototypes.h +78 -0
- package/src/frida_bindgen/assets/codegen_types.h +57 -0
- package/src/frida_bindgen/assets/customization_facade.exports +13 -0
- package/src/frida_bindgen/assets/customization_facade.ts +157 -0
- package/src/frida_bindgen/assets/customization_helpers.imports +2 -0
- package/src/frida_bindgen/assets/customization_helpers.ts +396 -0
- package/src/frida_bindgen/cli.py +96 -0
- package/src/frida_bindgen/codegen.py +2233 -0
- package/src/frida_bindgen/customization.py +924 -0
- package/src/frida_bindgen/loader.py +60 -0
- package/src/frida_bindgen/model.py +1357 -0
- package/src/meson.build +92 -27
- package/{lib/build.py → src/tsc.py} +12 -12
- package/src/win_delay_load_hook.c +56 -0
- package/subprojects/frida-core.wrap +1 -1
- package/test/data/index.ts +2 -2
- package/test/device.ts +1 -2
- package/test/device_manager.ts +1 -2
- package/test/labrat.ts +2 -2
- package/test/script.ts +12 -12
- package/test/session.ts +3 -3
- package/tsconfig.json +6 -11
- package/dist/application.d.ts +0 -81
- package/dist/application.js +0 -2
- package/dist/authentication.d.ts +0 -3
- package/dist/authentication.js +0 -2
- package/dist/bus.d.ts +0 -16
- package/dist/bus.js +0 -23
- package/dist/cancellable.d.ts +0 -15
- package/dist/cancellable.js +0 -41
- package/dist/child.d.ts +0 -16
- package/dist/child.js +0 -9
- package/dist/crash.d.ts +0 -10
- package/dist/crash.js +0 -2
- package/dist/device.d.ts +0 -156
- package/dist/device.js +0 -188
- package/dist/device_manager.d.ts +0 -25
- package/dist/device_manager.js +0 -42
- package/dist/endpoint_parameters.d.ts +0 -26
- package/dist/endpoint_parameters.js +0 -24
- package/dist/icon.d.ts +0 -14
- package/dist/icon.js +0 -2
- package/dist/index.d.ts +0 -161
- package/dist/index.js +0 -170
- package/dist/iostream.d.ts +0 -13
- package/dist/iostream.js +0 -73
- package/dist/native.d.ts +0 -1
- package/dist/native.js +0 -11
- package/dist/portal_membership.d.ts +0 -6
- package/dist/portal_membership.js +0 -12
- package/dist/portal_service.d.ts +0 -48
- package/dist/portal_service.js +0 -52
- package/dist/process.d.ts +0 -47
- package/dist/process.js +0 -2
- package/dist/relay.d.ts +0 -22
- package/dist/relay.js +0 -32
- package/dist/script.d.ts +0 -70
- package/dist/script.js +0 -266
- package/dist/service.d.ts +0 -16
- package/dist/service.js +0 -26
- package/dist/session.d.ts +0 -45
- package/dist/session.js +0 -73
- package/dist/signals.d.ts +0 -20
- package/dist/signals.js +0 -40
- package/dist/socket_address.d.ts +0 -25
- package/dist/socket_address.js +0 -2
- package/dist/spawn.d.ts +0 -4
- package/dist/spawn.js +0 -2
- package/dist/system_parameters.d.ts +0 -84
- package/dist/system_parameters.js +0 -2
- package/lib/application.ts +0 -98
- package/lib/authentication.ts +0 -3
- package/lib/bus.ts +0 -30
- package/lib/cancellable.ts +0 -48
- package/lib/child.ts +0 -15
- package/lib/crash.ts +0 -11
- package/lib/device.ts +0 -331
- package/lib/device_manager.ts +0 -69
- package/lib/endpoint_parameters.ts +0 -56
- package/lib/icon.ts +0 -15
- package/lib/index.ts +0 -316
- package/lib/iostream.ts +0 -78
- package/lib/meson.build +0 -53
- package/lib/native.ts +0 -9
- package/lib/portal_membership.ts +0 -10
- package/lib/portal_service.ts +0 -105
- package/lib/process.ts +0 -57
- package/lib/relay.ts +0 -44
- package/lib/script.ts +0 -361
- package/lib/service.ts +0 -34
- package/lib/session.ts +0 -113
- package/lib/signals.ts +0 -45
- package/lib/socket_address.ts +0 -35
- package/lib/spawn.ts +0 -4
- package/lib/system_parameters.ts +0 -103
- package/meson.options +0 -11
- package/src/addon.cc +0 -78
- package/src/application.cc +0 -148
- package/src/application.h +0 -31
- package/src/authentication.cc +0 -174
- package/src/authentication.h +0 -24
- package/src/bus.cc +0 -167
- package/src/bus.h +0 -33
- package/src/cancellable.cc +0 -117
- package/src/cancellable.h +0 -31
- package/src/child.cc +0 -150
- package/src/child.h +0 -32
- package/src/crash.cc +0 -122
- package/src/crash.h +0 -30
- package/src/device.cc +0 -1350
- package/src/device.h +0 -56
- package/src/device_manager.cc +0 -362
- package/src/device_manager.h +0 -35
- package/src/endpoint_parameters.cc +0 -171
- package/src/endpoint_parameters.h +0 -28
- package/src/glib_context.cc +0 -62
- package/src/glib_context.h +0 -29
- package/src/glib_object.cc +0 -25
- package/src/glib_object.h +0 -37
- package/src/iostream.cc +0 -243
- package/src/iostream.h +0 -30
- package/src/operation.h +0 -94
- package/src/portal_membership.cc +0 -100
- package/src/portal_membership.h +0 -26
- package/src/portal_service.cc +0 -401
- package/src/portal_service.h +0 -40
- package/src/process.cc +0 -135
- package/src/process.h +0 -30
- package/src/relay.cc +0 -139
- package/src/relay.h +0 -31
- package/src/runtime.cc +0 -568
- package/src/runtime.h +0 -69
- package/src/script.cc +0 -301
- package/src/script.h +0 -36
- package/src/service.cc +0 -224
- package/src/service.h +0 -36
- package/src/session.cc +0 -860
- package/src/session.h +0 -42
- package/src/signals.cc +0 -334
- package/src/signals.h +0 -47
- package/src/spawn.cc +0 -95
- package/src/spawn.h +0 -27
- package/src/usage_monitor.h +0 -117
- package/src/uv_context.cc +0 -118
- package/src/uv_context.h +0 -40
- package/src/win_delay_load_hook.cc +0 -63
- package/subprojects/nan.wrap +0 -9
- package/subprojects/packagefiles/nan.patch +0 -13
|
@@ -0,0 +1,962 @@
|
|
|
1
|
+
import bindings from "bindings";
|
|
2
|
+
import util from "util";
|
|
3
|
+
import { Minimatch } from "minimatch";
|
|
4
|
+
import { Duplex } from "stream";
|
|
5
|
+
const { inspect } = util;
|
|
6
|
+
const binding = bindings({
|
|
7
|
+
bindings: "frida_binding",
|
|
8
|
+
try: [
|
|
9
|
+
["module_root", "bindings"],
|
|
10
|
+
[process.cwd(), "bindings"],
|
|
11
|
+
]
|
|
12
|
+
});
|
|
13
|
+
var MessageTypeImpl;
|
|
14
|
+
(function (MessageTypeImpl) {
|
|
15
|
+
MessageTypeImpl["Send"] = "send";
|
|
16
|
+
MessageTypeImpl["Error"] = "error";
|
|
17
|
+
})(MessageTypeImpl || (MessageTypeImpl = {}));
|
|
18
|
+
binding.MessageType = MessageTypeImpl;
|
|
19
|
+
export const MessageType = binding.MessageType;
|
|
20
|
+
var LogLevelImpl;
|
|
21
|
+
(function (LogLevelImpl) {
|
|
22
|
+
LogLevelImpl["Info"] = "info";
|
|
23
|
+
LogLevelImpl["Warning"] = "warning";
|
|
24
|
+
LogLevelImpl["Error"] = "error";
|
|
25
|
+
})(LogLevelImpl || (LogLevelImpl = {}));
|
|
26
|
+
binding.LogLevel = LogLevelImpl;
|
|
27
|
+
export const LogLevel = binding.LogLevel;
|
|
28
|
+
{
|
|
29
|
+
const STANDARD_SPAWN_OPTION_NAMES = new Set([
|
|
30
|
+
"argv",
|
|
31
|
+
"envp",
|
|
32
|
+
"env",
|
|
33
|
+
"cwd",
|
|
34
|
+
"stdio",
|
|
35
|
+
]);
|
|
36
|
+
class ScriptServices {
|
|
37
|
+
exportsProxy = new ScriptExportsProxy(this);
|
|
38
|
+
#script;
|
|
39
|
+
#pendingRequests = new Map();
|
|
40
|
+
#nextRequestId = 1;
|
|
41
|
+
constructor(script) {
|
|
42
|
+
this.#script = script;
|
|
43
|
+
process.nextTick(() => {
|
|
44
|
+
script.message.connect(() => { });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
handleMessageIntercept = (message, data) => {
|
|
48
|
+
if (message.type === MessageType.Send && isRpcSendMessage(message)) {
|
|
49
|
+
const [, id, operation, ...params] = message.payload;
|
|
50
|
+
this.#onRpcMessage(id, operation, params, data);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
else if (isLogMessage(message)) {
|
|
54
|
+
const opaqueMessage = message;
|
|
55
|
+
const logMessage = opaqueMessage;
|
|
56
|
+
this.#script.logHandler(logMessage.level, logMessage.payload);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
};
|
|
61
|
+
request(operation, params, data, cancellable = null) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const id = this.#nextRequestId++;
|
|
64
|
+
const complete = (error, result) => {
|
|
65
|
+
if (cancellable !== null) {
|
|
66
|
+
cancellable.cancelled.disconnect(onOperationCancelled);
|
|
67
|
+
}
|
|
68
|
+
this.#script.destroyed.disconnect(onScriptDestroyed);
|
|
69
|
+
this.#pendingRequests.delete(id);
|
|
70
|
+
if (error === null) {
|
|
71
|
+
resolve(result);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
reject(error);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
function onScriptDestroyed() {
|
|
78
|
+
complete(new Error("Script is destroyed"));
|
|
79
|
+
}
|
|
80
|
+
function onOperationCancelled() {
|
|
81
|
+
complete(new Error("Operation was cancelled"));
|
|
82
|
+
}
|
|
83
|
+
this.#pendingRequests.set(id, complete);
|
|
84
|
+
this.#script.post(["frida:rpc", id, operation, ...params], data);
|
|
85
|
+
this.#script.destroyed.connect(onScriptDestroyed);
|
|
86
|
+
if (cancellable !== null) {
|
|
87
|
+
cancellable.cancelled.connect(onOperationCancelled);
|
|
88
|
+
if (cancellable.isCancelled) {
|
|
89
|
+
onOperationCancelled();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (this.#script.isDestroyed) {
|
|
94
|
+
onScriptDestroyed();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
#onRpcMessage(id, operation, params, data) {
|
|
99
|
+
if (operation === RpcOperation.Ok || operation === RpcOperation.Error) {
|
|
100
|
+
const callback = this.#pendingRequests.get(id);
|
|
101
|
+
if (callback === undefined) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let value = null;
|
|
105
|
+
let error = null;
|
|
106
|
+
if (operation === RpcOperation.Ok) {
|
|
107
|
+
if (data !== null) {
|
|
108
|
+
value = (params.length > 1) ? [params[1], data] : data;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
value = params[0];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const [message, name, stack, rawErr] = params;
|
|
116
|
+
error = new Error(message);
|
|
117
|
+
error.name = name;
|
|
118
|
+
error.stack = stack;
|
|
119
|
+
Object.assign(error, rawErr);
|
|
120
|
+
}
|
|
121
|
+
callback(error, value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
class ScriptExportsProxy {
|
|
126
|
+
constructor(rpcController) {
|
|
127
|
+
return new Proxy(this, {
|
|
128
|
+
has(target, property) {
|
|
129
|
+
return !isReservedMethodName(property);
|
|
130
|
+
},
|
|
131
|
+
get(target, property, receiver) {
|
|
132
|
+
if (typeof property === "symbol") {
|
|
133
|
+
if (property === inspect.custom) {
|
|
134
|
+
return inspectProxy;
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
if (property in target) {
|
|
139
|
+
return target[property];
|
|
140
|
+
}
|
|
141
|
+
if (isReservedMethodName(property)) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return (...args) => {
|
|
145
|
+
let cancellable = null;
|
|
146
|
+
if (args[args.length - 1] instanceof Cancellable) {
|
|
147
|
+
cancellable = args.pop();
|
|
148
|
+
}
|
|
149
|
+
let data = null;
|
|
150
|
+
if (Buffer.isBuffer(args[args.length - 1])) {
|
|
151
|
+
data = args.pop();
|
|
152
|
+
}
|
|
153
|
+
return rpcController.request("call", [property, args], data, cancellable);
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
set(target, property, value, receiver) {
|
|
157
|
+
if (typeof property === "symbol") {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
target[property] = value;
|
|
161
|
+
return true;
|
|
162
|
+
},
|
|
163
|
+
ownKeys(target) {
|
|
164
|
+
return Object.getOwnPropertyNames(target);
|
|
165
|
+
},
|
|
166
|
+
getOwnPropertyDescriptor(target, property) {
|
|
167
|
+
if (property in target) {
|
|
168
|
+
return Object.getOwnPropertyDescriptor(target, property);
|
|
169
|
+
}
|
|
170
|
+
if (isReservedMethodName(property)) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
writable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
enumerable: true
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function inspectProxy() {
|
|
183
|
+
return "ScriptExportsProxy {}";
|
|
184
|
+
}
|
|
185
|
+
let RpcOperation;
|
|
186
|
+
(function (RpcOperation) {
|
|
187
|
+
RpcOperation["Ok"] = "ok";
|
|
188
|
+
RpcOperation["Error"] = "error";
|
|
189
|
+
})(RpcOperation || (RpcOperation = {}));
|
|
190
|
+
function isInternalMessage(message) {
|
|
191
|
+
return isRpcMessage(message) || isLogMessage(message);
|
|
192
|
+
}
|
|
193
|
+
function isRpcMessage(message) {
|
|
194
|
+
return message.type === MessageType.Send && isRpcSendMessage(message);
|
|
195
|
+
}
|
|
196
|
+
function isRpcSendMessage(message) {
|
|
197
|
+
const payload = message.payload;
|
|
198
|
+
if (!Array.isArray(payload)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
return payload[0] === "frida:rpc";
|
|
202
|
+
}
|
|
203
|
+
function isLogMessage(message) {
|
|
204
|
+
return message.type === "log";
|
|
205
|
+
}
|
|
206
|
+
function log(level, text) {
|
|
207
|
+
switch (level) {
|
|
208
|
+
case LogLevel.Info:
|
|
209
|
+
console.log(text);
|
|
210
|
+
break;
|
|
211
|
+
case LogLevel.Warning:
|
|
212
|
+
console.warn(text);
|
|
213
|
+
break;
|
|
214
|
+
case LogLevel.Error:
|
|
215
|
+
console.error(text);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const reservedMethodNames = new Set([
|
|
220
|
+
"then",
|
|
221
|
+
"catch",
|
|
222
|
+
"finally",
|
|
223
|
+
]);
|
|
224
|
+
function isReservedMethodName(name) {
|
|
225
|
+
return reservedMethodNames.has(name.toString());
|
|
226
|
+
}
|
|
227
|
+
const IO_PRIORITY_DEFAULT = 0;
|
|
228
|
+
class IOStreamAdapter extends Duplex {
|
|
229
|
+
#impl;
|
|
230
|
+
#input;
|
|
231
|
+
#output;
|
|
232
|
+
#pending = new Set();
|
|
233
|
+
#cancellable = new Cancellable();
|
|
234
|
+
constructor(impl) {
|
|
235
|
+
super({});
|
|
236
|
+
this.#impl = impl;
|
|
237
|
+
this.#input = impl.inputStream;
|
|
238
|
+
this.#output = impl.outputStream;
|
|
239
|
+
}
|
|
240
|
+
async _destroy(error, callback) {
|
|
241
|
+
this.#cancellable.cancel();
|
|
242
|
+
for (const operation of this.#pending) {
|
|
243
|
+
try {
|
|
244
|
+
await operation;
|
|
245
|
+
}
|
|
246
|
+
catch (e) {
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
await this.#impl.close(IO_PRIORITY_DEFAULT);
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
}
|
|
254
|
+
callback(error);
|
|
255
|
+
}
|
|
256
|
+
_read(size) {
|
|
257
|
+
const operation = this.#input.read(size, IO_PRIORITY_DEFAULT, this.#cancellable)
|
|
258
|
+
.then((data) => {
|
|
259
|
+
const isEof = data.length === 0;
|
|
260
|
+
if (isEof) {
|
|
261
|
+
this.push(null);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.push(data);
|
|
265
|
+
})
|
|
266
|
+
.catch((error) => {
|
|
267
|
+
if (this.#impl.closed) {
|
|
268
|
+
this.push(null);
|
|
269
|
+
}
|
|
270
|
+
this.emit("error", error);
|
|
271
|
+
});
|
|
272
|
+
this.#track(operation);
|
|
273
|
+
}
|
|
274
|
+
_write(chunk, encoding, callback) {
|
|
275
|
+
let data;
|
|
276
|
+
if (Buffer.isBuffer(chunk)) {
|
|
277
|
+
data = chunk;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
data = Buffer.from(chunk, encoding);
|
|
281
|
+
}
|
|
282
|
+
const operation = this.#writeAll(data)
|
|
283
|
+
.then(() => {
|
|
284
|
+
callback(null);
|
|
285
|
+
})
|
|
286
|
+
.catch((error) => {
|
|
287
|
+
callback(error);
|
|
288
|
+
});
|
|
289
|
+
this.#track(operation);
|
|
290
|
+
}
|
|
291
|
+
async #writeAll(data) {
|
|
292
|
+
let offset = 0;
|
|
293
|
+
do {
|
|
294
|
+
const n = await this.#output.write(data.slice(offset), IO_PRIORITY_DEFAULT, this.#cancellable);
|
|
295
|
+
offset += n;
|
|
296
|
+
} while (offset !== data.length);
|
|
297
|
+
}
|
|
298
|
+
#track(operation) {
|
|
299
|
+
this.#pending.add(operation);
|
|
300
|
+
operation
|
|
301
|
+
.catch(_ => { })
|
|
302
|
+
.finally(() => {
|
|
303
|
+
this.#pending.delete(operation);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
class CallbackAuthenticationService extends binding.AbstractAuthenticationService {
|
|
308
|
+
#callback;
|
|
309
|
+
constructor(callback) {
|
|
310
|
+
super();
|
|
311
|
+
this.#callback = callback;
|
|
312
|
+
}
|
|
313
|
+
async authenticate(token, cancellable) {
|
|
314
|
+
const info = await this.#callback(token);
|
|
315
|
+
return JSON.stringify(info);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function parseSocketAddress(address) {
|
|
319
|
+
const family = address.family;
|
|
320
|
+
switch (family) {
|
|
321
|
+
case SocketFamily.Unix: {
|
|
322
|
+
const addr = address;
|
|
323
|
+
switch (addr.addressType) {
|
|
324
|
+
case UnixSocketAddressType.Anonymous:
|
|
325
|
+
return {
|
|
326
|
+
family: "unix:anonymous",
|
|
327
|
+
};
|
|
328
|
+
case UnixSocketAddressType.Path:
|
|
329
|
+
return {
|
|
330
|
+
family: "unix:path",
|
|
331
|
+
path: addr.path.toString(),
|
|
332
|
+
};
|
|
333
|
+
case UnixSocketAddressType.Abstract:
|
|
334
|
+
case UnixSocketAddressType.AbstractPadded:
|
|
335
|
+
return {
|
|
336
|
+
family: "unix:abstract",
|
|
337
|
+
path: addr.path,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case SocketFamily.Ipv4: {
|
|
343
|
+
const addr = address;
|
|
344
|
+
return {
|
|
345
|
+
family: "ipv4",
|
|
346
|
+
address: addr.address.toString(),
|
|
347
|
+
port: addr.port,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
case SocketFamily.Ipv6: {
|
|
351
|
+
const addr = address;
|
|
352
|
+
return {
|
|
353
|
+
family: "ipv6",
|
|
354
|
+
address: addr.address.toString(),
|
|
355
|
+
port: addr.port,
|
|
356
|
+
flowlabel: addr.flowinfo,
|
|
357
|
+
scopeid: addr.scopeId,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
throw new Error("invalid BaseSocketAddress");
|
|
362
|
+
}
|
|
363
|
+
function objectToStrv(object) {
|
|
364
|
+
return Object.entries(object).map(([k, v]) => `${k}=${v}`);
|
|
365
|
+
}
|
|
366
|
+
class SignalWrapper {
|
|
367
|
+
#source;
|
|
368
|
+
#transform;
|
|
369
|
+
#intercept;
|
|
370
|
+
#handlers = new Set();
|
|
371
|
+
constructor(source, options) {
|
|
372
|
+
this.#source = source;
|
|
373
|
+
if (options === undefined || options.transform === undefined) {
|
|
374
|
+
this.#intercept = options?.intercept;
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
this.#transform = options.transform;
|
|
378
|
+
this.#intercept = options.intercept;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
connect(handler) {
|
|
382
|
+
this.#handlers.add(handler);
|
|
383
|
+
if (this.#handlers.size === 1) {
|
|
384
|
+
this.#source.connect(this.#wrappedHandler);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
disconnect(handler) {
|
|
388
|
+
this.#handlers.delete(handler);
|
|
389
|
+
if (this.#handlers.size === 0) {
|
|
390
|
+
this.#source.disconnect(this.#wrappedHandler);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
#wrappedHandler = ((...sourceArgs) => {
|
|
394
|
+
let targetArgs;
|
|
395
|
+
const transform = this.#transform;
|
|
396
|
+
if (transform === undefined) {
|
|
397
|
+
targetArgs = sourceArgs;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
targetArgs = transform(...sourceArgs);
|
|
401
|
+
}
|
|
402
|
+
const intercept = this.#intercept;
|
|
403
|
+
if (intercept !== undefined) {
|
|
404
|
+
if (!intercept(...targetArgs)) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
for (const handler of this.#handlers) {
|
|
409
|
+
handler(...targetArgs);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
function inspectWrapper(object, name, properties, depth, options) {
|
|
414
|
+
if (depth < 0) {
|
|
415
|
+
return options.stylize(`[${name}]`, "special");
|
|
416
|
+
}
|
|
417
|
+
const summary = Object.fromEntries(properties.map(name => [name, object[name]]));
|
|
418
|
+
const nextOptions = Object.assign({}, options, {
|
|
419
|
+
depth: (options.depth === null) ? null : depth - 1
|
|
420
|
+
});
|
|
421
|
+
return name + " " + inspect(summary, nextOptions);
|
|
422
|
+
}
|
|
423
|
+
binding.DeviceManager.prototype[inspect.custom] = function (depth, options) {
|
|
424
|
+
return inspectWrapper(this, "DeviceManager", [], depth, options);
|
|
425
|
+
};
|
|
426
|
+
binding._Device.prototype[inspect.custom] = function (depth, options) {
|
|
427
|
+
return inspectWrapper(this, "Device", ["id", "name", "icon", "type", "bus"], depth, options);
|
|
428
|
+
};
|
|
429
|
+
class Device extends binding._Device {
|
|
430
|
+
async getProcess(name, options = {}, cancellable) {
|
|
431
|
+
const { scope = Scope.Minimal, } = options;
|
|
432
|
+
const processes = await this.enumerateProcesses({ scope }, cancellable);
|
|
433
|
+
const mm = new Minimatch(name.toLowerCase());
|
|
434
|
+
const matching = processes.filter(process => mm.match(process.name.toLowerCase()));
|
|
435
|
+
if (matching.length === 1) {
|
|
436
|
+
return matching[0];
|
|
437
|
+
}
|
|
438
|
+
else if (matching.length > 1) {
|
|
439
|
+
throw new Error("Ambiguous name; it matches: " + matching.map(process => `${process.name} (pid: ${process.pid})`).join(", "));
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
throw new Error("Process not found");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
async #getPid(target, cancellable) {
|
|
446
|
+
if (typeof target === "number") {
|
|
447
|
+
return target;
|
|
448
|
+
}
|
|
449
|
+
const process = await this.getProcess(target, {}, cancellable);
|
|
450
|
+
return process.pid;
|
|
451
|
+
}
|
|
452
|
+
async querySystemParameters(cancellable) {
|
|
453
|
+
const result = await this._querySystemParameters(cancellable);
|
|
454
|
+
return result;
|
|
455
|
+
}
|
|
456
|
+
async spawn(programOrArgv, opts, cancellable) {
|
|
457
|
+
const options = {};
|
|
458
|
+
let program;
|
|
459
|
+
let argv;
|
|
460
|
+
if (typeof programOrArgv === "string") {
|
|
461
|
+
program = programOrArgv;
|
|
462
|
+
argv = opts?.argv;
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
program = programOrArgv[0];
|
|
466
|
+
argv = programOrArgv;
|
|
467
|
+
if (argv.length === 1) {
|
|
468
|
+
argv = undefined;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (argv !== undefined) {
|
|
472
|
+
options.argv = argv;
|
|
473
|
+
}
|
|
474
|
+
if (opts !== undefined) {
|
|
475
|
+
const envp = opts.envp;
|
|
476
|
+
if (envp !== undefined) {
|
|
477
|
+
options.envp = objectToStrv(envp);
|
|
478
|
+
}
|
|
479
|
+
const env = opts.env;
|
|
480
|
+
if (env !== undefined) {
|
|
481
|
+
options.env = objectToStrv(env);
|
|
482
|
+
}
|
|
483
|
+
const cwd = opts.cwd;
|
|
484
|
+
if (cwd !== undefined) {
|
|
485
|
+
options.cwd = cwd;
|
|
486
|
+
}
|
|
487
|
+
options.aux = Object.fromEntries(Object.entries(opts).filter(([k, v]) => !STANDARD_SPAWN_OPTION_NAMES.has(k)));
|
|
488
|
+
}
|
|
489
|
+
const result = await this._spawn(program, options, cancellable);
|
|
490
|
+
return result;
|
|
491
|
+
}
|
|
492
|
+
async input(target, data, cancellable) {
|
|
493
|
+
const pid = await this.#getPid(target, cancellable);
|
|
494
|
+
const result = await this._input(pid, data, cancellable);
|
|
495
|
+
return result;
|
|
496
|
+
}
|
|
497
|
+
async resume(target, cancellable) {
|
|
498
|
+
const pid = await this.#getPid(target, cancellable);
|
|
499
|
+
const result = await this._resume(pid, cancellable);
|
|
500
|
+
return result;
|
|
501
|
+
}
|
|
502
|
+
async kill(target, cancellable) {
|
|
503
|
+
const pid = await this.#getPid(target, cancellable);
|
|
504
|
+
const result = await this._kill(pid, cancellable);
|
|
505
|
+
return result;
|
|
506
|
+
}
|
|
507
|
+
async attach(target, options, cancellable) {
|
|
508
|
+
const pid = await this.#getPid(target, cancellable);
|
|
509
|
+
const result = await this._attach(pid, options, cancellable);
|
|
510
|
+
return result;
|
|
511
|
+
}
|
|
512
|
+
async injectLibraryFile(target, path, entrypoint, data, cancellable) {
|
|
513
|
+
const pid = await this.#getPid(target, cancellable);
|
|
514
|
+
const result = await this._injectLibraryFile(pid, path, entrypoint, data, cancellable);
|
|
515
|
+
return result;
|
|
516
|
+
}
|
|
517
|
+
async injectLibraryBlob(target, blob, entrypoint, data, cancellable) {
|
|
518
|
+
const pid = await this.#getPid(target, cancellable);
|
|
519
|
+
const result = await this._injectLibraryBlob(pid, blob, entrypoint, data, cancellable);
|
|
520
|
+
return result;
|
|
521
|
+
}
|
|
522
|
+
async openChannel(address, cancellable) {
|
|
523
|
+
const result = await this._openChannel(address, cancellable);
|
|
524
|
+
return new IOStreamAdapter(result);
|
|
525
|
+
}
|
|
526
|
+
output = new SignalWrapper(this._output, {
|
|
527
|
+
transform(pid, fd, data) {
|
|
528
|
+
return [pid, fd, data];
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
uninjected = new SignalWrapper(this._uninjected, {
|
|
532
|
+
transform(id) {
|
|
533
|
+
return [id];
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
binding.Device = Device;
|
|
538
|
+
binding.Application.prototype[inspect.custom] = function (depth, options) {
|
|
539
|
+
return inspectWrapper(this, "Application", ["identifier", "name", "pid", "parameters"], depth, options);
|
|
540
|
+
};
|
|
541
|
+
binding.Process.prototype[inspect.custom] = function (depth, options) {
|
|
542
|
+
return inspectWrapper(this, "Process", ["pid", "name", "parameters"], depth, options);
|
|
543
|
+
};
|
|
544
|
+
binding.Spawn.prototype[inspect.custom] = function (depth, options) {
|
|
545
|
+
return inspectWrapper(this, "Spawn", ["pid", "identifier"], depth, options);
|
|
546
|
+
};
|
|
547
|
+
binding.Child.prototype[inspect.custom] = function (depth, options) {
|
|
548
|
+
return inspectWrapper(this, "Child", ["pid", "parentPid", "origin", "identifier", "path", "argv", "envp"], depth, options);
|
|
549
|
+
};
|
|
550
|
+
binding.Crash.prototype[inspect.custom] = function (depth, options) {
|
|
551
|
+
return inspectWrapper(this, "Crash", ["pid", "processName", "summary", "report", "parameters"], depth, options);
|
|
552
|
+
};
|
|
553
|
+
binding._Bus.prototype[inspect.custom] = function (depth, options) {
|
|
554
|
+
return inspectWrapper(this, "Bus", [], depth, options);
|
|
555
|
+
};
|
|
556
|
+
class Bus extends binding._Bus {
|
|
557
|
+
post(message, data) {
|
|
558
|
+
const json = JSON.stringify(message);
|
|
559
|
+
this._post(json, data);
|
|
560
|
+
}
|
|
561
|
+
message = new SignalWrapper(this._message, {
|
|
562
|
+
transform(json, data) {
|
|
563
|
+
return [JSON.parse(json), data];
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
binding.Bus = Bus;
|
|
568
|
+
binding.Service.prototype[inspect.custom] = function (depth, options) {
|
|
569
|
+
return inspectWrapper(this, "Service", [], depth, options);
|
|
570
|
+
};
|
|
571
|
+
binding.Session.prototype[inspect.custom] = function (depth, options) {
|
|
572
|
+
return inspectWrapper(this, "Session", ["pid", "persistTimeout"], depth, options);
|
|
573
|
+
};
|
|
574
|
+
binding._Script.prototype[inspect.custom] = function (depth, options) {
|
|
575
|
+
return inspectWrapper(this, "Script", [], depth, options);
|
|
576
|
+
};
|
|
577
|
+
class Script extends binding._Script {
|
|
578
|
+
#services = new ScriptServices(this);
|
|
579
|
+
logHandler = log;
|
|
580
|
+
get isDestroyed() {
|
|
581
|
+
return this._isDestroyed();
|
|
582
|
+
}
|
|
583
|
+
get exports() {
|
|
584
|
+
return this.#services.exportsProxy;
|
|
585
|
+
}
|
|
586
|
+
get defaultLogHandler() {
|
|
587
|
+
return log;
|
|
588
|
+
}
|
|
589
|
+
post(message, data) {
|
|
590
|
+
const json = JSON.stringify(message);
|
|
591
|
+
this._post(json, data);
|
|
592
|
+
}
|
|
593
|
+
async enableDebugger(options, cancellable) {
|
|
594
|
+
const port = options?.port ?? 0;
|
|
595
|
+
const result = await this._enableDebugger(port, cancellable);
|
|
596
|
+
return result;
|
|
597
|
+
}
|
|
598
|
+
message = new SignalWrapper(this._message, {
|
|
599
|
+
transform(json, data) {
|
|
600
|
+
return [JSON.parse(json), data];
|
|
601
|
+
},
|
|
602
|
+
intercept: this.#services.handleMessageIntercept,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
binding.Script = Script;
|
|
606
|
+
binding.PortalMembership.prototype[inspect.custom] = function (depth, options) {
|
|
607
|
+
return inspectWrapper(this, "PortalMembership", [], depth, options);
|
|
608
|
+
};
|
|
609
|
+
binding.ControlService.prototype[inspect.custom] = function (depth, options) {
|
|
610
|
+
return inspectWrapper(this, "ControlService", [], depth, options);
|
|
611
|
+
};
|
|
612
|
+
binding._PortalService.prototype[inspect.custom] = function (depth, options) {
|
|
613
|
+
return inspectWrapper(this, "PortalService", ["device", "clusterParams", "controlParams"], depth, options);
|
|
614
|
+
};
|
|
615
|
+
class PortalService extends binding._PortalService {
|
|
616
|
+
constructor(options) {
|
|
617
|
+
const clusterParams = options?.clusterParams ?? new EndpointParameters();
|
|
618
|
+
const controlParams = options?.controlParams ?? null;
|
|
619
|
+
super(clusterParams, controlParams);
|
|
620
|
+
}
|
|
621
|
+
post(connectionId, message, data) {
|
|
622
|
+
const json = JSON.stringify(message);
|
|
623
|
+
this._post(connectionId, json, data);
|
|
624
|
+
}
|
|
625
|
+
narrowcast(tag, message, data) {
|
|
626
|
+
const json = JSON.stringify(message);
|
|
627
|
+
this._narrowcast(tag, json, data);
|
|
628
|
+
}
|
|
629
|
+
broadcast(message, data) {
|
|
630
|
+
const json = JSON.stringify(message);
|
|
631
|
+
this._broadcast(json, data);
|
|
632
|
+
}
|
|
633
|
+
nodeConnected = new SignalWrapper(this._nodeConnected, {
|
|
634
|
+
transform(connectionId, remoteAddress) {
|
|
635
|
+
return [connectionId, parseSocketAddress(remoteAddress)];
|
|
636
|
+
},
|
|
637
|
+
});
|
|
638
|
+
nodeJoined = new SignalWrapper(this._nodeJoined, {
|
|
639
|
+
transform(connectionId, application) {
|
|
640
|
+
return [connectionId, application];
|
|
641
|
+
},
|
|
642
|
+
});
|
|
643
|
+
nodeLeft = new SignalWrapper(this._nodeLeft, {
|
|
644
|
+
transform(connectionId, application) {
|
|
645
|
+
return [connectionId, application];
|
|
646
|
+
},
|
|
647
|
+
});
|
|
648
|
+
nodeDisconnected = new SignalWrapper(this._nodeDisconnected, {
|
|
649
|
+
transform(connectionId, remoteAddress) {
|
|
650
|
+
return [connectionId, parseSocketAddress(remoteAddress)];
|
|
651
|
+
},
|
|
652
|
+
});
|
|
653
|
+
controllerConnected = new SignalWrapper(this._controllerConnected, {
|
|
654
|
+
transform(connectionId, remoteAddress) {
|
|
655
|
+
return [connectionId, parseSocketAddress(remoteAddress)];
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
controllerDisconnected = new SignalWrapper(this._controllerDisconnected, {
|
|
659
|
+
transform(connectionId, remoteAddress) {
|
|
660
|
+
return [connectionId, parseSocketAddress(remoteAddress)];
|
|
661
|
+
},
|
|
662
|
+
});
|
|
663
|
+
authenticated = new SignalWrapper(this._authenticated, {
|
|
664
|
+
transform(connectionId, sessionInfo) {
|
|
665
|
+
return [connectionId, JSON.parse(sessionInfo)];
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
subscribe = new SignalWrapper(this._subscribe, {
|
|
669
|
+
transform(connectionId) {
|
|
670
|
+
return [connectionId];
|
|
671
|
+
},
|
|
672
|
+
});
|
|
673
|
+
message = new SignalWrapper(this._message, {
|
|
674
|
+
transform(connectionId, json, data) {
|
|
675
|
+
return [connectionId, JSON.parse(json), data];
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
binding.PortalService = PortalService;
|
|
680
|
+
binding.FileMonitor.prototype[inspect.custom] = function (depth, options) {
|
|
681
|
+
return inspectWrapper(this, "FileMonitor", ["path"], depth, options);
|
|
682
|
+
};
|
|
683
|
+
binding.Compiler.prototype[inspect.custom] = function (depth, options) {
|
|
684
|
+
return inspectWrapper(this, "Compiler", ["manager"], depth, options);
|
|
685
|
+
};
|
|
686
|
+
binding.StaticAuthenticationService.prototype[inspect.custom] = function (depth, options) {
|
|
687
|
+
return inspectWrapper(this, "StaticAuthenticationService", ["tokenHash"], depth, options);
|
|
688
|
+
};
|
|
689
|
+
binding._Relay.prototype[inspect.custom] = function (depth, options) {
|
|
690
|
+
return inspectWrapper(this, "Relay", ["address", "username", "password", "kind"], depth, options);
|
|
691
|
+
};
|
|
692
|
+
class Relay extends binding._Relay {
|
|
693
|
+
constructor(properties) {
|
|
694
|
+
const { address, username, password, kind } = properties;
|
|
695
|
+
super(address, username, password, kind);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
binding.Relay = Relay;
|
|
699
|
+
binding._EndpointParameters.prototype[inspect.custom] = function (depth, options) {
|
|
700
|
+
return inspectWrapper(this, "EndpointParameters", ["address", "port", "certificate", "origin", "authService", "assetRoot"], depth, options);
|
|
701
|
+
};
|
|
702
|
+
class EndpointParameters extends binding._EndpointParameters {
|
|
703
|
+
constructor(params) {
|
|
704
|
+
const address = params?.address ?? null;
|
|
705
|
+
const port = params?.port ?? 0;
|
|
706
|
+
const certificate = params?.certificate ?? null;
|
|
707
|
+
const origin = params?.origin ?? null;
|
|
708
|
+
let authService = null;
|
|
709
|
+
const auth = params?.authentication;
|
|
710
|
+
if (auth !== undefined) {
|
|
711
|
+
if (auth.scheme === "token") {
|
|
712
|
+
authService = new StaticAuthenticationService(auth.token);
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
authService = new CallbackAuthenticationService(auth.callback);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const assetRoot = params?.assetRoot ?? null;
|
|
719
|
+
super(address, port, certificate, origin, authService, assetRoot);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
binding.EndpointParameters = EndpointParameters;
|
|
723
|
+
binding.AuthenticationService.prototype[inspect.custom] = function (depth, options) {
|
|
724
|
+
return inspectWrapper(this, "AuthenticationService", [], depth, options);
|
|
725
|
+
};
|
|
726
|
+
binding.BaseObject.prototype[inspect.custom] = function (depth, options) {
|
|
727
|
+
return inspectWrapper(this, "BaseObject", [], depth, options);
|
|
728
|
+
};
|
|
729
|
+
binding._Cancellable.prototype[inspect.custom] = function (depth, options) {
|
|
730
|
+
return inspectWrapper(this, "Cancellable", [], depth, options);
|
|
731
|
+
};
|
|
732
|
+
class Cancellable extends binding._Cancellable {
|
|
733
|
+
get isCancelled() {
|
|
734
|
+
return this._isCancelled();
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
binding.Cancellable = Cancellable;
|
|
738
|
+
binding.IOStream.prototype[inspect.custom] = function (depth, options) {
|
|
739
|
+
return inspectWrapper(this, "IOStream", ["closed", "inputStream", "outputStream"], depth, options);
|
|
740
|
+
};
|
|
741
|
+
binding.InputStream.prototype[inspect.custom] = function (depth, options) {
|
|
742
|
+
return inspectWrapper(this, "InputStream", [], depth, options);
|
|
743
|
+
};
|
|
744
|
+
binding.OutputStream.prototype[inspect.custom] = function (depth, options) {
|
|
745
|
+
return inspectWrapper(this, "OutputStream", [], depth, options);
|
|
746
|
+
};
|
|
747
|
+
binding.InetSocketAddress.prototype[inspect.custom] = function (depth, options) {
|
|
748
|
+
return inspectWrapper(this, "InetSocketAddress", ["address", "flowinfo", "port", "scopeId"], depth, options);
|
|
749
|
+
};
|
|
750
|
+
binding.InetAddress.prototype[inspect.custom] = function (depth, options) {
|
|
751
|
+
return inspectWrapper(this, "InetAddress", ["family", "isAny", "isLinkLocal", "isLoopback", "isMcGlobal", "isMcLinkLocal", "isMcNodeLocal", "isMcOrgLocal", "isMcSiteLocal", "isMulticast", "isSiteLocal"], depth, options);
|
|
752
|
+
};
|
|
753
|
+
binding.UnixSocketAddress.prototype[inspect.custom] = function (depth, options) {
|
|
754
|
+
return inspectWrapper(this, "UnixSocketAddress", ["addressType", "path"], depth, options);
|
|
755
|
+
};
|
|
756
|
+
binding.BaseSocketAddress.prototype[inspect.custom] = function (depth, options) {
|
|
757
|
+
return inspectWrapper(this, "BaseSocketAddress", ["family"], depth, options);
|
|
758
|
+
};
|
|
759
|
+
binding.SocketAddressEnumerator.prototype[inspect.custom] = function (depth, options) {
|
|
760
|
+
return inspectWrapper(this, "SocketAddressEnumerator", [], depth, options);
|
|
761
|
+
};
|
|
762
|
+
binding.SocketConnectable.prototype[inspect.custom] = function (depth, options) {
|
|
763
|
+
return inspectWrapper(this, "SocketConnectable", [], depth, options);
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
binding.commitConstructors();
|
|
767
|
+
export const { DeviceManager, Device, RemoteDeviceOptions, Application, Process, ProcessMatchOptions, RawSpawnOptions, Spawn, Child, Crash, Bus, Service, Session, Script, PortalMembership, ControlService, ControlServiceOptions, PortalService, FileMonitor, Compiler, CompilerOptions, BuildOptions, WatchOptions, StaticAuthenticationService, FrontmostQueryOptions, ApplicationQueryOptions, ProcessQueryOptions, SessionOptions, ScriptOptions, SnapshotOptions, PortalOptions, PeerOptions, Relay, EndpointParameters, AbstractAuthenticationService, BaseObject, Cancellable, IOStream, InputStream, OutputStream, InetSocketAddress, InetAddress, UnixSocketAddress, BaseSocketAddress, SocketAddressEnumerator, Runtime, DeviceType, SourceMaps, JsCompression, Realm, SessionDetachReason, Scope, Stdio, ChildOrigin, SnapshotTransport, ScriptRuntime, RelayKind, FileMonitorEvent, SocketFamily, UnixSocketAddressType, } = binding;
|
|
768
|
+
const frida = {
|
|
769
|
+
DeviceManager,
|
|
770
|
+
Device,
|
|
771
|
+
RemoteDeviceOptions,
|
|
772
|
+
Application,
|
|
773
|
+
Process,
|
|
774
|
+
ProcessMatchOptions,
|
|
775
|
+
RawSpawnOptions,
|
|
776
|
+
Spawn,
|
|
777
|
+
Child,
|
|
778
|
+
Crash,
|
|
779
|
+
Bus,
|
|
780
|
+
Service,
|
|
781
|
+
Session,
|
|
782
|
+
Script,
|
|
783
|
+
PortalMembership,
|
|
784
|
+
ControlService,
|
|
785
|
+
ControlServiceOptions,
|
|
786
|
+
PortalService,
|
|
787
|
+
FileMonitor,
|
|
788
|
+
Compiler,
|
|
789
|
+
CompilerOptions,
|
|
790
|
+
BuildOptions,
|
|
791
|
+
WatchOptions,
|
|
792
|
+
StaticAuthenticationService,
|
|
793
|
+
FrontmostQueryOptions,
|
|
794
|
+
ApplicationQueryOptions,
|
|
795
|
+
ProcessQueryOptions,
|
|
796
|
+
SessionOptions,
|
|
797
|
+
ScriptOptions,
|
|
798
|
+
SnapshotOptions,
|
|
799
|
+
PortalOptions,
|
|
800
|
+
PeerOptions,
|
|
801
|
+
Relay,
|
|
802
|
+
EndpointParameters,
|
|
803
|
+
AbstractAuthenticationService,
|
|
804
|
+
BaseObject,
|
|
805
|
+
Cancellable,
|
|
806
|
+
IOStream,
|
|
807
|
+
InputStream,
|
|
808
|
+
OutputStream,
|
|
809
|
+
InetSocketAddress,
|
|
810
|
+
InetAddress,
|
|
811
|
+
UnixSocketAddress,
|
|
812
|
+
BaseSocketAddress,
|
|
813
|
+
SocketAddressEnumerator,
|
|
814
|
+
Runtime,
|
|
815
|
+
DeviceType,
|
|
816
|
+
SourceMaps,
|
|
817
|
+
JsCompression,
|
|
818
|
+
Realm,
|
|
819
|
+
SessionDetachReason,
|
|
820
|
+
Scope,
|
|
821
|
+
Stdio,
|
|
822
|
+
ChildOrigin,
|
|
823
|
+
SnapshotTransport,
|
|
824
|
+
ScriptRuntime,
|
|
825
|
+
RelayKind,
|
|
826
|
+
FileMonitorEvent,
|
|
827
|
+
SocketFamily,
|
|
828
|
+
UnixSocketAddressType,
|
|
829
|
+
MessageType,
|
|
830
|
+
LogLevel,
|
|
831
|
+
querySystemParameters,
|
|
832
|
+
spawn,
|
|
833
|
+
resume,
|
|
834
|
+
kill,
|
|
835
|
+
attach,
|
|
836
|
+
injectLibraryFile,
|
|
837
|
+
injectLibraryBlob,
|
|
838
|
+
enumerateDevices,
|
|
839
|
+
getDeviceManager,
|
|
840
|
+
getLocalDevice,
|
|
841
|
+
getRemoteDevice,
|
|
842
|
+
getUsbDevice,
|
|
843
|
+
getDevice,
|
|
844
|
+
};
|
|
845
|
+
export default frida;
|
|
846
|
+
let sharedDeviceManager = null;
|
|
847
|
+
export async function querySystemParameters(cancellable) {
|
|
848
|
+
const device = await getLocalDevice(cancellable);
|
|
849
|
+
return await device.querySystemParameters(cancellable);
|
|
850
|
+
}
|
|
851
|
+
export async function spawn(program, options, cancellable) {
|
|
852
|
+
const device = await getLocalDevice(cancellable);
|
|
853
|
+
return await device.spawn(program, options, cancellable);
|
|
854
|
+
}
|
|
855
|
+
export async function resume(target, cancellable) {
|
|
856
|
+
const device = await getLocalDevice(cancellable);
|
|
857
|
+
await device.resume(target, cancellable);
|
|
858
|
+
}
|
|
859
|
+
export async function kill(target, cancellable) {
|
|
860
|
+
const device = await getLocalDevice(cancellable);
|
|
861
|
+
await device.kill(target, cancellable);
|
|
862
|
+
}
|
|
863
|
+
export async function attach(target, options, cancellable) {
|
|
864
|
+
const device = await getLocalDevice(cancellable);
|
|
865
|
+
return await device.attach(target, options, cancellable);
|
|
866
|
+
}
|
|
867
|
+
export async function injectLibraryFile(target, path, entrypoint, data, cancellable) {
|
|
868
|
+
const device = await getLocalDevice(cancellable);
|
|
869
|
+
return await device.injectLibraryFile(target, path, entrypoint, data, cancellable);
|
|
870
|
+
}
|
|
871
|
+
export async function injectLibraryBlob(target, blob, entrypoint, data, cancellable) {
|
|
872
|
+
const device = await getLocalDevice(cancellable);
|
|
873
|
+
return await device.injectLibraryBlob(target, blob, entrypoint, data, cancellable);
|
|
874
|
+
}
|
|
875
|
+
export async function enumerateDevices(cancellable) {
|
|
876
|
+
const deviceManager = getDeviceManager();
|
|
877
|
+
return await deviceManager.enumerateDevices(cancellable);
|
|
878
|
+
}
|
|
879
|
+
;
|
|
880
|
+
export function getDeviceManager() {
|
|
881
|
+
if (sharedDeviceManager === null) {
|
|
882
|
+
sharedDeviceManager = new DeviceManager();
|
|
883
|
+
}
|
|
884
|
+
return sharedDeviceManager;
|
|
885
|
+
}
|
|
886
|
+
export function getLocalDevice(cancellable) {
|
|
887
|
+
return getMatchingDevice(device => device.type === DeviceType.Local, {}, cancellable);
|
|
888
|
+
}
|
|
889
|
+
export function getRemoteDevice(cancellable) {
|
|
890
|
+
return getMatchingDevice(device => device.type === DeviceType.Remote, {}, cancellable);
|
|
891
|
+
}
|
|
892
|
+
export function getUsbDevice(options, cancellable) {
|
|
893
|
+
return getMatchingDevice(device => device.type === DeviceType.Usb, options, cancellable);
|
|
894
|
+
}
|
|
895
|
+
export function getDevice(id, options, cancellable) {
|
|
896
|
+
return getMatchingDevice(device => device.id === id, options, cancellable);
|
|
897
|
+
}
|
|
898
|
+
async function getMatchingDevice(predicate, options = {}, cancellable = null) {
|
|
899
|
+
const device = await findMatchingDevice(predicate, cancellable);
|
|
900
|
+
if (device !== null) {
|
|
901
|
+
return device;
|
|
902
|
+
}
|
|
903
|
+
const { timeout = 0 } = options;
|
|
904
|
+
if (timeout === 0) {
|
|
905
|
+
throw new Error("Device not found");
|
|
906
|
+
}
|
|
907
|
+
const getDeviceEventually = new Promise((resolve, reject) => {
|
|
908
|
+
const deviceManager = getDeviceManager();
|
|
909
|
+
deviceManager.added.connect(onDeviceAdded);
|
|
910
|
+
const timer = (timeout !== null) ? setTimeout(onTimeout, timeout) : null;
|
|
911
|
+
if (cancellable !== null) {
|
|
912
|
+
cancellable.cancelled.connect(onCancel);
|
|
913
|
+
if (cancellable.isCancelled) {
|
|
914
|
+
onCancel();
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
findMatchingDevice(predicate, cancellable)
|
|
919
|
+
.then(device => {
|
|
920
|
+
if (device !== null) {
|
|
921
|
+
onSuccess(device);
|
|
922
|
+
}
|
|
923
|
+
})
|
|
924
|
+
.catch(onError);
|
|
925
|
+
function onDeviceAdded(device) {
|
|
926
|
+
if (predicate(device)) {
|
|
927
|
+
onSuccess(device);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
function onSuccess(device) {
|
|
931
|
+
stopMonitoring();
|
|
932
|
+
resolve(device);
|
|
933
|
+
}
|
|
934
|
+
function onError(error) {
|
|
935
|
+
stopMonitoring();
|
|
936
|
+
reject(error);
|
|
937
|
+
}
|
|
938
|
+
function onTimeout() {
|
|
939
|
+
onError(new Error("Timed out while waiting for device to appear"));
|
|
940
|
+
}
|
|
941
|
+
function onCancel() {
|
|
942
|
+
onError(new Error("Operation was cancelled"));
|
|
943
|
+
}
|
|
944
|
+
function stopMonitoring() {
|
|
945
|
+
cancellable?.cancelled.disconnect(onCancel);
|
|
946
|
+
if (timer !== null) {
|
|
947
|
+
clearTimeout(timer);
|
|
948
|
+
}
|
|
949
|
+
deviceManager.added.disconnect(onDeviceAdded);
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
return await getDeviceEventually;
|
|
953
|
+
}
|
|
954
|
+
async function findMatchingDevice(predicate, cancellable) {
|
|
955
|
+
const deviceManager = getDeviceManager();
|
|
956
|
+
const devices = await deviceManager.enumerateDevices(cancellable);
|
|
957
|
+
const matching = devices.filter(predicate);
|
|
958
|
+
if (matching.length === 0) {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
return matching[0];
|
|
962
|
+
}
|