wasm-obfuscator
v0.1.3
Published
MoonBit-based WebAssembly obfuscator for Node.js and browsers
Readme
wasm-obfuscator
Node package for the MoonBit wasm-obfuscator project.
Install
pnpm add wasm-obfuscatorCLI
wasm-obfuscator input.wasm --output output.wasm --seed 123 --spyNode API
import fs from "node:fs";
import wasmObfuscator from "wasm-obfuscator";
const { obfuscateBytes, obfuscateFile } = wasmObfuscator;
const inputBytes = await fs.promises.readFile("input.wasm");
const { outputBytes, inputFormat } = obfuscateBytes({
inputBytes,
seed: 123,
});
console.log("detected format:", inputFormat);
await fs.promises.writeFile("output-bytes.wasm", outputBytes);
obfuscateFile({
inputPath: "input.wasm",
outputPath: "output.wasm",
seed: 123,
spy: true,
});Browser API (ESM)
import { obfuscateBytes } from "wasm-obfuscator/browser";
const inputBytes = await fetch("/input.wasm").then((res) => res.arrayBuffer());
const result = obfuscateBytes({
inputBytes,
inputFormat: "wasm",
seed: 123,
});
console.log(result.metrics.sizeGrowthPercent);Notes:
- Browser API runs fully client-side (no Node
fs/child_process). inputBytessupportsUint8Array,ArrayBuffer, and typed-array views.inputFormatcan be"wasm","wat", or"auto".- Returned
metricshas both camelCase and snake_case keys for compatibility.
CLI Options
<input.(wasm|wat)>(required)-o, --output <path>(default:<input>.obf.wasm)--seed <int>(default:20260305)--spy(enable pass trace output)--max-size-growth-percent <int>(default:5000)--max-runtime-slowdown-percent <int>(default:200)-h, --help
obfuscateBytes Options
inputBytes(required):Buffer | Uint8Array | ArrayBufferinputFormat(optional):"wasm" | "wat" | "auto"(default:"auto")autoprioritizes wasm magic header detection (00 61 73 6d 01 00 00 00) and falls back to WAT-like text heuristics ((module, etc.).
seed/spy/ budget options are the same asobfuscateFile
Current Obfuscation Behavior (v0.1.3)
- Runs 5 passes in order:
RenameIdentifiers(currently addswobf.renamecustom section; no real symbol rename yet)SplitBlocks(seed-dependentnopsequence injection)FlattenControlFlow(seed-dependenti32.const <imm>; dropinjection)EncodeConstants(seed-dependentenc/maskxor snippet injection)InsertOpaquePredicates(seed-dependenteq/eqzopaque predicate injection)
- Adds random custom sections with seed-dependent names (
wobf.<rand5>) per pass.
