Unity + WebGL Modules Exposer (Global)

Expose UnityLoader, UnityModule and the WASM module (aka 'Module') globally in 'window' to use for reverse engineering browser games much easier.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Unity + WebGL Modules Exposer (Global)
// @namespace    wasm-hunter
// @version      2.0
// @author       EnterpriseExperience
// @description  Expose UnityLoader, UnityModule and the WASM module (aka 'Module') globally in 'window' to use for reverse engineering browser games much easier.
// @match        https://www.gaming-style.com/*
// @run-at       document-start
// @grant        none
// @license      MIT
// ==/UserScript==

// do not change the '@match' argument to anything else, it won't work otherwise.
// logging is just purely to ensure the script runs more smoothly.

(function () {
    const g = window
    const found = {
        unity_loader:false,
        unity_module:false,
        wasm:false
    }

    function log(...a){
        console.log("[WASM-HUNTER]",...a)
    }

    function expose(name,obj){
        try{
            if(obj) g[name] = obj
        }catch(e){}
    }

    function normalizemodule(v){
        if(!v){
            return null
        }

        if(v.HEAPU8 || v.HEAP8 || v.wasmMemory){
            return v
        }

        if(v.Module && (v.Module.HEAPU8 || v.Module.HEAP8 || v.Module.wasmMemory)){
            return v.Module
        }

        if(v.asm && (v.HEAPU8 || v.HEAP8)){
            return v
        }

        return null
    }

    function scanforunityloader(win){
        if(found.unity_loader) return

        try{
            if(win.UnityLoader){
                expose("UnityLoader",win.UnityLoader)
                found.unity_loader = true
                log("UnityLoader captured")
            }
        }catch(e){}
    }

    function scanformodule(win){
        if(found.unity_module) return

        try{
            for(const k in win){
                const v = win[k]
                if(!v) continue

                const m = normalizemodule(v)

                if(m){
                    expose("UnityModule",m)
                    expose("Module",m)
                    found.unity_module = true
                    log("Unity Module detected via key.")
                    break
                }
            }
        }catch(e){}
    }

    function scanwindow(win){
        try{
            scanforunityloader(win)
            scanformodule(win)

            if(win.frames){
                for(let i=0;i<win.frames.length;i++){
                    try{
                        scanwindow(win.frames[i])
                    }catch(e){}
                }
            }
        }catch(e){}
    }

    const scan_interval = setInterval(()=>{
        scanwindow(g)

        if(found.unity_loader && found.unity_module && found.wasm){
            clearInterval(scan_interval)
            log("All targets captured")
        }

    },2000)

    function captureinstance(instance,module){
        if(found.wasm) return
        found.wasm = true

        expose("wasmInstance",instance)
        expose("wasmModule",module)

        const exports = instance.exports
        expose("wasmExports",exports)

        log("WASM objects captured successfully.")

        if(exports.__indirect_function_table){
            expose("wasmTable",exports.__indirect_function_table)
        }
    }

    const orig_instantiate = WebAssembly.instantiate
    WebAssembly.instantiate = async function(...args){
        const result = await orig_instantiate.apply(this,args)

        if(result && result.instance){
            captureinstance(result.instance,result.module)
        }

        return result
    }

    if(WebAssembly.instantiateStreaming){
        const orig_streaming = WebAssembly.instantiateStreaming

        WebAssembly.instantiateStreaming = async function(...args){
            const result = await orig_streaming.apply(this,args)

            if(result && result.instance){
                captureinstance(result.instance,result.module)
            }

            return result
        }
    }

    const orig_instance = WebAssembly.Instance
    WebAssembly.Instance = function(module,imports){
        const inst = new orig_instance(module,imports)
        captureinstance(inst,module)
        return inst
    }
    WebAssembly.Instance.prototype = orig_instance.prototype

    const orig_compile = WebAssembly.compile
    WebAssembly.compile = async function(...args){
        const mod = await orig_compile.apply(this,args)

        expose("compiledWasmModule",mod)

        log("WASM compiled")

        return mod
    }

    log("Unity WASM scanner started")
})()