修复游戏内控制台bug

This commit is contained in:
IceCola 2024-05-29 19:44:44 +08:00
parent 19006f23c6
commit 55736093a6
3 changed files with 67 additions and 24 deletions

View File

@ -1229,6 +1229,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
return;
}
//
control.overrideParameter("target", window);
})
.start();
@ -1260,21 +1261,27 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
*/
let fun
if (security.isSandboxRequired()) {
fun = security.eval(`
const _status=window._status;
const lib=window.lib;
const game=window.game;
const ui=window.ui;
const get=window.get;
const ai=window.ai;
// const cheat=window.lib.cheat; // 不再允许使用 cheat因为它是不允许访问的变量
//使用正则匹配绝大多数的普通obj对象避免解析成代码块。
const reg=${/^\{([^{}]+:\s*([^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\)))(?:,\s*([^{}]+:\s*(?:[^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\))))*\}$/};
return function(value){
"use strict";
return eval(reg.test(value)?('('+value+')'):value);
};
`);
const reg = /^\{([^{}]+:\s*([^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\)))(?:,\s*([^{}]+:\s*(?:[^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\))))*\}$/;
fun = function (value) {
const exp = reg.test(value) ? `(${value})` : value;
const expName = "_" + Math.random().toString().slice(2);
return security.exec(`return eval(${expName})`, { window: proxyWindow, [expName]: exp });
};
// security.exec(`
// const _status=window._status;
// const lib=window.lib;
// const game=window.game;
// const ui=window.ui;
// const get=window.get;
// const ai=window.ai;
// // const cheat=window.lib.cheat; // 不再允许使用 cheat因为它是不允许访问的变量
// //使用正则匹配绝大多数的普通obj对象避免解析成代码块。
// const reg=${/^\{([^{}]+:\s*([^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\)))(?:,\s*([^{}]+:\s*(?:[^\s,]*|'[^']*'|"[^"]*"|\{[^}]*\}|\[[^\]]*\]|null|undefined|([a-zA-Z$_][a-zA-Z0-9$_]*\s*:\s*)?[a-zA-Z$_][a-zA-Z0-9$_]*\(\))))*\}$/};
// return function(value){
// "use strict";
// return eval(reg.test(value)?('('+value+')'):value);
// };
// `, { window: proxyWindow });
} else {
fun = (new Function('window', `
const _status=window._status;

View File

@ -3101,9 +3101,11 @@ class Sandbox {
/** @type {Document?} */
#domainDocument;
/** @type {typeof Object} */
#domainObject = Object;
#domainObject;
/** @type {typeof Function} */
#domainFunction = Function;
#domainFunction;
/** @type {typeof Function} */
#domainEval;
/**
* ```plain
@ -3128,9 +3130,10 @@ class Sandbox {
this.#domainDocument = null; // 默认不开放DOM而且我们也缺少BrowserContext
this.#domainObject = this.#domainWindow.Object;
this.#domainFunction = this.#domainWindow.Function;
this.#domainEval = this.#domainWindow.eval;
Sandbox.#domainMap.set(this.#domain, this);
Sandbox.#createScope(this);
Sandbox.#initDomainFunctions(this, this.#domainWindow);
Sandbox.#createScope(this);
}
/**
@ -3209,6 +3212,31 @@ class Sandbox {
rewriteCtor(defaultAsyncGeneratorFunction.prototype, new Proxy(defaultAsyncGeneratorFunction, handler));
}
/**
* ```plain
* 替代原本的eval函数阻止访问原生的 window 对象
* ```
*
* @param {Window} trueWindow
* @param {(x: string) => any} _eval
* @param {Proxy} intercepter
* @param {Window} global
* @param {any} x
*/
static #wrappedEval = function (trueWindow, _eval, intercepter, global, x) {
const intercepterName = Sandbox.#makeName("_", trueWindow);
const evalName = Sandbox.#makeName("_", global);
const codeName = Sandbox.#makeName("_", global);
trueWindow[intercepterName] = intercepter;
global[evalName] = _eval;
global[codeName] = x;
const result = _eval(`with(${intercepterName}){with(window){${evalName}("use strict;"+${codeName})}}`);
delete global[codeName];
delete global[evalName];
delete trueWindow[intercepterName];
return result;
}
/**
* ```plain
* 获取当前的scope
@ -3306,8 +3334,8 @@ class Sandbox {
* ```
*/
const builtins = {
Object: this.#domainObject,
Function: this.#domainFunction,
Object: this.#domainWindow.Object,
Function: this.#domainWindow.Function,
Array: this.#domainWindow.Array,
Math: this.#domainWindow.Math,
Date: this.#domainWindow.Date,
@ -3332,7 +3360,7 @@ class Sandbox {
Reflect: this.#domainWindow.Reflect,
BigInt: this.#domainWindow.BigInt,
JSON: this.#domainWindow.JSON,
eval: this.#domainWindow.eval,
// eval: this.#domainWindow.eval, // 我们另外定义 `eval` 函数
setTimeout: this.#domainWindow.setTimeout,
clearTimeout: this.#domainWindow.clearTimeout,
setInterval: this.#domainWindow.setInterval,
@ -3446,6 +3474,7 @@ class Sandbox {
const writeContextAction = { exists: 0, extend: 1, all: 2 }[writeContext] || 0;
let argumentList;
let wrappedEval;
const raw = new thiz.#domainFunction("_", `with(_){with(window){with(${contextName}){return(()=>{"use strict";return(${applyName}(function(${parameters}){\n// 沙盒代码起始\n${code}\n// 沙盒代码结束\n},${contextName}.this,${argsName}))})()}}}`);
@ -3473,8 +3502,12 @@ class Sandbox {
if (p === Symbol.unscopables)
return undefined;
if (!(p in target))
if (!(p in target)) {
if (p === "eval")
return wrappedEval; // 返回我们封装的 `eval` 函数
throw new domainWindow.ReferenceError(`${String(p)} is not defined`);
}
return target[p];
},
@ -3487,9 +3520,12 @@ class Sandbox {
},
});
wrappedEval = Sandbox.#wrappedEval.bind(null,
thiz.#domainWindow, thiz.#domainEval, intercepter, scope);
// 构建陷入的沙盒闭包
// 同时对返回值进行封送
return ((...args) => {
return ((/** @type {any} */ ...args) => {
const prevDomain = Domain.current;
const domainAction = () => {
// 指定执行域

View File

@ -2,7 +2,7 @@
// 但沙盒不会也没有办法维护恶意服务器/房主对于游戏规则的破坏,请玩家尽量选择官方或其他安全的服务器,同时选择一个受信任的玩家作为房主
// 是否强制所有模式下使用沙盒
const SANDBOX_FORCED = false;
const SANDBOX_FORCED = true;
// 是否启用自动测试
const SANDBOX_AUTOTEST = false;
// 是否禁用自动测试延迟