archieve-projects/微信机器人/node_modules/frida/dist/script.js

251 lines
8.1 KiB
JavaScript
Executable File

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogLevel = exports.MessageType = exports.ScriptRuntime = exports.Script = void 0;
const cancellable_1 = require("./cancellable");
const signals_1 = require("./signals");
const util_1 = require("util");
class Script {
constructor(impl) {
this.impl = impl;
this.logHandlerImpl = log;
const services = new ScriptServices(this, impl.signals);
const rpcController = services;
this.exportsProxy = new ScriptExportsProxy(rpcController);
const signals = services;
this.destroyed = new signals_1.Signal(signals, "destroyed");
this.message = new signals_1.Signal(signals, "message");
}
get isDestroyed() {
return this.impl.isDestroyed;
}
get exports() {
return this.exportsProxy;
}
get logHandler() {
return this.logHandlerImpl;
}
set logHandler(handler) {
this.logHandlerImpl = handler;
}
get defaultLogHandler() {
return log;
}
load(cancellable) {
return this.impl.load(cancellable);
}
unload(cancellable) {
return this.impl.unload(cancellable);
}
eternalize(cancellable) {
return this.impl.eternalize(cancellable);
}
post(message, data = null) {
this.impl.post(message, data);
}
[util_1.inspect.custom](depth, options) {
return "Script {}";
}
}
exports.Script = Script;
var ScriptRuntime;
(function (ScriptRuntime) {
ScriptRuntime["Default"] = "default";
ScriptRuntime["QJS"] = "qjs";
ScriptRuntime["V8"] = "v8";
})(ScriptRuntime = exports.ScriptRuntime || (exports.ScriptRuntime = {}));
var MessageType;
(function (MessageType) {
MessageType["Send"] = "send";
MessageType["Error"] = "error";
})(MessageType = exports.MessageType || (exports.MessageType = {}));
var LogLevel;
(function (LogLevel) {
LogLevel["Info"] = "info";
LogLevel["Warning"] = "warning";
LogLevel["Error"] = "error";
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
class ScriptServices extends signals_1.SignalAdapter {
constructor(script, signals) {
super(signals);
this.script = script;
this.pendingRequests = {};
this.nextRequestId = 1;
this.onDestroyed = () => {
this.signals.disconnect("destroyed", this.onDestroyed);
this.signals.disconnect("message", this.onMessage);
};
this.onMessage = (message, data) => {
if (message.type === MessageType.Send && isRpcSendMessage(message)) {
const [, id, operation, ...params] = message.payload;
this.onRpcMessage(id, operation, params, data);
}
else if (isLogMessage(message)) {
const opaqueMessage = message;
const logMessage = opaqueMessage;
this.script.logHandler(logMessage.level, logMessage.payload);
}
};
this.signals.connect("destroyed", this.onDestroyed);
this.signals.connect("message", this.onMessage);
}
getProxy(name, userHandler) {
if (name === "message") {
return (message, data) => {
if (!isInternalMessage(message)) {
userHandler(message, data);
}
};
}
return null;
}
request(operation, params, cancellable) {
return new Promise((resolve, reject) => {
const id = this.nextRequestId++;
const complete = (error, result) => {
if (cancellable !== undefined) {
cancellable.cancelled.disconnect(onOperationCancelled);
}
this.signals.disconnect("destroyed", onScriptDestroyed);
delete this.pendingRequests[id];
if (error === null) {
resolve(result);
}
else {
reject(error);
}
};
function onScriptDestroyed() {
complete(new Error("Script is destroyed"));
}
function onOperationCancelled() {
complete(new Error("Operation was cancelled"));
}
this.pendingRequests[id] = complete;
this.script.post(["frida:rpc", id, operation].concat(params));
this.signals.connect("destroyed", onScriptDestroyed);
if (cancellable !== undefined) {
cancellable.cancelled.connect(onOperationCancelled);
if (cancellable.isCancelled) {
onOperationCancelled();
return;
}
}
if (this.script.isDestroyed) {
onScriptDestroyed();
}
});
}
onRpcMessage(id, operation, params, data) {
if (operation === RpcOperation.Ok || operation === RpcOperation.Error) {
const callback = this.pendingRequests[id];
if (callback === undefined) {
return;
}
let value = null;
let error = null;
if (operation === RpcOperation.Ok) {
value = (data !== null) ? data : params[0];
}
else {
const [message, name, stack, rawErr] = params;
error = new Error(message);
error.name = name;
error.stack = stack;
Object.assign(error, rawErr);
}
callback(error, value);
}
}
}
function ScriptExportsProxy(rpcController) {
return new Proxy(this, {
has(target, property) {
return !isReservedMethodName(property);
;
},
get(target, property, receiver) {
if (property in target) {
return target[property];
}
if (property === util_1.inspect.custom) {
return inspectProxy;
}
if (isReservedMethodName(property)) {
return undefined;
}
return (...args) => {
let cancellable;
if (args[args.length - 1] instanceof cancellable_1.Cancellable) {
cancellable = args.pop();
}
return rpcController.request("call", [property, args], cancellable);
};
},
set(target, property, value, receiver) {
target[property] = value;
return true;
},
ownKeys(target) {
return Object.getOwnPropertyNames(target);
},
getOwnPropertyDescriptor(target, property) {
if (property in target) {
return Object.getOwnPropertyDescriptor(target, property);
}
if (isReservedMethodName(property)) {
return undefined;
}
return {
writable: true,
configurable: true,
enumerable: true
};
},
});
}
function inspectProxy() {
return "ScriptExportsProxy {}";
}
var RpcOperation;
(function (RpcOperation) {
RpcOperation["Ok"] = "ok";
RpcOperation["Error"] = "error";
})(RpcOperation || (RpcOperation = {}));
function isInternalMessage(message) {
return isRpcMessage(message) || isLogMessage(message);
}
function isRpcMessage(message) {
return message.type === MessageType.Send && isRpcSendMessage(message);
}
function isRpcSendMessage(message) {
const payload = message.payload;
if (!(payload instanceof Array)) {
return false;
}
return payload[0] === "frida:rpc";
}
function isLogMessage(message) {
return message.type === "log";
}
function log(level, text) {
switch (level) {
case LogLevel.Info:
console.log(text);
break;
case LogLevel.Warning:
console.warn(text);
break;
case LogLevel.Error:
console.error(text);
break;
}
}
const reservedMethodNames = new Set([
"then",
"catch",
"finally",
]);
function isReservedMethodName(name) {
return reservedMethodNames.has(name.toString());
}