Skip to content

Commit

Permalink
Use WS createConnection option to access Frida over custom streams
Browse files Browse the repository at this point in the history
This requires WS 8.17, which exposes that option
  • Loading branch information
pimterry committed Apr 30, 2024
1 parent 3a0b4f9 commit 4cf7055
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
3 changes: 2 additions & 1 deletion karma.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ module.exports = function(config: any) {
target: 'esnext',
external: [
'./test/run-frida-server',
'child_process'
'child_process',
'net'
],
define: {
'process.env.FIXTURES_PATH': JSON.stringify(path.join(__dirname, 'test', 'fixtures')),
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"isomorphic-ws": "^4.0.1",
"long": "^4.0.0",
"ssri": "^10.0.4",
"ws": "^8.17.0",
"xz-decompress": "^0.2.1"
}
}
28 changes: 22 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type * as stream from 'stream';
import WebSocket = require('isomorphic-ws');
import createWebSocketStream = require('@httptoolkit/websocket-stream');
import dbus = require('@httptoolkit/dbus-native');
Expand All @@ -12,21 +13,36 @@ export {

const DEFAULT_FRIDA_PORT = 27042;

export async function connect(options: {
host?: string
} = {}) {
const fridaHost = options.host || `127.0.0.1:${DEFAULT_FRIDA_PORT}`;

const socket = new WebSocket(`ws://${fridaHost}/ws`);
const connectFridaWebSocket = async (fridaHost: string, options?: {
createConnection?: () => stream.Duplex
}) => {
const socket = new WebSocket(`ws://${fridaHost}/ws`, options);
socket.binaryType = 'arraybuffer';

await new Promise((resolve, reject) => {
socket.addEventListener('open', resolve);
socket.addEventListener('error', reject);
});

return socket;
}

export async function connect(options:
| { host?: string, stream?: undefined }
// Note that providing a stream directly is supported on Node only
| { stream?: stream.Duplex, host?: undefined }= {}
) {
const fridaHost = options.host || `127.0.0.1:${DEFAULT_FRIDA_PORT}`;

const webSocket = options.stream
? await connectFridaWebSocket(fridaHost, {
createConnection: () => options.stream!
})
: await connectFridaWebSocket(fridaHost);

const bus = dbus.createClient({
stream: createWebSocketStream(socket),
stream: createWebSocketStream(webSocket),
direct: true,
authMethods: []
});
Expand Down
16 changes: 16 additions & 0 deletions test/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import('./frida-test-setup');

import * as ChildProc from 'child_process';
import * as path from 'path';
import * as net from 'net';
import { expect } from 'chai';

import { fetch } from 'cross-fetch';
Expand Down Expand Up @@ -103,6 +104,21 @@ describe("Frida-JS", () => {
});

if (isNode) {
it("can connect to a Frida instance by raw stream", async () => {
const socket = net.createConnection({
host: '127.0.0.1',
port: 27042
});

await new Promise((resolve, reject) => {
socket.on('connect', resolve);
socket.on('error', reject);
});

fridaClient = await connect({ stream: socket, host: 'localhost:12345' as any });
expect((await fridaClient.enumerateProcesses()).length).to.be.greaterThan(0);
});

it("can inject into a target process", async () => {
// Start a demo subprocess to inject into:
const childProc = ChildProc.spawn(
Expand Down

0 comments on commit 4cf7055

Please sign in to comment.