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.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==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")
})()