frida-js
Version:
Pure-JS bindings to control Frida from node.js & browsers.
179 lines (178 loc) • 6.65 kB
TypeScript
import type * as stream from 'stream';
import dbus = require('@httptoolkit/dbus-native');
import { DBusVariantDict, NestedStringDict } from './dbus-value';
export { getFridaReleaseDetails, calculateFridaSRI, downloadFridaServer } from './download-frida';
export declare function connect(options?: {
host?: string;
stream?: undefined;
} | {
stream?: stream.Duplex;
host?: undefined;
}): Promise<FridaSession>;
interface HostSession {
QuerySystemParameters(): Promise<DBusVariantDict>;
EnumerateProcesses(arg: {}): Promise<Array<[pid: number, name: string]>>;
EnumerateApplications(arg: {}): Promise<Array<[id: string, name: string, pid: number | 0]>>;
Attach(pid: number, options: {}): Promise<[string]>;
Spawn(program: string, options: [
hasArgv: boolean,
argv: string[],
hasEnvP: boolean,
envp: string[],
hasEnv: boolean,
env: string[],
cwd: string,
stdio: number,
aux: []
]): Promise<number>;
Resume(pid: number): Promise<void>;
Kill(pid: number): Promise<void>;
}
interface AgentSession {
CreateScript(script: string, options: {}): Promise<[number]>;
LoadScript(scriptId: [number]): Promise<void>;
PostMessages(messages: [AgentMessage], batchId: number): Promise<void>;
}
/**
* A message from a Frida script to the runner.
* https://github.com/frida/frida-core/blob/main/lib/base/session.vala#L124C2-L146C3
* kind is the AgentMessageKind, "1" is a script message. There is also Debugger but no enum number is specified.
* script_id is the script id that sent the message. It is part of the AgentScriptId type.
* text is the message in plain text.
* has_data is a boolean that indicates if there is data attached to the message.
* data is the data attached to the message. It is a byte array.
*/
type AgentMessage = [kind: number, script_id: number[], text: string, has_data: boolean, data: Buffer | null];
/**
* A message sent from a script to the agent.
* https://github.com/frida/frida-node/blob/main/lib/script.ts#L103-L115
*/
export declare enum MessageType {
Send = "send",
Error = "error",
Log = "log"
}
export type Message = ScriptAgentSendMessage | ScriptAgentErrorMessage | ScriptAgentLogMessage;
export interface ScriptAgentSendMessage {
type: MessageType.Send;
payload: any;
}
export interface ScriptAgentErrorMessage {
type: MessageType.Error;
description: string;
stack?: string;
fileName?: string;
lineNumber?: number;
columnNumber?: number;
}
export interface ScriptAgentLogMessage {
type: MessageType.Log;
level: string;
payload: string;
}
export declare class FridaSession {
private bus;
constructor(bus: dbus.DBusClient);
/**
* Disconnect from Frida. Returns a promise that resolves once the connection has been closed.
*/
disconnect(): Promise<void>;
private getHostSession;
private getAgentSession;
/**
* Query the system parameters of the target Frida server. Returns metadata
* as a nested dictionary of strings.
*/
queryMetadata(): Promise<NestedStringDict>;
/**
* List all running processes accessible to the target Frida server. Returns an array
* of { pid, name } objects.
*/
enumerateProcesses(): Promise<Array<{
pid: number;
name: string;
}>>;
/**
* List all installed applications accessible on the target Frida server. Returns an array of
* { pid, id, name } objects, where pid is null if the application is not currently running.
*
* This is only applicable to mobile devices, and will return an empty array everywhere else.
*/
enumerateApplications(): Promise<Array<{
pid: number | null;
id: string;
name: string;
}>>;
attachToProcess(pid: number): Promise<{
session: FridaAgentSession;
}>;
/**
* Attach to a given pid and inject a Frida script to manipulate the target program.
*
* Whether you can attach to the process may depend on system configuration. For
* Linux specifically, if the process is not a child of your own process, you may
* need to run `sudo sysctl kernel.yama.ptrace_scope=0` first.
*/
injectIntoProcess(pid: number, fridaScript: string): Promise<{
session: FridaAgentSession;
script: FridaScript;
}>;
/**
* Run arbitrary Node.js code directly within a target Node process. The given
* code string will be wrapped with a Frida hook that injects it directly into
* the event loop, so it will run immediately.
*/
injectIntoNodeJSProcess(pid: number, nodeScript: string): Promise<{
session: FridaAgentSession;
script: FridaScript;
}>;
spawnPaused(command: string, args: string[] | undefined): Promise<{
pid: number;
session: FridaAgentSession;
}>;
spawnWithScript(command: string, args: string[] | undefined, fridaScript: string): Promise<{
pid: number;
session: FridaAgentSession;
script: FridaScript;
}>;
}
export declare class FridaAgentSession {
private bus;
private hostVersion;
private hostSession;
private pid;
private sessionId;
private agentSession;
constructor(bus: dbus.DBusClient, hostVersion: string, hostSession: HostSession, pid: number, sessionId: string, agentSession: AgentSession);
/**
* This method sets up a message handler for messages sent from the agent.
* @param cb Callback to be called when a message is received from the agent.
*/
onMessage(cb: (message: Message) => void): void;
/**
* Create a new Frida script within this agent session.
* @param script The Frida script in plain text to create.
* @param options Options to pass to the script.
*/
createScript(script: string, options?: {}): Promise<FridaScript>;
resume(): Promise<void>;
kill(): Promise<void>;
}
export declare class FridaScript {
private bus;
private agentSession;
private scriptId;
constructor(bus: dbus.DBusClient, agentSession: AgentSession, scriptId: [number]);
/**
* Load the script into the target process.
* @returns Promise that resolves when the script is loaded.
*/
loadScript(): Promise<void>;
/**
* Send a message to the script.
* @param message - The message object to send, will be JSON stringified.
* @param data - Optional binary data to send along with the message.
* @returns Promise that resolves when the message is posted.
*/
post(message: any, data?: Buffer | null): Promise<void>;
}