update laodeng

This commit is contained in:
geekgeekrun
2026-04-07 02:09:47 +08:00
parent 345d75ff98
commit eb90a825a0
2 changed files with 124 additions and 115 deletions

View File

@@ -1,125 +1,134 @@
"use strict";
const { PuppeteerExtraPlugin } = require("puppeteer-extra-plugin");
async function handle(p) {
await p.evaluateOnNewDocument(() => {
(() => {
"use strict";
/* -------------------------------------------------------
* 1. 保存原生 Function.prototype.toString
* ----------------------------------------------------- */
const nativeFunctionToString = Function.prototype.toString;
/* -------------------------------------------------------
* 2. WeakMap函数 → 伪原生源码
* ----------------------------------------------------- */
const nativeSourceMap = new WeakMap();
// 定义脚本内容,避免重复定义
const stealthScript = () => {
"use strict";
/* -------------------------------------------------------
* 1. 保存原生 Function.prototype.toString
* ----------------------------------------------------- */
const nativeFunctionToString = Function.prototype.toString;
/* -------------------------------------------------------
* 3. 注册伪原生源码
* ----------------------------------------------------- */
const registerNativeSource = (fn, source) => {
try {
nativeSourceMap.set(fn, source);
} catch (_) {}
};
/* -------------------------------------------------------
* 2. WeakMap函数 → 伪原生源码
* ----------------------------------------------------- */
const nativeSourceMap = new WeakMap();
/* -------------------------------------------------------
* 4. 劫持 Function.prototype.toString
* ----------------------------------------------------- */
Object.defineProperty(Function.prototype, "toString", {
configurable: true,
writable: true,
value: function toString() {
if (nativeSourceMap.has(this)) {
return nativeSourceMap.get(this);
}
return nativeFunctionToString.call(this);
},
});
/* -------------------------------------------------------
* 3. 注册伪原生源码
* ----------------------------------------------------- */
const registerNativeSource = (fn, source) => {
try {
nativeSourceMap.set(fn, source);
} catch (_) {}
};
/* -------------------------------------------------------
* 5. 伪装 Function.prototype.toString 自身
* ----------------------------------------------------- */
registerNativeSource(
Function.prototype.toString,
nativeFunctionToString.toString(),
);
/* -------------------------------------------------------
* 6. stealthify包装函数但保持“原生外观”
* ----------------------------------------------------- */
const stealthify = (obj, prop, handler) => {
const original = obj[prop];
if (typeof original !== "function") return;
const wrapped = function (...args) {
return handler.call(this, original, args);
};
const namePropertyDescriptor = Object.getOwnPropertyDescriptor(
wrapped,
"name",
);
// 处理函数 name 属性
Object.defineProperty(wrapped, "name", {
...namePropertyDescriptor,
value: prop,
});
// 保留 prototype某些函数有
try {
Object.setPrototypeOf(wrapped, Object.getPrototypeOf(original));
} catch (_) {}
// 注册伪原生源码(直接复用原函数的 native 表现)
registerNativeSource(wrapped, nativeFunctionToString.call(original));
// 用 defineProperty 保持 descriptor 接近原生
const desc = Object.getOwnPropertyDescriptor(obj, prop);
Object.defineProperty(obj, prop, {
...desc,
value: wrapped,
});
};
/* -------------------------------------------------------
* 7. 示例stealth console.log / debug / info
* ----------------------------------------------------- */
const filterConsoleArgs = (args) =>
args.map((arg) => {
if (arg && typeof arg === "object") {
// 防止 getter / Proxy / 大对象触发
return {};
}
return arg;
});
[
"log",
"debug",
"info",
"warn",
"error",
"dir",
"table",
"debug",
].forEach((name) => {
stealthify(console, name, (original, args) => {
// ❗不传递原始对象,避免 DevTools / CDP 展开
return original.apply(console, filterConsoleArgs(args));
});
});
/* -------------------------------------------------------
* 8. 防御性补丁(可选但强烈建议)
* ----------------------------------------------------- */
// 防止检测 toString 被替换
registerNativeSource(
registerNativeSource,
"function registerNativeSource() { [native code] }",
);
})();
/* -------------------------------------------------------
* 4. 劫持 Function.prototype.toString
* ----------------------------------------------------- */
Object.defineProperty(Function.prototype, "toString", {
configurable: true,
writable: true,
value: function toString() {
if (nativeSourceMap.has(this)) {
return nativeSourceMap.get(this);
}
return nativeFunctionToString.call(this);
},
});
/* -------------------------------------------------------
* 5. 伪装 Function.prototype.toString 自身
* ----------------------------------------------------- */
registerNativeSource(
Function.prototype.toString,
nativeFunctionToString.toString(),
);
/* -------------------------------------------------------
* 6. stealthify包装函数但保持"原生外观"
* ----------------------------------------------------- */
const stealthify = (obj, prop, handler) => {
const original = obj[prop];
if (typeof original !== "function") return;
const wrapped = function (...args) {
return handler.call(this, original, args);
};
const namePropertyDescriptor = Object.getOwnPropertyDescriptor(
wrapped,
"name",
);
// 处理函数 name 属性
Object.defineProperty(wrapped, "name", {
...namePropertyDescriptor,
value: prop,
});
// 保留 prototype某些函数有
try {
Object.setPrototypeOf(wrapped, Object.getPrototypeOf(original));
} catch (_) {}
// 注册伪原生源码(直接复用原函数的 native 表现)
registerNativeSource(wrapped, nativeFunctionToString.call(original));
// 用 defineProperty 保持 descriptor 接近原生
const desc = Object.getOwnPropertyDescriptor(obj, prop);
Object.defineProperty(obj, prop, {
...desc,
value: wrapped,
});
};
/* -------------------------------------------------------
* 7. 示例stealth console.log / debug / info
* ----------------------------------------------------- */
const filterConsoleArgs = (args) =>
args.map((arg) => {
if (arg && typeof arg === "object") {
// 防止 getter / Proxy / 大对象触发
return {};
}
return arg;
});
[
"log",
"debug",
"info",
"warn",
"error",
"dir",
"table",
"debug",
].forEach((name) => {
stealthify(console, name, (original, args) => {
// ❗不传递原始对象,避免 DevTools / CDP 展开
return original.apply(console, filterConsoleArgs(args));
});
});
/* -------------------------------------------------------
* 8. 防御性补丁(可选但强烈建议)
* ----------------------------------------------------- */
// 防止检测 toString 被替换
registerNativeSource(
registerNativeSource,
"function registerNativeSource() { [native code] }",
);
};
async function handle(p) {
// 1. 立即执行一次(针对当前已有的文档,防止错过)
try {
await p.evaluate(stealthScript);
} catch (e) {
// 如果当前页面还没准备好,忽略错误
}
// 2. 注册为新文档脚本(针对未来的导航)
await p.evaluateOnNewDocument(stealthScript);
}
class Plugin extends PuppeteerExtraPlugin {

View File

@@ -1,6 +1,6 @@
{
"name": "@geekgeekrun/puppeteer-extra-plugin-laodeng",
"version": "0.0.1",
"version": "0.0.2",
"description": "laodeng",
"main": "./index.js",
"author": "geekgeekrun",