@efffrida/frida-tools 0.0.14 → 0.0.16
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 +6 -10
- package/dist/{dts/FridaDevice.d.ts → FridaDevice.d.ts} +48 -4
- package/dist/FridaDevice.d.ts.map +1 -0
- package/dist/{esm/FridaDevice.js → FridaDevice.js} +22 -2
- package/dist/FridaDevice.js.map +1 -0
- package/dist/{dts/FridaDeviceAcquisitionError.d.ts → FridaDeviceAcquisitionError.d.ts} +2 -1
- package/dist/FridaDeviceAcquisitionError.d.ts.map +1 -0
- package/dist/{esm/FridaDeviceAcquisitionError.js → FridaDeviceAcquisitionError.js} +5 -1
- package/dist/FridaDeviceAcquisitionError.js.map +1 -0
- package/dist/FridaScript.d.ts +104 -0
- package/dist/FridaScript.d.ts.map +1 -0
- package/dist/{esm/FridaScript.js → FridaScript.js} +5 -0
- package/dist/FridaScript.js.map +1 -0
- package/dist/FridaSession.d.ts +72 -0
- package/dist/FridaSession.d.ts.map +1 -0
- package/dist/{esm/FridaSession.js → FridaSession.js} +10 -0
- package/dist/FridaSession.js.map +1 -0
- package/dist/FridaSessionError.d.ts.map +1 -0
- package/dist/FridaSessionError.js.map +1 -0
- package/dist/{dts/index.d.ts → index.d.ts} +8 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/{esm/index.js → index.js} +3 -0
- package/dist/index.js.map +1 -0
- package/dist/{dts/internal → internal}/device.d.ts.map +1 -1
- package/dist/internal/device.js +189 -0
- package/dist/internal/device.js.map +1 -0
- package/dist/{dts/internal → internal}/script.d.ts.map +1 -1
- package/dist/internal/script.js +229 -0
- package/dist/internal/script.js.map +1 -0
- package/dist/{dts/internal → internal}/session.d.ts.map +1 -1
- package/dist/internal/session.js +124 -0
- package/dist/internal/session.js.map +1 -0
- package/package.json +54 -68
- package/src/FridaDevice.ts +92 -8
- package/src/FridaDeviceAcquisitionError.ts +6 -2
- package/src/FridaScript.ts +67 -31
- package/src/FridaSession.ts +31 -5
- package/src/FridaSessionError.ts +1 -1
- package/src/index.ts +9 -5
- package/src/internal/device.ts +311 -32
- package/src/internal/script.ts +286 -118
- package/src/internal/session.ts +136 -27
- package/FridaDevice/package.json +0 -6
- package/FridaDeviceAcquisitionError/package.json +0 -6
- package/FridaScript/package.json +0 -6
- package/FridaSession/package.json +0 -6
- package/FridaSessionError/package.json +0 -6
- package/dist/cjs/FridaDevice.js +0 -60
- package/dist/cjs/FridaDevice.js.map +0 -1
- package/dist/cjs/FridaDeviceAcquisitionError.js +0 -33
- package/dist/cjs/FridaDeviceAcquisitionError.js.map +0 -1
- package/dist/cjs/FridaScript.js +0 -40
- package/dist/cjs/FridaScript.js.map +0 -1
- package/dist/cjs/FridaSession.js +0 -45
- package/dist/cjs/FridaSession.js.map +0 -1
- package/dist/cjs/FridaSessionError.js +0 -37
- package/dist/cjs/FridaSessionError.js.map +0 -1
- package/dist/cjs/index.js +0 -18
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/internal/device.js +0 -68
- package/dist/cjs/internal/device.js.map +0 -1
- package/dist/cjs/internal/script.js +0 -163
- package/dist/cjs/internal/script.js.map +0 -1
- package/dist/cjs/internal/session.js +0 -55
- package/dist/cjs/internal/session.js.map +0 -1
- package/dist/dts/FridaDevice.d.ts.map +0 -1
- package/dist/dts/FridaDeviceAcquisitionError.d.ts.map +0 -1
- package/dist/dts/FridaScript.d.ts +0 -80
- package/dist/dts/FridaScript.d.ts.map +0 -1
- package/dist/dts/FridaSession.d.ts +0 -56
- package/dist/dts/FridaSession.d.ts.map +0 -1
- package/dist/dts/FridaSessionError.d.ts.map +0 -1
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/esm/FridaDevice.js.map +0 -1
- package/dist/esm/FridaDeviceAcquisitionError.js.map +0 -1
- package/dist/esm/FridaScript.js.map +0 -1
- package/dist/esm/FridaSession.js.map +0 -1
- package/dist/esm/FridaSessionError.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/internal/device.js +0 -55
- package/dist/esm/internal/device.js.map +0 -1
- package/dist/esm/internal/script.js +0 -155
- package/dist/esm/internal/script.js.map +0 -1
- package/dist/esm/internal/session.js +0 -44
- package/dist/esm/internal/session.js.map +0 -1
- package/dist/esm/package.json +0 -4
- package/index/package.json +0 -6
- /package/dist/{dts/FridaSessionError.d.ts → FridaSessionError.d.ts} +0 -0
- /package/dist/{esm/FridaSessionError.js → FridaSessionError.js} +0 -0
- /package/dist/{dts/internal → internal}/device.d.ts +0 -0
- /package/dist/{dts/internal → internal}/script.d.ts +0 -0
- /package/dist/{dts/internal → internal}/session.d.ts +0 -0
package/src/internal/script.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import type * as Scope from "effect/Scope";
|
|
2
|
-
import type * as FridaScript from "../FridaScript.
|
|
2
|
+
import type * as FridaScript from "../FridaScript.ts";
|
|
3
3
|
|
|
4
|
+
import * as Path from "@effect/platform/Path";
|
|
5
|
+
import * as Cause from "effect/Cause";
|
|
4
6
|
import * as Context from "effect/Context";
|
|
5
7
|
import * as Deferred from "effect/Deferred";
|
|
6
8
|
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Exit from "effect/Exit";
|
|
7
10
|
import * as Function from "effect/Function";
|
|
8
11
|
import * as Layer from "effect/Layer";
|
|
12
|
+
import * as Mailbox from "effect/Mailbox";
|
|
9
13
|
import * as Option from "effect/Option";
|
|
10
14
|
import * as Predicate from "effect/Predicate";
|
|
11
|
-
import * as
|
|
15
|
+
import * as Schema from "effect/Schema";
|
|
12
16
|
import * as Sink from "effect/Sink";
|
|
13
17
|
import * as Stream from "effect/Stream";
|
|
14
|
-
import * as Take from "effect/Take";
|
|
15
18
|
import * as Frida from "frida";
|
|
16
|
-
|
|
17
|
-
import * as FridaSession from "../FridaSession.
|
|
18
|
-
import * as FridaSessionError from "../FridaSessionError.
|
|
19
|
+
|
|
20
|
+
import * as FridaSession from "../FridaSession.ts";
|
|
21
|
+
import * as FridaSessionError from "../FridaSessionError.ts";
|
|
19
22
|
|
|
20
23
|
/** @internal */
|
|
21
24
|
export const FridaScriptTypeId: FridaScript.FridaScriptTypeId = Symbol.for(
|
|
@@ -28,182 +31,347 @@ export const Tag = Context.GenericTag<FridaScript.FridaScript>("@efffrida/frida-
|
|
|
28
31
|
/** @internal */
|
|
29
32
|
export const isFridaScript = (u: unknown): u is FridaScript.FridaScript => Predicate.hasProperty(u, FridaScriptTypeId);
|
|
30
33
|
|
|
34
|
+
/** @internal */
|
|
35
|
+
export const compile = Function.dual<
|
|
36
|
+
(
|
|
37
|
+
options?: Frida.CompilerOptions | undefined
|
|
38
|
+
) => (path: string) => Effect.Effect<string, FridaSessionError.FridaSessionError, Scope.Scope>,
|
|
39
|
+
(
|
|
40
|
+
path: string,
|
|
41
|
+
options?: Frida.CompilerOptions | undefined
|
|
42
|
+
) => Effect.Effect<string, FridaSessionError.FridaSessionError, Scope.Scope>
|
|
43
|
+
>(
|
|
44
|
+
(arguments_) => Predicate.isString(arguments_[0]),
|
|
45
|
+
(path: string, options?: Frida.CompilerOptions | undefined) =>
|
|
46
|
+
Effect.asyncEffect<string, FridaSessionError.FridaSessionError, never, never, never, Scope.Scope>(
|
|
47
|
+
Effect.fnUntraced(function* (resume) {
|
|
48
|
+
// https://github.com/frida/frida-compile/blob/e81ae27369466c69868fc6ee36c0f227bbfe340c/src/cli.ts#L173-L182
|
|
49
|
+
interface Diagnostic {
|
|
50
|
+
category: string;
|
|
51
|
+
code: number;
|
|
52
|
+
text: string;
|
|
53
|
+
file?: {
|
|
54
|
+
path: string;
|
|
55
|
+
line: number;
|
|
56
|
+
character: number;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const formatDiagnostic = (diagnostic: Diagnostic): FridaSessionError.FridaSessionError => {
|
|
61
|
+
const location = diagnostic.file
|
|
62
|
+
? `${diagnostic.file.path}:${diagnostic.file.line}:${diagnostic.file.character}`
|
|
63
|
+
: undefined;
|
|
64
|
+
const message = `TS${diagnostic.code}: ${diagnostic.text}`;
|
|
65
|
+
const cause = location ? `${location} - ${message}` : message;
|
|
66
|
+
return new FridaSessionError.FridaSessionError({ cause, when: "compile" });
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const compileErrors: Array<Diagnostic> = [];
|
|
70
|
+
const compiler = new Frida.Compiler();
|
|
71
|
+
|
|
72
|
+
const onOutput = (bundle: string) => resume(Effect.succeed(bundle));
|
|
73
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => compiler.output.disconnect(onOutput)));
|
|
74
|
+
compiler.output.connect(onOutput);
|
|
75
|
+
|
|
76
|
+
const onDiagnostic = (diagnostic: Array<Diagnostic>) => {
|
|
77
|
+
for (const diag of diagnostic) {
|
|
78
|
+
if (diag.category === "error") {
|
|
79
|
+
compileErrors.push(diag);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => compiler.diagnostics.disconnect(onDiagnostic)));
|
|
84
|
+
compiler.diagnostics.connect(onDiagnostic);
|
|
85
|
+
|
|
86
|
+
const onFinished = () => {
|
|
87
|
+
if (compileErrors.length > 0) {
|
|
88
|
+
resume(
|
|
89
|
+
Effect.failCauseSync(() => {
|
|
90
|
+
const [first, ...rest] = compileErrors;
|
|
91
|
+
let cause = Cause.fail(formatDiagnostic(first));
|
|
92
|
+
for (const diag of rest) {
|
|
93
|
+
cause = Cause.parallel(cause, Cause.fail(formatDiagnostic(diag)));
|
|
94
|
+
}
|
|
95
|
+
return cause;
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => compiler.finished.disconnect(onFinished)));
|
|
101
|
+
compiler.finished.connect(onFinished);
|
|
102
|
+
|
|
103
|
+
const cancellable = new Frida.Cancellable();
|
|
104
|
+
compiler
|
|
105
|
+
.build(
|
|
106
|
+
path,
|
|
107
|
+
{
|
|
108
|
+
externals: options?.externals,
|
|
109
|
+
projectRoot: options?.projectRoot,
|
|
110
|
+
platform: options?.platform ?? Frida.JsPlatform.Gum,
|
|
111
|
+
typeCheck: options?.typeCheck ?? Frida.TypeCheckMode.Full,
|
|
112
|
+
sourceMaps: options?.sourceMaps ?? Frida.SourceMaps.Included,
|
|
113
|
+
compression: options?.compression ?? Frida.JsCompression.None,
|
|
114
|
+
bundleFormat: options?.bundleFormat ?? Frida.BundleFormat.Esm,
|
|
115
|
+
outputFormat: options?.outputFormat ?? Frida.OutputFormat.Unescaped,
|
|
116
|
+
},
|
|
117
|
+
cancellable
|
|
118
|
+
)
|
|
119
|
+
.catch((error) =>
|
|
120
|
+
resume(
|
|
121
|
+
Effect.fail(
|
|
122
|
+
new FridaSessionError.FridaSessionError({
|
|
123
|
+
cause: error,
|
|
124
|
+
when: "compile",
|
|
125
|
+
})
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return Effect.sync(() => cancellable.cancel());
|
|
131
|
+
})
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
|
|
31
135
|
/** @internal */
|
|
32
136
|
export const load = Function.dual<
|
|
33
137
|
(
|
|
34
|
-
options?:
|
|
138
|
+
options?: FridaScript.LoadOptions | undefined
|
|
35
139
|
) => (
|
|
36
|
-
|
|
140
|
+
entrypoint: URL
|
|
37
141
|
) => Effect.Effect<
|
|
38
142
|
FridaScript.FridaScript,
|
|
39
143
|
FridaSessionError.FridaSessionError,
|
|
40
|
-
|
|
144
|
+
Path.Path | FridaSession.FridaSession | Scope.Scope
|
|
41
145
|
>,
|
|
42
146
|
(
|
|
43
|
-
|
|
44
|
-
options?:
|
|
147
|
+
entrypoint: URL,
|
|
148
|
+
options?: FridaScript.LoadOptions | undefined
|
|
45
149
|
) => Effect.Effect<
|
|
46
150
|
FridaScript.FridaScript,
|
|
47
151
|
FridaSessionError.FridaSessionError,
|
|
48
|
-
|
|
152
|
+
Path.Path | FridaSession.FridaSession | Scope.Scope
|
|
49
153
|
>
|
|
50
154
|
>(
|
|
51
|
-
(arguments_) => Predicate.
|
|
155
|
+
(arguments_) => Predicate.hasProperty(arguments_[0], "href"),
|
|
52
156
|
Effect.fnUntraced(
|
|
53
|
-
function* (
|
|
54
|
-
|
|
55
|
-
options?: (Frida.ScriptOptions & { readonly resume?: boolean | undefined }) | undefined
|
|
56
|
-
) {
|
|
57
|
-
const { device } = yield* FridaDevice.FridaDevice;
|
|
157
|
+
function* (entrypoint: URL, options?: FridaScript.LoadOptions | undefined) {
|
|
158
|
+
const path = yield* Path.Path;
|
|
58
159
|
const { session } = yield* FridaSession.FridaSession;
|
|
59
160
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
161
|
+
const projectRoot = yield* path
|
|
162
|
+
.fromFileUrl(entrypoint)
|
|
163
|
+
.pipe(
|
|
164
|
+
Effect.mapError(
|
|
165
|
+
(cause) =>
|
|
166
|
+
new FridaSessionError.FridaSessionError({
|
|
167
|
+
when: "compile",
|
|
168
|
+
cause,
|
|
169
|
+
})
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
.pipe(Effect.map((p) => path.dirname(p)));
|
|
173
|
+
|
|
174
|
+
const source = yield* path
|
|
175
|
+
.fromFileUrl(entrypoint)
|
|
176
|
+
.pipe(
|
|
177
|
+
Effect.flatMap(
|
|
178
|
+
compile({
|
|
179
|
+
...options,
|
|
180
|
+
projectRoot: options?.projectRoot ?? projectRoot,
|
|
181
|
+
})
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
.pipe(Effect.scoped)
|
|
185
|
+
.pipe(
|
|
186
|
+
Effect.timeoutFail({
|
|
187
|
+
duration: "1 minute",
|
|
188
|
+
onTimeout: () =>
|
|
189
|
+
new FridaSessionError.FridaSessionError({
|
|
190
|
+
when: "compile",
|
|
191
|
+
cause: "TypeScript compilation timed out",
|
|
192
|
+
}),
|
|
193
|
+
})
|
|
194
|
+
)
|
|
195
|
+
.pipe(
|
|
196
|
+
Effect.catchTag(
|
|
197
|
+
"BadArgument",
|
|
198
|
+
(platformCause) =>
|
|
199
|
+
new FridaSessionError.FridaSessionError({
|
|
200
|
+
when: "compile",
|
|
201
|
+
cause: platformCause,
|
|
202
|
+
})
|
|
203
|
+
)
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const script = yield* Effect.tryPromise({
|
|
207
|
+
try: (signal) => {
|
|
208
|
+
const cancellable = new Frida.Cancellable();
|
|
209
|
+
signal.onabort = () => cancellable.cancel();
|
|
210
|
+
return session.createScript(
|
|
211
|
+
source,
|
|
212
|
+
{
|
|
213
|
+
runtime: Frida.ScriptRuntime.V8,
|
|
214
|
+
...options,
|
|
215
|
+
},
|
|
216
|
+
cancellable
|
|
217
|
+
);
|
|
218
|
+
},
|
|
219
|
+
catch: (cause) =>
|
|
220
|
+
new FridaSessionError.FridaSessionError({
|
|
221
|
+
cause,
|
|
222
|
+
when: "compile",
|
|
223
|
+
}),
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const destroyed = yield* Deferred.make<void, never>();
|
|
227
|
+
const scriptError = yield* Deferred.make<unknown, never>();
|
|
228
|
+
const mailbox = yield* Mailbox.make<
|
|
229
|
+
{ message: unknown; data: Option.Option<Buffer> },
|
|
230
|
+
FridaSessionError.FridaSessionError
|
|
231
|
+
>(options?.messageMailboxCapacity);
|
|
232
|
+
yield* Effect.addFinalizer(() => mailbox.shutdown); // TODO: is this needed?
|
|
233
|
+
|
|
234
|
+
const destroyedHandler: Frida.ScriptDestroyedHandler = () => {
|
|
235
|
+
Deferred.unsafeDone(destroyed, Effect.void);
|
|
236
|
+
mailbox.unsafeDone(
|
|
237
|
+
Exit.fail(
|
|
238
|
+
new FridaSessionError.FridaSessionError({
|
|
239
|
+
when: "message",
|
|
240
|
+
cause: "Script destroyed",
|
|
241
|
+
})
|
|
242
|
+
)
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => script.destroyed.disconnect(destroyedHandler)));
|
|
246
|
+
script.destroyed.connect(destroyedHandler);
|
|
247
|
+
|
|
76
248
|
const messageHandler: Frida.ScriptMessageHandler = (message: Frida.Message, data: Buffer | null): void => {
|
|
77
249
|
switch (message.type) {
|
|
78
250
|
case Frida.MessageType.Error: {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
251
|
+
const cause = new Error();
|
|
252
|
+
cause.name = "FridaScriptDefect";
|
|
253
|
+
cause.stack = message.stack ?? "";
|
|
254
|
+
cause.message = message.description.replace(/^\w{0,}: /, "") ?? "";
|
|
255
|
+
Deferred.unsafeDone(scriptError, Exit.succeed(cause));
|
|
256
|
+
mailbox.unsafeDone(
|
|
257
|
+
Exit.fail(
|
|
258
|
+
new FridaSessionError.FridaSessionError({
|
|
259
|
+
when: "message",
|
|
260
|
+
cause,
|
|
261
|
+
})
|
|
262
|
+
)
|
|
263
|
+
);
|
|
90
264
|
break;
|
|
91
265
|
}
|
|
92
266
|
|
|
93
267
|
case Frida.MessageType.Send: {
|
|
94
|
-
|
|
95
|
-
|
|
268
|
+
mailbox.unsafeOffer({
|
|
269
|
+
message: message.payload,
|
|
270
|
+
data: Option.fromNullable(data),
|
|
271
|
+
});
|
|
96
272
|
break;
|
|
97
273
|
}
|
|
98
274
|
|
|
99
|
-
default:
|
|
100
|
-
Function.absurd(message);
|
|
275
|
+
default: {
|
|
276
|
+
return Function.absurd(message);
|
|
277
|
+
}
|
|
101
278
|
}
|
|
102
279
|
};
|
|
103
|
-
|
|
104
|
-
const disconnectMessageHandler = Effect.sync(() => script.message.disconnect(messageHandler));
|
|
105
|
-
yield* Effect.addFinalizer(() => Effect.flatMap(messageQueue.shutdown, () => disconnectMessageHandler));
|
|
280
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => script.message.disconnect(messageHandler)));
|
|
106
281
|
script.message.connect(messageHandler);
|
|
107
282
|
|
|
108
|
-
const
|
|
283
|
+
const failIfScriptError = (when: FridaSessionError.FridaSessionError["when"]) =>
|
|
284
|
+
Effect.if(Deferred.isDone(scriptError), {
|
|
285
|
+
onFalse: () => Effect.void,
|
|
286
|
+
onTrue: () =>
|
|
287
|
+
Effect.flatMap(
|
|
288
|
+
Deferred.await(scriptError),
|
|
289
|
+
(cause) => new FridaSessionError.FridaSessionError({ cause, when })
|
|
290
|
+
),
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const failIfDestroyed = (when: FridaSessionError.FridaSessionError["when"]) =>
|
|
294
|
+
Effect.if(Deferred.isDone(destroyed), {
|
|
295
|
+
onFalse: () => Effect.void,
|
|
296
|
+
onTrue: () => new FridaSessionError.FridaSessionError({ cause: "Script is destroyed", when }),
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
const stream = yield* Stream.share(
|
|
300
|
+
Mailbox.toStream(mailbox),
|
|
301
|
+
options?.streamShareOptions ?? {
|
|
302
|
+
replay: 100,
|
|
303
|
+
capacity: "unbounded",
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
|
|
109
307
|
const sink = Sink.forEach<
|
|
110
|
-
{ message:
|
|
308
|
+
{ message: unknown; data: Option.Option<Buffer> },
|
|
111
309
|
void,
|
|
112
310
|
FridaSessionError.FridaSessionError,
|
|
113
311
|
never
|
|
114
|
-
>(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
);
|
|
122
|
-
} else {
|
|
123
|
-
return Effect.sync(() => script.post(message, Option.getOrNull(data)));
|
|
124
|
-
}
|
|
125
|
-
});
|
|
312
|
+
>(
|
|
313
|
+
Effect.fnUntraced(function* ({ data, message }) {
|
|
314
|
+
yield* failIfDestroyed("message");
|
|
315
|
+
yield* failIfScriptError("message");
|
|
316
|
+
script.post(message, Option.getOrNull(data));
|
|
317
|
+
})
|
|
318
|
+
);
|
|
126
319
|
|
|
127
|
-
const
|
|
128
|
-
const destroyedHandler = () => Deferred.unsafeDone(destroyed, Effect.void);
|
|
129
|
-
script.destroyed.connect(destroyedHandler);
|
|
130
|
-
|
|
131
|
-
const callExport = (exportName: string) =>
|
|
320
|
+
const callExport = <A, I, R>(exportName: string, schema: Schema.Schema<A, I, R>) =>
|
|
132
321
|
Effect.fn(`call frida export ${exportName}`)(function* (...args: Array<any>) {
|
|
133
322
|
yield* Effect.annotateCurrentSpan("args", args);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (isDestroyed) {
|
|
137
|
-
return yield* new FridaSessionError.FridaSessionError({
|
|
138
|
-
when: "rpcCall",
|
|
139
|
-
cause: "Script is destroyed",
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (Predicate.isNotUndefined(scriptDefectCause)) {
|
|
144
|
-
return yield* new FridaSessionError.FridaSessionError({
|
|
145
|
-
when: "rpcCall",
|
|
146
|
-
cause: scriptDefectCause,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
323
|
+
yield* failIfDestroyed("rpcCall");
|
|
324
|
+
yield* failIfScriptError("rpcCall");
|
|
150
325
|
const result = yield* Effect.tryPromise({
|
|
151
326
|
try: () => script.exports[exportName](...args) as Promise<unknown>,
|
|
152
327
|
catch: (cause) => new FridaSessionError.FridaSessionError({ when: "rpcCall", cause }),
|
|
153
328
|
});
|
|
154
|
-
|
|
155
329
|
yield* Effect.annotateCurrentSpan("result", result);
|
|
156
|
-
return result;
|
|
330
|
+
return yield* Schema.decodeUnknown(schema)(result);
|
|
157
331
|
});
|
|
158
332
|
|
|
159
333
|
yield* Effect.tryPromise({
|
|
160
|
-
try: () =>
|
|
334
|
+
try: (signal) => {
|
|
335
|
+
const cancellable = new Frida.Cancellable();
|
|
336
|
+
signal.onabort = () => cancellable.cancel();
|
|
337
|
+
return script.load(cancellable);
|
|
338
|
+
},
|
|
161
339
|
catch: (cause) => new FridaSessionError.FridaSessionError({ cause, when: "load" }),
|
|
162
340
|
});
|
|
163
341
|
|
|
164
|
-
if (options?.resume === true) {
|
|
165
|
-
yield* Effect.tryPromise({
|
|
166
|
-
try: () => device.resume(session.pid),
|
|
167
|
-
catch: (cause) => new FridaSessionError.FridaSessionError({ cause, when: "resume" }),
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
342
|
return {
|
|
172
343
|
sink,
|
|
173
|
-
script,
|
|
174
344
|
stream,
|
|
345
|
+
script,
|
|
175
346
|
destroyed,
|
|
176
347
|
callExport,
|
|
348
|
+
scriptError,
|
|
177
349
|
[FridaScriptTypeId]: FridaScriptTypeId,
|
|
178
350
|
} as const;
|
|
179
351
|
},
|
|
180
|
-
Effect.acquireRelease(({ script }: FridaScript.FridaScript) =>
|
|
352
|
+
Effect.acquireRelease(({ script }: FridaScript.FridaScript) =>
|
|
353
|
+
Effect.promise((signal) => {
|
|
354
|
+
const cancellable = new Frida.Cancellable();
|
|
355
|
+
signal.onabort = () => cancellable.cancel();
|
|
356
|
+
return script.unload(cancellable);
|
|
357
|
+
})
|
|
358
|
+
)
|
|
181
359
|
)
|
|
182
360
|
);
|
|
183
361
|
|
|
184
362
|
/** @internal */
|
|
185
363
|
export const layer = Function.dual<
|
|
186
364
|
(
|
|
187
|
-
options?:
|
|
365
|
+
options?: FridaScript.LoadOptions | undefined
|
|
188
366
|
) => (
|
|
189
|
-
|
|
190
|
-
) => Layer.Layer<
|
|
191
|
-
FridaScript.FridaScript,
|
|
192
|
-
FridaSessionError.FridaSessionError,
|
|
193
|
-
FridaSession.FridaSession | FridaDevice.FridaDevice
|
|
194
|
-
>,
|
|
367
|
+
entrypoint: URL
|
|
368
|
+
) => Layer.Layer<FridaScript.FridaScript, FridaSessionError.FridaSessionError, FridaSession.FridaSession>,
|
|
195
369
|
(
|
|
196
|
-
|
|
197
|
-
options?:
|
|
198
|
-
) => Layer.Layer<
|
|
199
|
-
FridaScript.FridaScript,
|
|
200
|
-
FridaSessionError.FridaSessionError,
|
|
201
|
-
FridaSession.FridaSession | FridaDevice.FridaDevice
|
|
202
|
-
>
|
|
370
|
+
entrypoint: URL,
|
|
371
|
+
options?: FridaScript.LoadOptions | undefined
|
|
372
|
+
) => Layer.Layer<FridaScript.FridaScript, FridaSessionError.FridaSessionError, FridaSession.FridaSession>
|
|
203
373
|
>(
|
|
204
|
-
(arguments_) => Predicate.
|
|
205
|
-
(
|
|
206
|
-
|
|
207
|
-
options?: (Frida.ScriptOptions & { readonly resume?: boolean | undefined }) | undefined
|
|
208
|
-
) => Layer.scoped(Tag, load(source, options))
|
|
374
|
+
(arguments_) => Predicate.hasProperty(arguments_[0], "href"),
|
|
375
|
+
(entrypoint: URL, options?: FridaScript.LoadOptions | undefined) =>
|
|
376
|
+
Layer.scoped(Tag, load(entrypoint, options)).pipe(Layer.provide(Path.layer))
|
|
209
377
|
);
|