Greasy Fork is available in English.
Expose UnityLoader, UnityModule and the WASM module (aka 'Module') globally in 'window' to use for reverse engineering browser games much easier.
// ==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")
})()