您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Partially deobfuscate the code
// ==UserScript== // @name Bonk Deobfuscator // @version 0.2 // @description Partially deobfuscate the code // @author KOOKY WARRIOR // @license MIT // @match https://bonk.io/gameframe-release.html // @require https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify.min.js // @grant none // @run-at document-end // @namespace https://greasyfork.org/users/999838 // ==/UserScript== /* This code can only **PARTIALLY** deobfuscate the alpha2.js and save as a .js file **TIPS: Disable this userscript once you have obtained the deobfuscated code** */ function log(text) { console.log(`[Bonk Deobfuscator] ${text}`) } const url = "https://bonk.io/js/alpha2s.js" log("Fetching " + url) fetch(url) .then((response) => response.text()) .then((response) => { log("Deobfuscation started") function noDuplicate(array) { return [...new Set(array)] } function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") } let tmp log("Unminifing the code") const splitedText = js_beautify(response, { e4x: true }).split("requirejs") log("Setting up main variables") const MAINFUNCTION = splitedText[0].match(/[^\[]+/)[0] const MAINARRAY = splitedText[0].match(/^var ([^=^\s]+);/m)[1] log(`eval ${MAINFUNCTION} function`) eval(`var ${MAINFUNCTION};${response.split("requestjs")[0]}`) let returncode = `requirejs${splitedText[1]}` log(`Replacing "var a = ${MAINFUNCTION}; a.bcd(123)" to "${MAINFUNCTION}.bcd(123)"`) tmp = returncode.match(new RegExp(`var (\\S+) = ${escapeRegExp(MAINFUNCTION)};`, ""))[1] returncode = returncode.replaceAll(`${tmp}.`, `${MAINFUNCTION}.`) log(`Replacing all duplicate functions`) tmp = [...splitedText[0].matchAll(new RegExp(`(?<v>${escapeRegExp(MAINFUNCTION)}\\.[\\S]+) = (?<f>function\\(\\) \\{.+?};)`, "gs"))] let VARIABLES = tmp.map((m) => m.groups.v) let FUNCTIONS = tmp.map((m) => m.groups.f) let indices = {} for (let i = 0; i < FUNCTIONS.length; i++) { if (!indices[FUNCTIONS[i]]) { indices[FUNCTIONS[i]] = [] } indices[FUNCTIONS[i]].push(i) } for (const key in indices) { const element = indices[key] for (let i = 0; i < element.length; i++) { splitedText[0] = splitedText[0].replaceAll(VARIABLES[element[i]], VARIABLES[element[0]]) returncode = returncode.replaceAll(VARIABLES[element[i]], VARIABLES[element[0]]) } } log(`Replacing math operation`) const OPERATIONEQUALVARIABLE = /case 0:\n\s+(\S+) = .+\n.+break;/gm.exec(splitedText[0])[1] tmp = new RegExp( `return {\\s+(\\S+): function\\(\\) {\\s+var ${escapeRegExp(OPERATIONEQUALVARIABLE)}, (.+) = arguments;\\s+switch \\((.+)\\)`, "gm" ).exec(splitedText[0]) const OPERATIONFUNCTION = new RegExp(`(${escapeRegExp(MAINFUNCTION)}\\....) = function\\(\\) {\\s+return.+${tmp[1]}`, "gm").exec(splitedText[0])[1] const OPERATIONFUNCTIONSETTER = new RegExp( `(${escapeRegExp(MAINFUNCTION)}\\....) = function\\(\\) {\\s+return.+${escapeRegExp( new RegExp(`,\\s+(\\S+): function.+\\s+${escapeRegExp(tmp[3])} =`, "gm").exec(splitedText[0])[1] )}`, "gm" ).exec(splitedText[0])[1] const OPERATIONARGUMENTVARIABLE = escapeRegExp(tmp[2]) tmp = returncode.match( new RegExp( `${escapeRegExp(OPERATIONFUNCTION)}\\((?:[^)(]|\\((?:[^)(]|\\((?:[^)(]|\\([^)(]*\\))*\\))*\\))*\\)|${escapeRegExp( OPERATIONFUNCTIONSETTER )}\\(\\d+\\)`, "g" ) ) // FUNCTION\((?:[^)(]|\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\))*\) var OPERATIONFUNCTIONSETTERVALUE = 0 for (let i = 0; i < tmp.length; i++) { const element = tmp[i] if (element.includes(OPERATIONFUNCTION)) { const args = element.replace(`${OPERATIONFUNCTION}(`, "").replace(/.$/, "").replace(/\s/g, "").split(",") if (args[args.length - 1].includes(OPERATIONFUNCTIONSETTER)) { OPERATIONFUNCTIONSETTERVALUE = parseInt(new RegExp(`${escapeRegExp(OPERATIONFUNCTIONSETTER)}\\((\\d+)\\)`).exec(args[args.length - 1])[1]) args.pop() } var value = new RegExp(`case ${OPERATIONFUNCTIONSETTERVALUE}:\\n\\s+${escapeRegExp(OPERATIONEQUALVARIABLE)} = (.+);\\n.+break;`, "gm").exec( splitedText[0] )[1] for (let j = 0; j < args.length; j++) { value = value.replaceAll(`${OPERATIONARGUMENTVARIABLE}[${j}]`, args[j]) } try { value = eval(value) } catch (error) { } finally { returncode = returncode.replace(element, value) } } else { OPERATIONFUNCTIONSETTERVALUE = parseInt(new RegExp(`${escapeRegExp(OPERATIONFUNCTIONSETTER)}\\((\\d+)\\)`).exec(element)[1]) } } const ARRAYFUNCTION = new RegExp(`${escapeRegExp(MAINARRAY)} = .+?(${escapeRegExp(MAINFUNCTION)}\\....)`, "").exec(splitedText[0])[1] log(`Replacing "${ARRAYFUNCTION}(123)" to "real data"`) tmp = noDuplicate(returncode.match(new RegExp(`${escapeRegExp(ARRAYFUNCTION)}\\((?:[^)(]|\\((?:[^)(]|\\((?:[^)(]|\\([^)(]*\\))*\\))*\\))*\\)`, "g"))) for (let i = 0; i < tmp.length; i++) { const element = tmp[i] try { returncode = returncode.replaceAll(element, `"${eval(element).replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/"/g, '\\"')}"`) } catch (error) { const args = element.replace(`${ARRAYFUNCTION}(`, "").replace(/.$/, "") const value = parseInt(new RegExp(`${escapeRegExp(args)} = (\\d+)`).exec(returncode)[1]) returncode = returncode.replaceAll( element, `"${eval(`${ARRAYFUNCTION}(${value})`).replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/"/g, '\\"')}"` ) } } log(`Replacing "var a = ${MAINARRAY}; a[123]" to "${MAINARRAY}[123]"`) tmp = [...returncode.matchAll(new RegExp(`\\s+(?<v>\\S+) = ${escapeRegExp(MAINARRAY)}.*$`, "gm"))].map((m) => m.groups.v) for (let i = 0; i < tmp.length; i++) { returncode = returncode.replaceAll(tmp[i], MAINARRAY) } log(`Replacing "${MAINARRAY}[123]" to "real data"`) tmp = noDuplicate( returncode.match(new RegExp(`${escapeRegExp(MAINARRAY)}\\[(?:[^\\]\\[]|\\[(?:[^\\]\\[]|\\[(?:[^\\]\\[]|\\[[^\\]\\[]*\\])*\\])*\\])*\\]`, "g")) ) // ARRAY\[(?:[^\]\[]|\[(?:[^\]\[]|\[(?:[^\]\[]|\[[^\]\[]*\])*\])*\])*\] for (let i = 0; i < tmp.length; i++) { const element = tmp[i] try { returncode = returncode.replaceAll(element, `"${eval(element).replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/"/g, '\\"')}"`) } catch (error) { try { const args = element.replace(`${MAINARRAY}[`, "").replace(/.$/, "") const value = parseInt(new RegExp(`${escapeRegExp(args)} = (\\d+)`).exec(returncode)[1]) returncode = returncode.replaceAll(element, `"${eval(`${MAINARRAY}[${value}]`).replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/"/g, '\\"')}"`) } catch (err) {} } } log("Saving deobfuscated code") const filename = `BonkDeobfuscated_${Date.now()}` const blob = new Blob([splitedText[0] + returncode], { type: "text/javascript;charset=utf-8;" }) if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(blob, filename) } else { const elem = window.document.createElement("a") elem.href = window.URL.createObjectURL(blob) elem.download = filename document.body.appendChild(elem) elem.click() document.body.removeChild(elem) } }) .catch((err) => console.log(err))