reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,261 @@
const { scaffoldModule } = require("./scaffold-module");
const { buildPluginGraph } = require("./build-plugin-graph");
function clone(value) {
return JSON.parse(JSON.stringify(value || {}));
}
function normalizeNavigatorSeed(seed = {}) {
const navigatorSeed = seed.navigator && typeof seed.navigator === "object" ? seed.navigator : seed;
const plugins = Array.isArray(seed.plugins) ? clone(seed.plugins) : [];
const mimeTypes = Array.isArray(seed.mimeTypes) ? clone(seed.mimeTypes) : [];
return {
navigator: {
userAgent: navigatorSeed.userAgent || "",
platform: navigatorSeed.platform || "",
vendor: navigatorSeed.vendor || "",
language: navigatorSeed.language || "",
languages: Array.isArray(navigatorSeed.languages) ? navigatorSeed.languages.slice() : [],
webdriver: typeof navigatorSeed.webdriver === "boolean" ? navigatorSeed.webdriver : false,
hardwareConcurrency: Number.isFinite(navigatorSeed.hardwareConcurrency)
? navigatorSeed.hardwareConcurrency
: 8,
deviceMemory: Number.isFinite(navigatorSeed.deviceMemory) ? navigatorSeed.deviceMemory : 8,
maxTouchPoints: Number.isFinite(navigatorSeed.maxTouchPoints) ? navigatorSeed.maxTouchPoints : 0,
cookieEnabled: navigatorSeed.cookieEnabled !== false,
pdfViewerEnabled: navigatorSeed.pdfViewerEnabled !== false,
appCodeName: navigatorSeed.appCodeName || "Mozilla",
appName: navigatorSeed.appName || "Netscape",
appVersion: navigatorSeed.appVersion || navigatorSeed.userAgent || "",
userAgentData: clone(seed.userAgentData || navigatorSeed.userAgentData || null),
connection: clone(seed.connection || navigatorSeed.connection || null),
},
plugins,
mimeTypes,
battery: clone(seed.battery || null),
};
}
function renderNavigatorPatch(seed) {
const serializedSeed = JSON.stringify(seed, null, 2);
return `(
function installNavigatorModule(globalObject) {
const seed = ${serializedSeed};
const protector = globalObject.__envNativeProtector || null;
const pluginSeed = Array.isArray(seed.plugins) ? seed.plugins.slice() : [];
const mimeSeed = Array.isArray(seed.mimeTypes) ? seed.mimeTypes.slice() : [];
function defineValue(target, key, value) {
Object.defineProperty(target, key, {
configurable: true,
enumerable: false,
writable: true,
value: value
});
}
function defineGetter(target, key, getter) {
Object.defineProperty(target, key, {
configurable: true,
enumerable: false,
get: getter
});
if (protector && protector.protectDescriptor) {
protector.protectDescriptor(target, key);
}
}
function createIndexedCollection(items, namedKey) {
const collection = {};
for (let index = 0; index < items.length; index += 1) {
Object.defineProperty(collection, index, {
configurable: true,
enumerable: false,
writable: false,
value: items[index]
});
if (items[index] && items[index][namedKey]) {
Object.defineProperty(collection, items[index][namedKey], {
configurable: true,
enumerable: false,
writable: false,
value: items[index]
});
}
}
defineValue(collection, "length", items.length);
defineValue(collection, "item", function item(index) {
return items[index] || null;
});
defineValue(collection, "namedItem", function namedItem(name) {
return items.find(function findItem(entry) {
return entry && entry[namedKey] === name;
}) || null;
});
defineValue(collection, "refresh", function refresh() {});
return collection;
}
const pluginArray = pluginSeed.map(function mapPlugin(plugin) {
return {
name: plugin.name || "",
filename: plugin.filename || "",
description: plugin.description || "",
length: 0
};
});
const mimeTypeArray = mimeSeed.map(function mapMime(mime) {
return {
type: mime.type || "",
suffixes: mime.suffixes || "",
description: mime.description || "",
enabledPlugin: null
};
});
for (let index = 0; index < mimeSeed.length; index += 1) {
const pluginName = mimeSeed[index].enabledPluginName || "";
const plugin = pluginArray.find(function findPlugin(entry) {
return entry.name === pluginName;
}) || null;
mimeTypeArray[index].enabledPlugin = plugin;
if (plugin) {
const itemIndex = plugin.length;
Object.defineProperty(plugin, itemIndex, {
configurable: true,
enumerable: false,
writable: false,
value: mimeTypeArray[index]
});
plugin.length += 1;
}
}
const plugins = createIndexedCollection(pluginArray, "name");
const mimeTypes = createIndexedCollection(mimeTypeArray, "type");
function Navigator() {}
const navigatorState = seed.navigator || {};
const navigatorInstance = Object.create(Navigator.prototype);
const scalarKeys = [
"userAgent",
"platform",
"vendor",
"language",
"webdriver",
"hardwareConcurrency",
"deviceMemory",
"maxTouchPoints",
"cookieEnabled",
"pdfViewerEnabled",
"appCodeName",
"appName",
"appVersion"
];
scalarKeys.forEach(function defineScalar(key) {
defineGetter(Navigator.prototype, key, function getScalar() {
return navigatorState[key];
});
});
defineGetter(Navigator.prototype, "languages", function getLanguages() {
return Array.isArray(navigatorState.languages) ? navigatorState.languages.slice() : [];
});
defineGetter(Navigator.prototype, "plugins", function getPlugins() {
return plugins;
});
defineGetter(Navigator.prototype, "mimeTypes", function getMimeTypes() {
return mimeTypes;
});
defineGetter(Navigator.prototype, "userAgentData", function getUserAgentData() {
return navigatorState.userAgentData || null;
});
defineGetter(Navigator.prototype, "connection", function getConnection() {
return navigatorState.connection || null;
});
defineValue(Navigator.prototype, "javaEnabled", function javaEnabled() {
return false;
});
defineValue(Navigator.prototype, "getBattery", function getBattery() {
return Promise.resolve(seed.battery || {
charging: true,
chargingTime: 0,
dischargingTime: Infinity,
level: 1
});
});
if (protector && protector.repairFunctionMeta) {
protector.repairFunctionMeta(Navigator, { name: "Navigator", length: 0 });
protector.repairFunctionMeta(Navigator.prototype.javaEnabled, { name: "javaEnabled", length: 0 });
protector.repairFunctionMeta(Navigator.prototype.getBattery, { name: "getBattery", length: 0 });
}
if (protector && protector.protectFunction) {
protector.protectFunction(Navigator, "Navigator");
protector.protectFunction(Navigator.prototype.javaEnabled, "javaEnabled");
protector.protectFunction(Navigator.prototype.getBattery, "getBattery");
}
defineValue(navigatorInstance, Symbol.toStringTag, "Navigator");
Object.defineProperty(globalObject, "Navigator", {
configurable: true,
enumerable: false,
writable: true,
value: Navigator
});
Object.defineProperty(globalObject, "navigator", {
configurable: true,
enumerable: false,
writable: true,
value: navigatorInstance
});
return navigatorInstance;
})(typeof globalThis !== "undefined" ? globalThis : window);
`;
}
function buildNavigatorModule(seed = {}) {
const module = scaffoldModule("navigator-module");
const normalizedSeed = normalizeNavigatorSeed(seed);
const pluginGraph = buildPluginGraph({
plugins: normalizedSeed.plugins,
mimeTypes: normalizedSeed.mimeTypes,
});
module.patchPlan = [
"构建 Navigator 构造器、prototype 和 navigator 实例。",
"把 userAgent/language/webdriver 等高频字段补成 prototype getter,而不是直接灌到实例上。",
"把 plugins/mimeTypes 构造成类数组图结构,并补 getBattery/userAgentData 等高频检测点。",
];
module.patchCode = renderNavigatorPatch(normalizedSeed);
module.runtimeState = {
navigator: normalizedSeed.navigator,
plugins: pluginGraph.pluginArray,
mimeTypes: pluginGraph.mimeTypeArray,
battery: normalizedSeed.battery,
};
module.validation = [
"检查 navigator.webdriver === false。",
"检查 navigator.plugins.length 与 navigator.mimeTypes.length。",
"检查 navigator.plugins.item(0) / namedItem(name) 与 mimeTypes.enabledPlugin 关系。",
"检查 navigator.getBattery() 返回 Promise。",
"检查 Navigator.prototype 上 getter 的描述符与 toString 保护是否生效。",
];
module.residualRisk = [
"这里只覆盖常见字段与图结构,未实现 permissions、mediaDevices、bluetooth 等更深层能力对象。",
"如果目标脚本会校验 brands/mobile/platformVersion 等 userAgentData 细节,仍需真实浏览器种子。",
];
return module;
}
module.exports = {
buildNavigatorModule,
normalizeNavigatorSeed,
};