mirror of
https://github.com/bnmgh1/NodeSandbox.git
synced 2025-04-12 03:36:56 +08:00
441 lines
22 KiB
JavaScript
441 lines
22 KiB
JavaScript
(function () {
|
|
cbb_wf = {};
|
|
cbb_wf.code = "";
|
|
cbb_wf.init_proto_code = "";
|
|
cbb_wf.symbol_code = ""
|
|
cbb_wf.constructor_code = "";
|
|
cbb_wf.func = [];
|
|
|
|
cbb_wf.object_code = ""
|
|
// 接下来写的就是脱环境的了
|
|
let jsdom_function = ["DOMException", "URL", "webkitURL", "URLSearchParams", "EventTarget", "NamedNodeMap", "Node", "Attr", "Element", "DocumentFragment", "DOMImplementation", "Document", "XMLDocument", "CharacterData", "Text", "CDATASection", "ProcessingInstruction", "Comment", "DocumentType", "NodeList", "RadioNodeList", "HTMLCollection", "HTMLOptionsCollection", "DOMStringMap", "DOMTokenList", "StyleSheetList", "HTMLElement", "HTMLHeadElement", "HTMLTitleElement", "HTMLBaseElement", "HTMLLinkElement", "HTMLMetaElement", "HTMLStyleElement", "HTMLBodyElement", "HTMLHeadingElement", "HTMLParagraphElement", "HTMLHRElement", "HTMLPreElement", "HTMLUListElement", "HTMLOListElement", "HTMLLIElement", "HTMLMenuElement", "HTMLDListElement", "HTMLDivElement", "HTMLAnchorElement", "HTMLAreaElement", "HTMLBRElement", "HTMLButtonElement", "HTMLCanvasElement", "HTMLDataElement", "HTMLDataListElement", "HTMLDetailsElement", "HTMLDialogElement", "HTMLDirectoryElement", "HTMLFieldSetElement", "HTMLFontElement", "HTMLFormElement", "HTMLHtmlElement", "HTMLImageElement", "HTMLInputElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLMapElement", "HTMLMarqueeElement", "HTMLMediaElement", "HTMLMeterElement", "HTMLModElement", "HTMLOptGroupElement", "HTMLOptionElement", "HTMLOutputElement", "HTMLPictureElement", "HTMLProgressElement", "HTMLQuoteElement", "HTMLScriptElement", "HTMLSelectElement", "HTMLSlotElement", "HTMLSourceElement", "HTMLSpanElement", "HTMLTableCaptionElement", "HTMLTableCellElement", "HTMLTableColElement", "HTMLTableElement", "HTMLTimeElement", "HTMLTableRowElement", "HTMLTableSectionElement", "HTMLTemplateElement", "HTMLTextAreaElement", "HTMLUnknownElement", "HTMLFrameElement", "HTMLFrameSetElement", "HTMLIFrameElement", "HTMLEmbedElement", "HTMLObjectElement", "HTMLParamElement", "HTMLVideoElement", "HTMLAudioElement", "HTMLTrackElement", "HTMLFormControlsCollection", "SVGElement", "SVGGraphicsElement", "SVGSVGElement", "SVGTitleElement", "SVGAnimatedString", "SVGNumber", "SVGStringList", ];
|
|
// 过滤掉不需要
|
|
let filter_key = ["Object", "Function", "Array", "Number", "parseFloat", "parseInt", "Infinity", "NaN", "undefined", "Boolean", "String", "Symbol", "Date", "Promise", "RegExp", "Error", "AggregateError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "globalThis", "JSON", "Math", "Intl", "ArrayBuffer", "Uint8Array", "Int8Array", "Uint16Array", "Int16Array", "Uint32Array", "Int32Array", "Float32Array", "Float64Array", "Uint8ClampedArray", "BigUint64Array", "BigInt64Array", "DataView", "Map", "BigInt", "Set", "WeakMap", "WeakSet", "Proxy", "Reflect", "FinalizationRegistry", "WeakRef", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "escape", "unescape", "eval", "isFinite", "isNaN", "console", "SharedArrayBuffer", "Atomics", "WebAssembly"]
|
|
let desp = Object.getOwnPropertyDescriptors(this);
|
|
for (let key in desp) {
|
|
if (filter_key.indexOf(key) > -1) continue;
|
|
if (typeof this[key] == "function" && "prototype" in this[key]) {
|
|
// dump_static_env(key);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
function dump_function_env(func_name) {
|
|
// 构造函数也会拥有函数. 比如URL
|
|
let desp = Object.getOwnPropertyDescriptors(this[func_name]);
|
|
let x = ["prototype", "arguments", "length", "name", "caller"];
|
|
let code = ""
|
|
for (let key in desp) {
|
|
if (x.indexOf(key) > -1) continue;
|
|
if (typeof desp[key].value == "function") {
|
|
// 要不要区分下是不是jsdom里的
|
|
code += `this.${func_name}_${key} = function () {
|
|
let r = cbb_wf.checkIllegal(this, "${func_name}");
|
|
let ctx = r[0];
|
|
let result;
|
|
if (cbb_wf.is_log) {
|
|
// 函数没补, 原来的静态代码, 没有动过
|
|
let info = "";
|
|
if (!result) {
|
|
info = ". 暂时未处理"
|
|
}
|
|
console.log("[*] ${func_name}_${key}, this =>", this + '', ", arguments =>", arguments, ", result =>", result + '', info);
|
|
}
|
|
return result;
|
|
|
|
}` + '\n'
|
|
}
|
|
}
|
|
cbb_wf.code += code;
|
|
|
|
}
|
|
|
|
function dump_static_env(func_name) {
|
|
// set __proto__ 代码脱下来
|
|
let function_name = this[func_name].name;
|
|
if (func_name !== function_name) {
|
|
// console.log(func_name, function_name);
|
|
return;
|
|
}
|
|
cbb_wf.func.push(func_name);
|
|
dump_constructor(func_name);
|
|
dump_function_env(func_name);
|
|
// return;
|
|
if (!function_name) {
|
|
debugger;
|
|
}
|
|
let proto = this[function_name].__proto__;
|
|
let proto_func_name = proto.name;
|
|
if (this[function_name].prototype[Symbol.iterator]) {
|
|
cbb_wf.symbol_code += `Object.defineProperty(this.${function_name}.prototype, Symbol.iterator, desp1);` + '\n'
|
|
} else if (this[function_name].prototype[Symbol.unscopables]) {
|
|
cbb_wf.symbol_code += `Object.defineProperty(this.${function_name}.prototype, Symbol.unscopables, desp2);` + '\n'
|
|
}
|
|
if (proto_func_name == '') {
|
|
// 跳过
|
|
}
|
|
else {
|
|
let prototype_func_name = this[func_name].prototype.__proto__[Symbol.toStringTag];
|
|
if (prototype_func_name !== proto_func_name) debugger;
|
|
cbb_wf.init_proto_code += `this.${function_name}.__proto__ = this.${proto_func_name};
|
|
this.${function_name}.prototype.__proto__ = this.${proto_func_name}.prototype;` + '\n';
|
|
}
|
|
|
|
|
|
|
|
let code = "";
|
|
let desp = Object.getOwnPropertyDescriptors(this[func_name].prototype);
|
|
for (let key in desp) {
|
|
if (key === "constructor") continue
|
|
if (jsdom_function.indexOf(func_name) > -1) {
|
|
// 走jsdom脱环境那一套
|
|
if ("get" in desp[key]) {
|
|
code += `this.${function_name}_get_${key} = function () {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
// 获取到jsdom对象
|
|
let dom_element = cbb_wf.getValue(this, "dom_element");
|
|
let result = dom_element.${key};
|
|
let type = typeof result;
|
|
switch (type) {
|
|
case "object":
|
|
// 套壳
|
|
// result[Symbol.toStringTag]
|
|
console.log("[*] ${function_name}_get_${key} 得到的结果类型为Object, result =>", result);
|
|
result = result && ctx.my_api.getWrapperObject(result);
|
|
break
|
|
|
|
case "function":
|
|
console.log("[*] ${function_name}_get_${key} 得到的结果类型为function, result =>", result);
|
|
break
|
|
case "number":
|
|
result.__proto__ = ctx.Number.prototype;
|
|
break
|
|
case "string":
|
|
result.__proto__ = ctx.String.prototype;
|
|
break
|
|
case "boolean":
|
|
result.__proto__ = ctx.Boolean.prototype;
|
|
break
|
|
default:
|
|
// string number
|
|
console.log("[*] ${function_name}_get_${key} 得到的结果类型没有处理, type =>", type, ", result =>", result);
|
|
break
|
|
}
|
|
if (cbb_wf.is_log) {
|
|
// 函数没补, 原来的静态代码, 没有动过
|
|
let info = "";
|
|
if (!result) {
|
|
info = ". 暂时未处理"
|
|
}
|
|
console.log("[*] ${function_name}_get_${key}, this =>", this + '', ", result =>", result + '', info);
|
|
}
|
|
return result;
|
|
}` + '\n';
|
|
|
|
if (desp[key].set) {
|
|
// 有值说明才有set函数
|
|
code += `this.${function_name}_set_${key} = function (val) {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
// 获取到jsdom对象
|
|
let dom_element = cbb_wf.getValue(this, "dom_element");
|
|
dom_element.${key} = val;
|
|
if (cbb_wf.is_log) {
|
|
console.log("[*] ${function_name}_set_${key}, this =>", this + '', ", val =>", val + '', ". 暂时未处理");
|
|
}
|
|
}` + '\n';
|
|
}
|
|
}
|
|
else {
|
|
if (typeof desp[key].value === "function") {
|
|
code += `this.${function_name}_${key} = function () {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
// 获取到jsdom对象
|
|
let dom_element = cbb_wf.getValue(this, "dom_element");
|
|
let result = dom_element.${key}.apply(dom_element, arguments);
|
|
let type = typeof result;
|
|
switch (type) {
|
|
case "object":
|
|
// 套壳
|
|
console.log("[*] ${function_name}_${key} 得到的结果类型为Object, result =>", result);
|
|
result = result && ctx.my_api.getWrapperObject(result);
|
|
break
|
|
|
|
case "function":
|
|
console.log("[*] ${function_name}_${key} 得到的结果类型为function, result =>", result);
|
|
break
|
|
case "number":
|
|
result.__proto__ = ctx.Number.prototype;
|
|
break
|
|
case "string":
|
|
result.__proto__ = ctx.String.prototype;
|
|
break
|
|
case "boolean":
|
|
result.__proto__ = ctx.Boolean.prototype;
|
|
break
|
|
default:
|
|
// string number
|
|
console.log("[*] ${function_name}_${key} 得到的结果类型没有处理, type =>", type, ", result =>", result);
|
|
break
|
|
}
|
|
if (cbb_wf.is_log) {
|
|
let info = "";
|
|
if (!result) {
|
|
info = ". 暂时未处理"
|
|
}
|
|
console.log("[*] ${function_name}_${key}, this =>", this + '', ", arguments =>", arguments, ", result =>", result + '', info);
|
|
}
|
|
return result;
|
|
}
|
|
` + '\n'
|
|
}
|
|
// number之类的
|
|
}
|
|
}
|
|
else {
|
|
// 走正常脱环境那一套
|
|
if ("get" in desp[key]) {
|
|
code += `this.${function_name}_get_${key} = function () {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
let result = cbb_wf.getValue(this, "${key}");
|
|
if (cbb_wf.is_log) {
|
|
// 函数没补, 原来的静态代码, 没有动过
|
|
let info = "";
|
|
if (!result) {
|
|
info = ". 暂时未处理"
|
|
}
|
|
console.log("[*] ${function_name}_get_${key}, this =>", this + '', ", result =>", result + '', info);
|
|
}
|
|
return result;
|
|
}
|
|
` + '\n'
|
|
if (desp[key].set) {
|
|
code += `this.${function_name}_set_${key} = function (val) {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
cbb_wf.setValue(this, "${key}", val);
|
|
if (cbb_wf.is_log) {
|
|
console.log("[*] ${function_name}_set_${key}, this =>", this + '', ", val =>", val + '', ". 暂时未处理");
|
|
}
|
|
return;
|
|
}` + '\n'
|
|
}
|
|
}
|
|
else {
|
|
if (typeof desp[key].value === "function") {
|
|
code += `this.${function_name}_${key} = function () {
|
|
// 非法调用
|
|
let r = cbb_wf.checkIllegal(this, "${function_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
// 没有功能
|
|
let result;
|
|
if (cbb_wf.is_log) {
|
|
// 函数没补, 原来的静态代码, 没有动过
|
|
console.log("[*] ${function_name}_${key}, this =>", this + '', ", arguments =>", arguments, ", result =>", result + '', '. 暂时未处理');
|
|
}
|
|
return result;
|
|
|
|
}` + '\n'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cbb_wf.code += code;
|
|
}
|
|
|
|
function dump_object_env(obj, name) {
|
|
let code = "";
|
|
let proto_name = obj.__proto__[Symbol.toStringTag];
|
|
if (!proto_name) {
|
|
debugger;
|
|
}
|
|
// 可能是window, location
|
|
let desc = Object.getOwnPropertyDescriptors(obj);
|
|
let is_log_str = "";
|
|
if (obj == window) {
|
|
is_log_str = "is_log_window";
|
|
} else is_log_str = "is_log";
|
|
for (let key in desc) {
|
|
if (filter_key.indexOf(key) > -1) continue;
|
|
if ("get" in desc[key]) {
|
|
|
|
code += `this.${name}_get_${key} = function () {
|
|
let r = cbb_wf.checkIllegal(this, "${proto_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
let result = cbb_wf.getValue(this, "${key}");
|
|
if (cbb_wf.${is_log_str}) {
|
|
cbb_wf.console.log("[*] ${name}_get_${key}, this =>", this + '', ", result => ", result + '');
|
|
}
|
|
return result;
|
|
}` + '\n'
|
|
if (desc[key].set) {
|
|
code += `this.${name}_set_${key} = function (val) {
|
|
let r = cbb_wf.checkIllegal(this, "${proto_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
let result = cbb_wf.setValue(this, "${key}", val);
|
|
if (cbb_wf.${is_log_str}) {
|
|
cbb_wf.console.log("[*] ${name}_set_${key}, this =>", this + '', ", val => ", val + '');
|
|
}
|
|
return result;
|
|
}` + '\n'
|
|
}
|
|
}
|
|
else {
|
|
if (typeof obj[key] === "function") {
|
|
if (obj == window && !("prototype" in obj[key])) {
|
|
// window下的构造函数 我们不能重复脱, setTimeout 普通函数
|
|
code += `this.${name}_${key} = function(){
|
|
let r = cbb_wf.checkIllegal(this, "${proto_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
let result;
|
|
if (cbb_wf.is_log_window) {
|
|
cbb_wf.console.log("[*] ${name}_${key}, this =>", this + '', ", arguments => ", arguments, ", result => ", result + '', ".暂未实现");
|
|
}
|
|
return result;
|
|
}` + '\n'
|
|
}
|
|
else if ("prototype" in obj[key]) {
|
|
// 几乎没有,我没遇到过
|
|
debugger;
|
|
}
|
|
else {
|
|
// 普通函数
|
|
code += `this.${name}_${key} = function(){
|
|
let r = cbb_wf.checkIllegal(this, "${proto_name}");
|
|
let ctx = r[0];
|
|
if (r[1]) {
|
|
// 报错
|
|
throw cbb_wf.newError.call(ctx, "Illegal invocation");
|
|
}
|
|
let result;
|
|
if (cbb_wf.is_log) {
|
|
cbb_wf.console.log("[*] ${name}_${key}, this =>", this + '', ", arguments => ", arguments, ", result => ", result + '', ".暂未实现");
|
|
}
|
|
return result;
|
|
}` + '\n'
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
cbb_wf.object_code += code;
|
|
}
|
|
|
|
|
|
function dump_constructor(func_name) {
|
|
let call_err_message = '';
|
|
let arg_less_length = '';
|
|
try {
|
|
this[func_name]();
|
|
// 构造函数能直接调用
|
|
debugger;
|
|
}
|
|
catch (e) {
|
|
// console.log(e.message);
|
|
call_err_message = e.message;
|
|
}
|
|
|
|
try {
|
|
new this[func_name]();
|
|
// 如果不报错, 说明可以直接被new
|
|
arg_less_length = '';
|
|
}
|
|
catch (e) {
|
|
console.log(e.message);
|
|
// 可能是能new, 但是传参不够
|
|
arg_less_length = e.message;
|
|
}
|
|
let code = '';
|
|
if (arg_less_length.indexOf("argument required, but only") > -1) {
|
|
let arg_length = arg_less_length.split(" argument")[0].split(": ")[1];
|
|
code = `this.${func_name} = this.${func_name} || function ${func_name}(){
|
|
// 如果是直接调用函数的话 new.target为undefined
|
|
if (!new.target) {
|
|
throw new TypeError("${call_err_message}");
|
|
}
|
|
if (arguments.length < ${arg_length}) {
|
|
throw new TypeError("${arg_less_length}".replace('0', arguments.length));
|
|
}
|
|
cbb_wf.console.log("[*] new ${func_name}, arguments =>", arguments);
|
|
return this;
|
|
}`
|
|
}
|
|
else {
|
|
if (arg_less_length == '') {
|
|
code = `this.${func_name} = this.${func_name} || function ${func_name}(){
|
|
// 如果是直接调用函数的话 new.target为undefined
|
|
if (!new.target) {
|
|
throw new TypeError("${call_err_message}");
|
|
}
|
|
cbb_wf.console.log("[*] new ${func_name}, arguments =>", arguments);
|
|
return this;
|
|
}`
|
|
} else {
|
|
code = `this.${func_name} = this.${func_name} || function ${func_name}(){
|
|
// 如果是直接调用函数的话 new.target为undefined
|
|
if (!new.target) {
|
|
throw new TypeError("${call_err_message}");
|
|
}
|
|
cbb_wf.console.log("[*] new ${func_name}, arguments =>", arguments);
|
|
throw new TypeError("${arg_less_length}");
|
|
return this;
|
|
}`
|
|
}
|
|
|
|
}
|
|
|
|
cbb_wf.constructor_code += code + '\n' + `cbb_wf.setNative(this.${func_name});` + '\n';
|
|
|
|
}
|
|
|
|
|
|
// dump_object_env(location, "location");
|
|
dump_object_env(window, "window");
|
|
})() |