Manga Reader: lector web autoalojado con modo libro 3D y estante

This commit is contained in:
Nino
2026-11-06 09:42:34 -06:00
commit e40127265f
45 changed files with 12822 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
// Extrae la clave con la que M440 cifra su lista de capítulos. La clave está repartida en trozos dentro de
// un script ofuscado (js/ads2.js) que llama a CryptoJS.AES.decrypt(datos, clave, …). En vez de
// desofuscarlo, se ejecuta en un contexto vm vacío con un CryptoJS falso que solo anota la clave.
//
// Se lanza como proceso aparte con el modelo de permisos de Node (sin acceso a archivos salvo este, sin
// procesos hijo ni workers) y con tiempo límite. Dentro del vm no se pasa ningún objeto del proceso
// (todo se define con código dentro del contexto) y la generación de código desde strings está
// desactivada, así que el script no puede alcanzar process ni require.
// Entrada: el script por stdin. Salida: {"key": "..."} por stdout.
import vm from 'node:vm'
let src = ''
process.stdin.setEncoding('utf8')
for await (const chunk of process.stdin) {
src += chunk
if (src.length > 2e6) process.exit(2)
}
const ctx = vm.createContext({}, { codeGeneration: { strings: false, wasm: false } })
vm.runInContext(`
var __key = null;
var window = globalThis, self = globalThis;
var UsaPoncho = '{"ct":"AAAA","iv":"00","s":"00"}';
function mk() {
return new Proxy(function () {}, {
get: function (t, k) {
if (k === Symbol.toPrimitive) return function () { return '' };
if (k === 'toString') return function () { return '[]' };
return mk();
},
apply: function () { return mk() },
construct: function () { return mk() },
});
}
var document = mk(), $ = mk(), jQuery = $, localStorage = mk(), sessionStorage = mk();
var navigator = { userAgent: 'Mozilla/5.0', language: 'es' }, location = { href: 'https://m440.in/', hostname: 'm440.in' };
var setTimeout = function () {}, setInterval = function () {}, clearTimeout = function () {}, clearInterval = function () {};
var console = { log: function () {}, warn: function () {}, error: function () {}, info: function () {}, debug: function () {}, trace: function () {}, table: function () {}, exception: function () {} };
var id = function (s) { return s };
var CryptoJS = {
AES: {
decrypt: function (c, k) { if (__key === null) __key = String(k); return { toString: function () { return '"[]"' } } },
encrypt: mk(),
},
enc: { Utf8: { parse: id, stringify: id }, Hex: { parse: id, stringify: id }, Base64: { parse: id, stringify: id } },
lib: { CipherParams: { create: id }, WordArray: { create: id } },
format: { OpenSSL: {} },
};
`, ctx)
try {
vm.runInContext(src, ctx, { timeout: 5000 })
} catch {}
const key = vm.runInContext('typeof __key === "string" ? __key : ""', ctx)
process.stdout.write(JSON.stringify({ key: typeof key === 'string' ? key.slice(0, 200) : '' }))
process.exit(0)