├── run.bat ├── README.md ├── obfuscators ├── moonsec │ ├── opcodes │ │ ├── NewTable.js │ │ ├── LoadNil.js │ │ ├── Len.js │ │ ├── Move.js │ │ ├── Unm.js │ │ ├── Not.js │ │ ├── GetUpval.js │ │ ├── SetUpval.js │ │ ├── Concat.js │ │ ├── SetGlobal.js │ │ ├── GetGlobal.js │ │ ├── Jmp.js │ │ ├── LoadK.js │ │ ├── Close.js │ │ ├── LoadBool.js │ │ ├── GetTable.js │ │ ├── Self.js │ │ ├── VarArg.js │ │ ├── Test.js │ │ ├── TForLoop.js │ │ ├── ForLoop.js │ │ ├── ForPrep.js │ │ ├── TestSet.js │ │ ├── TailCall.js │ │ ├── SetList.js │ │ ├── SetTable.js │ │ ├── Add.js │ │ ├── Div.js │ │ ├── Mod.js │ │ ├── Mul.js │ │ ├── Pow.js │ │ ├── Sub.js │ │ ├── Return.js │ │ ├── Closure.js │ │ ├── Eq.js │ │ ├── Lt.js │ │ ├── Le.js │ │ └── Call.js │ ├── deobfuscate.js │ ├── emulation.js │ └── deserialize.js └── ironbrew │ ├── opcodes │ ├── 2.7.0 │ │ ├── NewTable.js │ │ ├── LoadNil.js │ │ ├── Len.js │ │ ├── Move.js │ │ ├── Unm.js │ │ ├── Jmp.js │ │ ├── Not.js │ │ ├── GetUpval.js │ │ ├── SetUpval.js │ │ ├── Concat.js │ │ ├── LoadK.js │ │ ├── SetGlobal.js │ │ ├── GetGlobal.js │ │ ├── Close.js │ │ ├── LoadBool.js │ │ ├── GetTable.js │ │ ├── Self.js │ │ ├── VarArg.js │ │ ├── TForLoop.js │ │ ├── ForLoop.js │ │ ├── ForPrep.js │ │ ├── TestSet.js │ │ ├── TailCall.js │ │ ├── Test.js │ │ ├── SetList.js │ │ ├── SetTable.js │ │ ├── Add.js │ │ ├── Div.js │ │ ├── Mod.js │ │ ├── Mul.js │ │ ├── Pow.js │ │ ├── Sub.js │ │ ├── Return.js │ │ ├── Closure.js │ │ ├── Eq.js │ │ ├── Lt.js │ │ ├── Le.js │ │ └── Call.js │ └── 2.7.1 │ │ ├── NewTable.js │ │ ├── LoadNil.js │ │ ├── Len.js │ │ ├── Move.js │ │ ├── Unm.js │ │ ├── Not.js │ │ ├── GetUpval.js │ │ ├── SetUpval.js │ │ ├── Concat.js │ │ ├── LoadK.js │ │ ├── SetGlobal.js │ │ ├── GetGlobal.js │ │ ├── Jmp.js │ │ ├── Close.js │ │ ├── LoadBool.js │ │ ├── GetTable.js │ │ ├── Self.js │ │ ├── VarArg.js │ │ ├── Test.js │ │ ├── TForLoop.js │ │ ├── ForLoop.js │ │ ├── ForPrep.js │ │ ├── TestSet.js │ │ ├── TailCall.js │ │ ├── SetList.js │ │ ├── Add.js │ │ ├── Div.js │ │ ├── Mod.js │ │ ├── Mul.js │ │ ├── Pow.js │ │ ├── SetTable.js │ │ ├── Sub.js │ │ ├── Return.js │ │ ├── Closure.js │ │ ├── Eq.js │ │ ├── Lt.js │ │ ├── Le.js │ │ └── Call.js │ ├── deobfuscate.js │ ├── emulation.js │ ├── analyze.js │ ├── deserialize.js │ └── devirtualize.js ├── package.json ├── index.js └── utility ├── printer.js └── binary.js /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | node index.js 3 | pause -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Lua Deobfuscator 2 | 3 | ### Only for (MoonSec V2, IronBrew, AztupBrew) 4 | -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/NewTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NewTableB0: { 3 | String: "Stk[Inst[OP_A]]={};", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/NewTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NewTableB0: { 3 | String: "Stk[Inst[OP_A]]={};", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/NewTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NewTableB0: { 3 | String: "Stk[Inst[OP_A]]={};", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/LoadNil.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadNil: { 3 | String: "for Idx=Inst[OP_A],Inst[OP_B] do Stk[Idx]=nil;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/LoadNil.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadNil: { 3 | String: "for Idx=Inst[OP_A],Inst[OP_B] do Stk[Idx]=nil;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/LoadNil.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadNil: { 3 | String: "for Idx=Inst[OP_A],Inst[OP_B] do Stk[Idx]=nil;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Len.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Len: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=#Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Move.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Move: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Unm.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Unm: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=-Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Len.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Len: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=#Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Move.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Move: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Unm.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Unm: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=-Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Len.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Len: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=#Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Move.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Move: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Unm.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Unm: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=-Stk[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Not.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Not: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=(not Stk[Inst[OP_B]]);", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Jmp.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Jmp: { 3 | Thorough: true, 4 | String: "InstrPoint = InstrPoint + Inst[OP_B]", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Not.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Not: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=(not Stk[Inst[OP_B]]);", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Not.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Not: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=(not Stk[Inst[OP_B]]);", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/GetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetUpval: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Upvalues[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/SetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetUpval: { 3 | Thorough: true, 4 | String: "Upvalues[Inst[OP_B]]=Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/GetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetUpval: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Upvalues[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/SetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetUpval: { 3 | Thorough: true, 4 | String: "Upvalues[Inst[OP_B]]=Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/GetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetUpval: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Upvalues[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/SetUpval.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetUpval: { 3 | Thorough: true, 4 | String: "Upvalues[Inst[OP_B]]=Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | return instruction 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Concat: { 3 | String: "local B=Inst[OP_B];local K=Stk[B] for Idx=B+1,Inst[OP_C] do K=K..Stk[Idx];end;Stk[Inst[OP_A]]=K;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Concat: { 3 | String: "local B=Inst[OP_B];local K=Stk[B] for Idx=B+1,Inst[OP_C] do K=K..Stk[Idx];end;Stk[Inst[OP_A]]=K;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Concat: { 3 | String: "local B=Inst[OP_B];local K=Stk[B] for Idx=B+1,Inst[OP_C] do K=K..Stk[Idx];end;Stk[Inst[OP_A]]=K;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/SetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetGlobal: { 3 | Thorough: true, 4 | String: "Env[Inst[OP_B]] = Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/LoadK.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadK: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]] = Inst[OP_B];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/SetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetGlobal: { 3 | Thorough: true, 4 | String: "Env[Inst[OP_B]] = Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/GetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetGlobal: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Env[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/LoadK.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadK: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/SetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetGlobal: { 3 | Thorough: true, 4 | String: "Env[Const[Inst[OP_B]]] = Stk[Inst[OP_A]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/GetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetGlobal: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Env[Inst[OP_B]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/GetGlobal.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetGlobal: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]]=Env[Const[Inst[OP_B]]];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Jmp.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Jmp: { 3 | Thorough: true, 4 | String: "InstrPoint=Inst[OP_B];", 5 | Create: function(instruction) { 6 | instruction.B = instruction.B - instruction.PC - 1 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Jmp.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Jmp: { 3 | Thorough: true, 4 | String: "InstrPoint=Inst[OP_B];", 5 | Create: function(instruction) { 6 | instruction.B = instruction.B - instruction.PC - 1 7 | 8 | return instruction 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/LoadK.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadK: { 3 | Thorough: true, 4 | String: "Stk[Inst[OP_A]] = Inst[OP_B];", 5 | Create: function(instruction) { 6 | instruction.B-- 7 | 8 | //console.log(instruction) 9 | 10 | return instruction 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Close.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Close: { 3 | String: "local A=Inst[OP_A];local Cls={};for Idx=1,#Lupvals do local List=Lupvals[Idx];for Idz=0,#List do local Upv=List[Idz];local NStk=Upv[1];local Pos=Upv[2]; if NStk==Stk and Pos>=A then Cls[Pos]=NStk[Pos];Upv[1]=Cls;end;end;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Close.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Close: { 3 | String: "local A=Inst[OP_A];local Cls={};for Idx=1,#Lupvals do local List=Lupvals[Idx];for Idz=0,#List do local Upv=List[Idz];local NStk=Upv[1];local Pos=Upv[2]; if NStk==Stk and Pos>=A then Cls[Pos]=NStk[Pos];Upv[1]=Cls;end;end;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Close.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Close: { 3 | String: "local A=Inst[OP_A];local Cls={};for Idx=1,#Lupvals do local List=Lupvals[Idx];for Idz=0,#List do local Upv=List[Idz];local NStk=Upv[1];local Pos=Upv[2]; if NStk==Stk and Pos>=A then Cls[Pos]=NStk[Pos];Upv[1]=Cls;end;end;end;", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lua-deobfuscator", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "keywords": [], 11 | "description": "", 12 | "dependencies": { 13 | "chalk": "^4.1.2", 14 | "smart-buffer": "^4.2.0", 15 | "unicode-substring": "^1.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/LoadBool.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadBool: { 3 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | LoadBoolC: { 9 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);InstrPoint=InstrPoint+1;", 10 | Create: function(instruction) { 11 | instruction.C = 1 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/LoadBool.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadBool: { 3 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | LoadBoolC: { 9 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);InstrPoint=InstrPoint+1;", 10 | Create: function(instruction) { 11 | instruction.C = 1 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/LoadBool.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | LoadBool: { 3 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | LoadBoolC: { 9 | String: "Stk[Inst[OP_A]]=(Inst[OP_B]~=0);InstrPoint=InstrPoint+1;", 10 | Create: function(instruction) { 11 | instruction.C = 1 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/GetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetTable: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | GetTableConst: { 9 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Inst[OP_C]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/GetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetTable: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | GetTableConst: { 9 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Inst[OP_C]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/GetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | GetTable: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | GetTableConst: { 9 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]][Const[Inst[OP_C]]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Self.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Self: { 3 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SelfC: { 9 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Inst[OP_C]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Self.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Self: { 3 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SelfC: { 9 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Inst[OP_C]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Self.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Self: { 3 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Stk[Inst[OP_C]]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SelfC: { 9 | String: "local A=Inst[OP_A];local B=Stk[Inst[OP_B]];Stk[A+1]=B;Stk[A]=B[Const[Inst[OP_C]]];", 10 | Create: function(instruction) { 11 | instruction.C += 255 12 | 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/VarArg.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | String: "local A=Inst[OP_A];local B=Inst[OP_B];for Idx=A,B do Stk[Idx]=Vararg[Idx-A];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | ClosureNU: { 11 | String: "local A=Inst[OP_A];Top=A+Varargsz-1;for Idx=A,Top do local VA=Vararg[Idx-A];Stk[Idx]=VA;end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/VarArg.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | String: "local A=Inst[OP_A];local B=Inst[OP_B];for Idx=A,B do Stk[Idx]=Vararg[Idx-A];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | ClosureNU: { 11 | String: "local A=Inst[OP_A];Top=A+Varargsz-1;for Idx=A,Top do local VA=Vararg[Idx-A];Stk[Idx]=VA;end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/VarArg.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | String: "local A=Inst[OP_A];local B=Inst[OP_B];for Idx=A,B do Stk[Idx]=Vararg[Idx-A];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | ClosureNU: { 11 | String: "local A=Inst[OP_A];Top=A+Varargsz-1;for Idx=A,Top do local VA=Vararg[Idx-A];Stk[Idx]=VA;end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Test: { 3 | String: "if Stk[Inst[OP_A]] then InstrPoint=InstrPoint + 1; else InstrPoint = Inst[OP_B]; end;", 4 | Create: function(instruction) { 5 | instruction.B = 0 6 | 7 | return instruction 8 | } 9 | }, 10 | TestC: { 11 | String: "if not Stk[Inst[OP_A]] then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 12 | Create: function(instruction) { 13 | instruction.B = 0 14 | 15 | return instruction 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Test: { 3 | String: "if Stk[Inst[OP_A]] then InstrPoint=InstrPoint + 1; else InstrPoint = Inst[OP_B]; end;", 4 | Create: function(instruction) { 5 | instruction.B = 0 6 | instruction.C = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | TestC: { 12 | String: "if not Stk[Inst[OP_A]] then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = 0 15 | instruction.C = 1 16 | 17 | return instruction 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/TForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local C = Inst[OP_C]; 5 | local CB = A + 2 6 | local Result = {Stk[A](Stk[A + 1],Stk[CB])}; 7 | for Idx = 1, C do 8 | Stk[CB + Idx] = Result[Idx]; 9 | end; 10 | local R = Result[1] 11 | if R then 12 | Stk[CB] = R 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | InstrPoint = InstrPoint + 1; 16 | end;`, 17 | Create: function(instruction) { 18 | instruction.B = 0 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/TForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local C = Inst[OP_C]; 5 | local CB = A + 2 6 | local Result = {Stk[A](Stk[A + 1],Stk[CB])}; 7 | for Idx = 1, C do 8 | Stk[CB + Idx] = Result[Idx]; 9 | end; 10 | local R = Result[1] 11 | if R then 12 | Stk[CB] = R 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | InstrPoint = InstrPoint + 1; 16 | end;`, 17 | Create: function(instruction) { 18 | instruction.B = 0 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/TForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local C = Inst[OP_C]; 5 | local CB = A + 2 6 | local Result = {Stk[A](Stk[A + 1],Stk[CB])}; 7 | for Idx = 1, C do 8 | Stk[CB + Idx] = Result[Idx]; 9 | end; 10 | local R = Result[1] 11 | if R then 12 | Stk[CB] = R 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | InstrPoint = InstrPoint + 1; 16 | end;`, 17 | Create: function(instruction) { 18 | instruction.B = 0 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/ForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForLoop: { 3 | String: `local A = Inst[OP_A]; 4 | local Step = Stk[A + 2]; 5 | local Index = Stk[A] + Step; 6 | Stk[A] = Index; 7 | if (Step > 0) then 8 | if (Index <= Stk[A+1]) then 9 | InstrPoint = Inst[OP_B]; 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index >= Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | Stk[A+3] = Index; 15 | end`, 16 | Create: function(instruction) { 17 | instruction.B = instruction.B - instruction.PC - 1 18 | 19 | return instruction 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/ForPrep.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local Index = Stk[A] 5 | local Step = Stk[A + 2]; 6 | if (Step > 0) then 7 | if (Index > Stk[A+1]) then 8 | InstrPoint = Inst[OP_B]; 9 | else 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index < Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | Stk[A+3] = Index; 16 | end`, 17 | Create: function(instruction) { 18 | instruction.B = instruction.B - instruction.PC - 2 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/ForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForLoop: { 3 | String: `local A = Inst[OP_A]; 4 | local Step = Stk[A + 2]; 5 | local Index = Stk[A] + Step; 6 | Stk[A] = Index; 7 | if (Step > 0) then 8 | if (Index <= Stk[A+1]) then 9 | InstrPoint = Inst[OP_B]; 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index >= Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | Stk[A+3] = Index; 15 | end`, 16 | Create: function(instruction) { 17 | instruction.B = instruction.B - instruction.PC - 1 18 | 19 | return instruction 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/ForLoop.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForLoop: { 3 | String: `local A = Inst[OP_A]; 4 | local Step = Stk[A + 2]; 5 | local Index = Stk[A] + Step; 6 | Stk[A] = Index; 7 | if (Step > 0) then 8 | if (Index <= Stk[A+1]) then 9 | InstrPoint = Inst[OP_B]; 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index >= Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | Stk[A+3] = Index; 15 | end`, 16 | Create: function(instruction) { 17 | instruction.B = instruction.B - instruction.PC - 1 18 | 19 | return instruction 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/ForPrep.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local Index = Stk[A] 5 | local Step = Stk[A + 2]; 6 | if (Step > 0) then 7 | if (Index > Stk[A+1]) then 8 | InstrPoint = Inst[OP_B]; 9 | else 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index < Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | Stk[A+3] = Index; 16 | end`, 17 | Create: function(instruction) { 18 | instruction.B = instruction.B - instruction.PC - 2 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/ForPrep.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ForPrep: { 3 | String: `local A = Inst[OP_A]; 4 | local Index = Stk[A] 5 | local Step = Stk[A + 2]; 6 | if (Step > 0) then 7 | if (Index > Stk[A+1]) then 8 | InstrPoint = Inst[OP_B]; 9 | else 10 | Stk[A+3] = Index; 11 | end 12 | elseif (Index < Stk[A+1]) then 13 | InstrPoint = Inst[OP_B]; 14 | else 15 | Stk[A+3] = Index; 16 | end`, 17 | Create: function(instruction) { 18 | instruction.B = instruction.B - instruction.PC - 2 19 | 20 | return instruction 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/TestSet.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TestSet: { 3 | String: "local B=Stk[Inst[OP_C]];if B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.C 6 | instruction.C = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | TestSetC: { 12 | String: "local B=Stk[Inst[OP_C]];if not B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.C 15 | instruction.C = 1 16 | 17 | return instruction 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/TestSet.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TestSet: { 3 | String: "local B=Stk[Inst[OP_C]];if B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.C 6 | instruction.C = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | TestSetC: { 12 | String: "local B=Stk[Inst[OP_C]];if not B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.C 15 | instruction.C = 1 16 | 17 | return instruction 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/TestSet.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TestSet: { 3 | String: "local B=Stk[Inst[OP_C]];if B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.C 6 | instruction.C = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | TestSetC: { 12 | String: "local B=Stk[Inst[OP_C]];if not B then InstrPoint=InstrPoint+1;else Stk[Inst[OP_A]]=B;InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.C 15 | instruction.C = 1 16 | 17 | return instruction 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/TailCall.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TailCall: { 3 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Inst[OP_B])) end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | TailCallB0: { 11 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Top)) end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | TailCallB1: { 17 | String: "do return Stk[Inst[OP_A]](); end;", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/TailCall.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TailCall: { 3 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Inst[OP_B])) end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | TailCallB0: { 11 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Top)) end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | TailCallB1: { 17 | String: "do return Stk[Inst[OP_A]](); end;", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/TailCall.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | TailCall: { 3 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Inst[OP_B])) end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | 7 | return instruction 8 | } 9 | }, 10 | TailCallB0: { 11 | String: "local A = Inst[OP_A]; do return Stk[A](Unpack(Stk, A + 1, Top)) end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | TailCallB1: { 17 | String: "do return Stk[Inst[OP_A]](); end;", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Test: { 3 | String: `if Stk[Inst[OP_A]] then 4 | InstrPoint = InstrPoint + 1; 5 | else 6 | InstrPoint = InstrPoint + Inst[OP_B]; 7 | end;`, 8 | Create: function(instruction) { 9 | instruction.B = 0 10 | instruction.C = 0 11 | 12 | return instruction 13 | } 14 | }, 15 | TestC: { 16 | String: `if not Stk[Inst[OP_A]] then 17 | InstrPoint = InstrPoint + 1; 18 | else 19 | InstrPoint = InstrPoint + Inst[OP_B]; 20 | end;`, 21 | Create: function(instruction) { 22 | instruction.B = 0 23 | instruction.C = 1 24 | 25 | return instruction 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/SetList.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetList: { 3 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 4 | Create: function(instruction) { 5 | instruction.B -= instruction.A 6 | 7 | return instruction 8 | } 9 | }, 10 | SetListB0: { 11 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Top do Insert(T, Stk[Idx]) end;", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | SetListC0: { 17 | String: "InstrPoint = InstrPoint + 1 local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 18 | Create: function(instruction) { 19 | throw "ahh help" 20 | 21 | return instruction 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/SetList.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetList: { 3 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 4 | Create: function(instruction) { 5 | instruction.B -= instruction.A 6 | 7 | return instruction 8 | } 9 | }, 10 | SetListB0: { 11 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Top do Insert(T, Stk[Idx]) end;", 12 | Create: function(instruction) { 13 | instruction.C = 0 14 | 15 | return instruction 16 | } 17 | }, 18 | SetListC0: { 19 | String: "InstrPoint = InstrPoint + 1 local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 20 | Create: function(instruction) { 21 | throw "big ass fucking table fuck" 22 | 23 | return instruction 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/SetList.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetList: { 3 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 4 | Create: function(instruction) { 5 | instruction.B -= instruction.A 6 | 7 | return instruction 8 | } 9 | }, 10 | SetListB0: { 11 | String: "local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Top do Insert(T, Stk[Idx]) end;", 12 | Create: function(instruction) { 13 | instruction.C = 0 14 | 15 | return instruction 16 | } 17 | }, 18 | SetListC0: { 19 | String: "InstrPoint = InstrPoint + 1 local A = Inst[OP_A]; local T = Stk[A]; for Idx = A + 1, Inst[OP_B] do Insert(T, Stk[Idx]) end;", 20 | Create: function(instruction) { 21 | throw "big ass fucking table fuck" 22 | 23 | return instruction 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/deobfuscate.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const analyze = require("./analyze") 3 | const deserialize = require("./deserialize") 4 | const devirtualize = require("./devirtualize") 5 | const binary = require("../../utility/binary") 6 | const printer = require("../../utility/printer") 7 | 8 | function detect(source) { 9 | return source.match(/\.\.:::MoonSec::\.\./g) != null 10 | } 11 | 12 | function deobfuscate(ast) { 13 | let vmdata 14 | 15 | process.stdout.write(`[${chalk.blueBright("INFO")}] Finding Vm Data...`) 16 | vmdata = analyze(ast.StatementList, true) 17 | 18 | process.stdout.write(`[${chalk.blueBright("INFO")}] Deserializing Bytecode...`) 19 | vmdata = deserialize(vmdata, true) 20 | 21 | process.stdout.write(`[${chalk.blueBright("INFO")}] Devirtualizing Bytecode...`) 22 | vmdata = devirtualize(vmdata, true) 23 | 24 | return binary.sterilize(vmdata) 25 | } 26 | 27 | module.exports = {detect, deobfuscate, name: "MoonSecV2"} 28 | -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/SetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetTable: { 3 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]]=Stk[Inst[OP_C]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | 9 | SetTableB: { 10 | String: "Stk[Inst[OP_A]][Inst[OP_B]] = Stk[Inst[OP_C]];", 11 | Create: function(instruction) { 12 | instruction.B += 255 13 | 14 | return instruction 15 | } 16 | }, 17 | SetTableC: { 18 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]] = Inst[OP_C];", 19 | Create: function(instruction) { 20 | instruction.C += 255 21 | 22 | return instruction 23 | } 24 | }, 25 | SetTableBC: { 26 | String: "Stk[Inst[OP_A]][Inst[OP_B]] = Inst[OP_C];", 27 | Create: function(instruction) { 28 | instruction.B += 255 29 | instruction.C += 255 30 | 31 | return instruction 32 | } 33 | }, 34 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Add.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Add: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]+Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | AddB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] + Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | AddC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] + Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | AddBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] + Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Div.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Div: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]/Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | DivB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] / Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | DivC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] / Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | DivBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] / Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Mod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mod: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]%Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | ModB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] % Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | ModC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] % Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | ModBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] % Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Mul.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mul: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]*Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | MulB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] * Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | MulC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] * Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | MulBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] * Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Pow.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Pow: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]^Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | PowB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] ^ Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | PowC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] ^ Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | PowBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] ^ Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Sub.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Sub: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]-Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SubB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] - Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | SubC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] - Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | SubBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] - Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Add.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Add: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]+Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | AddB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] + Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | AddC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] + Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | AddBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] + Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Div.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Div: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]/Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | DivB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] / Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | DivC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] / Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | DivBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] / Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Mod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mod: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]%Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | ModB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] % Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | ModC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] % Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | ModBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] % Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Mul.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mul: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]*Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | MulB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] * Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | MulC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] * Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | MulBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] * Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Pow.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Pow: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]^Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | PowB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] ^ Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | PowC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] ^ Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | PowBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] ^ Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/SetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetTable: { 3 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]]=Stk[Inst[OP_C]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | 9 | SetTableB: { 10 | String: "Stk[Inst[OP_A]][Inst[OP_B]] = Stk[Inst[OP_C]];", 11 | Create: function(instruction) { 12 | instruction.B += 255 13 | 14 | return instruction 15 | } 16 | }, 17 | SetTableC: { 18 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]] = Inst[OP_C];", 19 | Create: function(instruction) { 20 | instruction.C += 255 21 | 22 | return instruction 23 | } 24 | }, 25 | SetTableBC: { 26 | String: "Stk[Inst[OP_A]][Inst[OP_B]] = Inst[OP_C];", 27 | Create: function(instruction) { 28 | instruction.B += 255 29 | instruction.C += 255 30 | 31 | return instruction 32 | } 33 | }, 34 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Sub.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Sub: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]-Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SubB: { 9 | String: "Stk[Inst[OP_A]] = Inst[OP_B] - Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | SubC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] - Inst[OP_C]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | SubBC: { 25 | String: "Stk[Inst[OP_A]] = Inst[OP_B] - Inst[OP_C]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/SetTable.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SetTable: { 3 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]]=Stk[Inst[OP_C]];", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | 9 | SetTableB: { 10 | String: "Stk[Inst[OP_A]][Const[Inst[OP_B]]] = Stk[Inst[OP_C]];", 11 | Create: function(instruction) { 12 | instruction.B += 255 13 | 14 | return instruction 15 | } 16 | }, 17 | SetTableC: { 18 | String: "Stk[Inst[OP_A]][Stk[Inst[OP_B]]] = Const[Inst[OP_C]];", 19 | Create: function(instruction) { 20 | instruction.C += 255 21 | 22 | return instruction 23 | } 24 | }, 25 | SetTableBC: { 26 | String: "Stk[Inst[OP_A]][Const[Inst[OP_B]]] = Const[Inst[OP_C]];", 27 | Create: function(instruction) { 28 | instruction.B += 255 29 | instruction.C += 255 30 | 31 | return instruction 32 | } 33 | }, 34 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Add.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Add: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]+Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | AddB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] + Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | AddC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] + Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | AddBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] + Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Div.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Div: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]/Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | DivB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] / Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | DivC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] / Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | DivBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] / Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Mod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mod: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]%Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | ModB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] % Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | ModC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] % Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | ModBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] % Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Mul.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Mul: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]*Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | MulB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] * Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | MulC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] * Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | MulBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] * Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Pow.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Pow: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]^Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | PowB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] ^ Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | PowC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] ^ Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | PowBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] ^ Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Sub.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Sub: { 3 | String: "Stk[Inst[OP_A]]=Stk[Inst[OP_B]]-Stk[Inst[OP_C]]", 4 | Create: function(instruction) { 5 | return instruction 6 | } 7 | }, 8 | SubB: { 9 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] - Stk[Inst[OP_C]]", 10 | Create: function(instruction) { 11 | instruction.B += 255 12 | 13 | return instruction 14 | } 15 | }, 16 | SubC: { 17 | String: "Stk[Inst[OP_A]] = Stk[Inst[OP_B]] - Const[Inst[OP_C]]", 18 | Create: function(instruction) { 19 | instruction.C += 255 20 | 21 | return instruction 22 | } 23 | }, 24 | SubBC: { 25 | String: "Stk[Inst[OP_A]] = Const[Inst[OP_B]] - Const[Inst[OP_C]]", 26 | Create: function(instruction) { 27 | instruction.B += 255 28 | instruction.C += 255 29 | 30 | return instruction 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Return.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Return: { 3 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, A + Inst[OP_B]) end;", 4 | Create: function(instruction) { 5 | instruction.B += 2 6 | 7 | return instruction 8 | } 9 | }, 10 | ReturnB2: { 11 | String: "do return Stk[Inst[OP_A]] end", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | ReturnB3: { 17 | String: "local A = Inst[OP_A];\ndo return Stk[A], Stk[A + 1] end", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | ReturnB0: { 23 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, Top) end;", 24 | Create: function(instruction) { 25 | return instruction 26 | } 27 | }, 28 | ReturnB1: { 29 | String: "do return end;", 30 | Create: function(instruction) { 31 | return instruction 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Return.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Return: { 3 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, A + Inst[OP_B]) end;", 4 | Create: function(instruction) { 5 | instruction.B += 2 6 | 7 | return instruction 8 | } 9 | }, 10 | ReturnB2: { 11 | String: "do return Stk[Inst[OP_A]] end", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | ReturnB3: { 17 | String: "local A = Inst[OP_A];\ndo return Stk[A], Stk[A + 1] end", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | ReturnB0: { 23 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, Top) end;", 24 | Create: function(instruction) { 25 | return instruction 26 | } 27 | }, 28 | ReturnB1: { 29 | String: "do return end;", 30 | Create: function(instruction) { 31 | return instruction 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Return.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Return: { 3 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, A + Inst[OP_B]) end;", 4 | Create: function(instruction) { 5 | instruction.B += 2 6 | 7 | return instruction 8 | } 9 | }, 10 | ReturnB2: { 11 | String: "do return Stk[Inst[OP_A]] end", 12 | Create: function(instruction) { 13 | return instruction 14 | } 15 | }, 16 | ReturnB3: { 17 | String: "local A = Inst[OP_A];\ndo return Stk[A], Stk[A + 1] end", 18 | Create: function(instruction) { 19 | return instruction 20 | } 21 | }, 22 | ReturnB0: { 23 | String: "local A = Inst[OP_A];\ndo return Unpack(Stk, A, Top) end;", 24 | Create: function(instruction) { 25 | return instruction 26 | } 27 | }, 28 | ReturnB1: { 29 | String: "do return end;", 30 | Create: function(instruction) { 31 | return instruction 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/deobfuscate.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const analyze = require("./analyze") 3 | const deserialize = require("./deserialize") 4 | const devirtualize = require("./devirtualize") 5 | const luamin = require("../../utility/luamin") 6 | const binary = require("../../utility/binary") 7 | 8 | function detect(source) { 9 | return source.match(/return table\.concat\([_\-a-zA-Z0-9]+\)/g) != null || source.match(/return [_\-a-zA-Z0-9]+\(true, ?\{\}, ?[_\-a-zA-Z0-9]+\(\)\)\(\);?/g) != null || source.match(/bit and bit\.bxor or function\([_\-a-zA-Z0-9]+, ?[_\-a-zA-Z0-9]+\)/g) != null 10 | } 11 | 12 | function deobfuscate(ast) { 13 | let vmdata 14 | 15 | process.stdout.write(`[${chalk.blueBright("INFO")}] Finding Vm Data...`) 16 | vmdata = analyze(ast.StatementList, true) 17 | 18 | process.stdout.write(`[${chalk.blueBright("INFO")}] Deserializing Bytecode...`) 19 | vmdata = deserialize(vmdata, true) 20 | 21 | luamin.SolveMath(ast) 22 | 23 | process.stdout.write(`[${chalk.blueBright("INFO")}] Devirtualizing Bytecode...`) 24 | vmdata = devirtualize(vmdata) 25 | 26 | return binary.sterilize(vmdata) 27 | } 28 | 29 | module.exports = {detect, deobfuscate, name: "IronBrew"} 30 | -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Closure.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | Match: function(instruction) { 4 | if (instruction.length > 3 && instruction[3].Type == "AssignmentStat") { 5 | const s = instruction[3] 6 | 7 | if (s.Rhs[0].Type == "CallExpr") { 8 | const r = s.Rhs[0] 9 | const l = r.FunctionArguments.ArgList.length > 1 ? r.FunctionArguments.ArgList[1] : null 10 | 11 | if (l != null && l.Type == "TableLiteral" && l.EntryList.length > 1) { 12 | if (l.EntryList[0].Field.Source == "__index") { 13 | return true 14 | } 15 | } 16 | } 17 | } 18 | }, 19 | Create: function(instruction) { 20 | return instruction 21 | } 22 | }, 23 | ClosureNU: { 24 | String: "Stk[Inst[OP_A]]=Wrap(Proto[Inst[OP_B]],nil,Env);", 25 | Create: function(instruction) { 26 | return instruction 27 | } 28 | } 29 | } 30 | 31 | /* 32 | local NewProto = Proto[Inst[OP_B]]; 33 | local NewUvals; 34 | local Indexes = {}; 35 | NewUvals = Setmetatable({}, { 36 | __index = function(_, Key) 37 | local Val = Indexes[Key]; 38 | return Val[1][Val[2]]; 39 | end, 40 | __newindex = function(_, Key, Value) 41 | local Val = Indexes[Key] 42 | Val[1][Val[2]] = Value; 43 | end; 44 | }); 45 | for Idx = 1, Inst[OP_C] do 46 | InstrPoint = InstrPoint + 1; 47 | local Mvm = Instr[InstrPoint]; 48 | if Mvm[OP_ENUM] == OP_MOVE then 49 | Indexes[Idx - 1] = { 50 | Stk, 51 | Mvm[OP_B] 52 | }; 53 | else 54 | Indexes[Idx - 1] = { 55 | Upvalues, 56 | Mvm[OP_B] 57 | }; 58 | end; 59 | Lupvals[#Lupvals + 1] = Indexes; 60 | end; 61 | Stk[Inst[OP_A]] = Wrap(NewProto, NewUvals, Env); 62 | */ -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Closure.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | Match: function(instruction) { 4 | if (instruction.length > 3 && instruction[3].Type == "AssignmentStat") { 5 | const s = instruction[3] 6 | 7 | if (s.Rhs[0].Type == "CallExpr") { 8 | const r = s.Rhs[0] 9 | const l = r.FunctionArguments.ArgList.length > 1 ? r.FunctionArguments.ArgList[1] : null 10 | 11 | if (l != null && l.Type == "TableLiteral" && l.EntryList.length > 1) { 12 | if (l.EntryList[0].Field.Source == "__index") { 13 | return true 14 | } 15 | } 16 | } 17 | } 18 | }, 19 | Create: function(instruction) { 20 | return instruction 21 | } 22 | }, 23 | ClosureNU: { 24 | String: "Stk[Inst[OP_A]]=Wrap(Proto[Inst[OP_B]],nil,Env);", 25 | Create: function(instruction) { 26 | return instruction 27 | } 28 | } 29 | } 30 | 31 | /* 32 | local NewProto = Proto[Inst[OP_B]]; 33 | local NewUvals; 34 | local Indexes = {}; 35 | NewUvals = Setmetatable({}, { 36 | __index = function(_, Key) 37 | local Val = Indexes[Key]; 38 | return Val[1][Val[2]]; 39 | end, 40 | __newindex = function(_, Key, Value) 41 | local Val = Indexes[Key] 42 | Val[1][Val[2]] = Value; 43 | end; 44 | }); 45 | for Idx = 1, Inst[OP_C] do 46 | InstrPoint = InstrPoint + 1; 47 | local Mvm = Instr[InstrPoint]; 48 | if Mvm[OP_ENUM] == OP_MOVE then 49 | Indexes[Idx - 1] = { 50 | Stk, 51 | Mvm[OP_B] 52 | }; 53 | else 54 | Indexes[Idx - 1] = { 55 | Upvalues, 56 | Mvm[OP_B] 57 | }; 58 | end; 59 | Lupvals[#Lupvals + 1] = Indexes; 60 | end; 61 | Stk[Inst[OP_A]] = Wrap(NewProto, NewUvals, Env); 62 | */ -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Closure.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Closure: { 3 | Match: function(instruction) { 4 | if (instruction.length > 3 && instruction[3].Type == "AssignmentStat") { 5 | const s = instruction[3] 6 | 7 | if (s.Rhs[0].Type == "CallExpr") { 8 | const r = s.Rhs[0] 9 | const l = r.FunctionArguments.ArgList.length > 1 ? r.FunctionArguments.ArgList[1] : null 10 | 11 | if (l != null && l.Type == "TableLiteral" && l.EntryList.length > 1) { 12 | if (l.EntryList[0].Field.Source == "__index") { 13 | return true 14 | } 15 | } 16 | } 17 | } 18 | }, 19 | Create: function(instruction) { 20 | return instruction 21 | } 22 | }, 23 | ClosureNU: { 24 | String: "Stk[Inst[OP_A]]=Wrap(Proto[Inst[OP_B]],nil,Env);", 25 | Create: function(instruction) { 26 | return instruction 27 | } 28 | } 29 | } 30 | 31 | /* 32 | local NewProto = Proto[Inst[OP_B]]; 33 | local NewUvals; 34 | local Indexes = {}; 35 | NewUvals = Setmetatable({}, { 36 | __index = function(_, Key) 37 | local Val = Indexes[Key]; 38 | return Val[1][Val[2]]; 39 | end, 40 | __newindex = function(_, Key, Value) 41 | local Val = Indexes[Key] 42 | Val[1][Val[2]] = Value; 43 | end; 44 | }); 45 | for Idx = 1, Inst[OP_C] do 46 | InstrPoint = InstrPoint + 1; 47 | local Mvm = Instr[InstrPoint]; 48 | if Mvm[OP_ENUM] == OP_MOVE then 49 | Indexes[Idx - 1] = { 50 | Stk, 51 | Mvm[OP_B] 52 | }; 53 | else 54 | Indexes[Idx - 1] = { 55 | Upvalues, 56 | Mvm[OP_B] 57 | }; 58 | end; 59 | Lupvals[#Lupvals + 1] = Indexes; 60 | end; 61 | Stk[Inst[OP_A]] = Wrap(NewProto, NewUvals, Env); 62 | */ -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | const chalk = require("chalk") 3 | const luamin = require("./utility/luamin") 4 | 5 | const inputFile = "./input.lua" 6 | const outputFile = "output.luac" 7 | 8 | let script = fs.readFileSync(inputFile, "utf8") 9 | let parsed, bytecode 10 | 11 | /// console.log(script) 12 | 13 | /*script = script.replace(/[_\-a-zA-Z0-9]+ ?\+= ?[_\-a-zA-Z0-9]+/g, (match) => { 14 | let perameters = match.split("+=") 15 | let x = perameters[0], y = perameters[1] 16 | 17 | return ` ${x} = ${x} + ${y} ` // "ADDITION_ASSIGNMENT" 18 | }).replace(/[_\-a-zA-Z0-9]+ ?\*= ?[_\-a-zA-Z0-9]+/g, (match) => { 19 | let perameters = match.split("*=") 20 | let x = perameters[0], y = perameters[1] 21 | 22 | return ` ${x} = ${x} * ${y} ` // "MULTIPLICATION_ASSIGNMENT" 23 | }).replace(/[_\-a-zA-Z0-9]+ ?\-= ?[_\-a-zA-Z0-9]+/g, (match) => { 24 | let perameters = match.split("-=") 25 | let x = perameters[0], y = perameters[1] 26 | 27 | return ` ${x} = ${x} - ${y} ` // "SUBTRACTION_ASSIGNMENT" 28 | })*/ 29 | 30 | // script = luamin.Beautify(script, {RenameVariables: true}) 31 | 32 | try { 33 | process.stdout.write(`[${chalk.blueBright("INFO")}] Generating Syntax Tree...`) 34 | parsed = luamin.Parse(script)//[0] 35 | console.log(` ${chalk.greenBright("Success")}`) 36 | } catch { 37 | return console.log(` ${chalk.redBright("Syntax Error")}`) 38 | } 39 | 40 | try { 41 | process.stdout.write(`[${chalk.blueBright("INFO")}] Beautifying Syntax Tree...`) 42 | parsed = luamin.BeautifyAst(parsed, {RenameVariables: true, Format: true}) 43 | console.log(` ${chalk.greenBright("Success")}`) 44 | } catch (err) { 45 | console.log(err) 46 | console.log(` ${chalk.redBright("Failed")}`) 47 | 48 | return 49 | } 50 | 51 | // console.log(luamin.Print(parsed)) 52 | 53 | fs.readdirSync("./obfuscators").forEach(obfuscator => { 54 | const deobfuscator = require(`./obfuscators/${obfuscator}/deobfuscate`) 55 | 56 | if (deobfuscator.detect(script)) { 57 | console.log(`[${chalk.blueBright("INFO")}] Detected obfuscator: ${deobfuscator.name}`) 58 | bytecode = deobfuscator.deobfuscate(parsed) 59 | return 60 | } 61 | }) 62 | 63 | if (bytecode != undefined) { 64 | fs.writeFileSync(outputFile, bytecode, "utf8") 65 | } else { 66 | throw "Failed to detect obfuscator" 67 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Eq.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Eq: { 3 | String: "if(Stk[Inst[OP_A]]==Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.A 6 | instruction.A = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | EqB: { 12 | String: "if(Inst[OP_A] == Stk[Inst[OP_C]]) then InstrPoint = InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.A + 255 15 | instruction.A = 0 16 | 17 | return instruction 18 | } 19 | }, 20 | EqC: { 21 | String: "if(Stk[Inst[OP_A]] == Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 22 | Create: function(instruction) { 23 | instruction.B = instruction.A 24 | instruction.C += 255 25 | instruction.A = 0 26 | 27 | return instruction 28 | } 29 | }, 30 | EqBC: { 31 | String: "if(Inst[OP_A] == Inst[OP_C]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 32 | Create: function(instruction) { 33 | instruction.B = instruction.A + 255 34 | instruction.C += 255 35 | instruction.A = 0 36 | 37 | return instruction 38 | } 39 | }, 40 | Ne: { 41 | String: "if(Stk[Inst[OP_A]]~=Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 42 | Create: function(instruction) { 43 | instruction.B = instruction.A 44 | instruction.A = 1 45 | 46 | return instruction 47 | } 48 | }, 49 | NeB: { 50 | String: "if(Inst[OP_A] ~= Stk[Inst[OP_C]]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 51 | Create: function(instruction) { 52 | instruction.B = instruction.A + 255 53 | instruction.A = 1 54 | 55 | return instruction 56 | } 57 | }, 58 | NeC: { 59 | String: "if(Stk[Inst[OP_A]] ~= Inst[OP_C]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 60 | Create: function(instruction) { 61 | instruction.B = instruction.A 62 | instruction.C += 255 63 | instruction.A = 1 64 | 65 | return instruction 66 | } 67 | }, 68 | NeBC: { 69 | String: "if(Inst[OP_A] ~= Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 70 | Create: function(instruction) { 71 | instruction.B = instruction.A + 255 72 | instruction.C += 255 73 | instruction.A = 1 74 | 75 | return instruction 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Eq.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Eq: { 3 | String: "if(Stk[Inst[OP_A]]==Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.A 6 | instruction.A = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | EqB: { 12 | String: "if(Inst[OP_A] == Stk[Inst[OP_C]]) then InstrPoint = InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.A + 255 15 | instruction.A = 0 16 | 17 | return instruction 18 | } 19 | }, 20 | EqC: { 21 | String: "if(Stk[Inst[OP_A]] == Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 22 | Create: function(instruction) { 23 | instruction.B = instruction.A 24 | instruction.C += 255 25 | instruction.A = 0 26 | 27 | return instruction 28 | } 29 | }, 30 | EqBC: { 31 | String: "if(Inst[OP_A] == Inst[OP_C]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 32 | Create: function(instruction) { 33 | instruction.B = instruction.A + 255 34 | instruction.C += 255 35 | instruction.A = 0 36 | 37 | return instruction 38 | } 39 | }, 40 | Ne: { 41 | String: "if(Stk[Inst[OP_A]]~=Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 42 | Create: function(instruction) { 43 | instruction.B = instruction.A 44 | instruction.A = 1 45 | 46 | return instruction 47 | } 48 | }, 49 | NeB: { 50 | String: "if(Inst[OP_A] ~= Stk[Inst[OP_C]]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 51 | Create: function(instruction) { 52 | instruction.B = instruction.A + 255 53 | instruction.A = 1 54 | 55 | return instruction 56 | } 57 | }, 58 | NeC: { 59 | String: "if(Stk[Inst[OP_A]] ~= Inst[OP_C]) then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 60 | Create: function(instruction) { 61 | instruction.B = instruction.A 62 | instruction.C += 255 63 | instruction.A = 1 64 | 65 | return instruction 66 | } 67 | }, 68 | NeBC: { 69 | String: "if(Inst[OP_A] ~= Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 70 | Create: function(instruction) { 71 | instruction.B = instruction.A + 255 72 | instruction.C += 255 73 | instruction.A = 1 74 | 75 | return instruction 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Eq.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Eq: { 3 | String: "if(Stk[Inst[OP_A]]==Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 4 | Create: function(instruction) { 5 | instruction.B = instruction.A 6 | instruction.A = 0 7 | 8 | return instruction 9 | } 10 | }, 11 | EqB: { 12 | String: "if(Const[Inst[OP_A]] == Stk[Inst[OP_C]]) then InstrPoint = InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 13 | Create: function(instruction) { 14 | instruction.B = instruction.A + 255 15 | instruction.A = 0 16 | 17 | return instruction 18 | } 19 | }, 20 | EqC: { 21 | String: "if(Stk[Inst[OP_A]] == Const[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 22 | Create: function(instruction) { 23 | instruction.B = instruction.A 24 | instruction.C += 255 25 | instruction.A = 0 26 | 27 | return instruction 28 | } 29 | }, 30 | EqBC: { 31 | String: "if(Const[Inst[OP_A]] == Const[Inst[OP_C]]) then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 32 | Create: function(instruction) { 33 | instruction.B = instruction.A + 255 34 | instruction.C += 255 35 | instruction.A = 0 36 | 37 | return instruction 38 | } 39 | }, 40 | Ne: { 41 | String: "if(Stk[Inst[OP_A]]~=Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 42 | Create: function(instruction) { 43 | instruction.B = instruction.A 44 | instruction.A = 1 45 | 46 | return instruction 47 | } 48 | }, 49 | NeB: { 50 | String: "if(Const[Inst[OP_A]] ~= Stk[Inst[OP_C]]) then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 51 | Create: function(instruction) { 52 | instruction.B = instruction.A + 255 53 | instruction.A = 1 54 | 55 | return instruction 56 | } 57 | }, 58 | NeC: { 59 | String: "if(Stk[Inst[OP_A]] ~= Const[Inst[OP_C]]) then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 60 | Create: function(instruction) { 61 | instruction.B = instruction.A 62 | instruction.C += 255 63 | instruction.A = 1 64 | 65 | return instruction 66 | } 67 | }, 68 | NeBC: { 69 | String: "if(Const[Inst[OP_A]] ~= Const[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=InstrPoint+Inst[OP_B];end;", 70 | Create: function(instruction) { 71 | instruction.B = instruction.A + 255 72 | instruction.C += 255 73 | instruction.A = 1 74 | 75 | return instruction 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Lt.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Lt: { 3 | Thorough: true, 4 | String: "if(Stk[Inst[OP_A]] < Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 5 | Create: function(instruction) { 6 | instruction.B = instruction.A 7 | instruction.A = 0 8 | 9 | return instruction 10 | } 11 | }, 12 | LtB: { 13 | Thorough: true, 14 | String: "if(Inst[OP_A] < Stk[Inst[OP_C]])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 15 | Create: function(instruction) { 16 | instruction.B = instruction.A + 255 17 | instruction.A = 0 18 | 19 | return instruction 20 | } 21 | }, 22 | LtC: { 23 | Thorough: true, 24 | String: "if(Stk[Inst[OP_A]] < Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 25 | Create: function(instruction) { 26 | instruction.B = instruction.A 27 | instruction.C += 255 28 | instruction.A = 0 29 | 30 | return instruction 31 | } 32 | }, 33 | LtBC: { 34 | Thorough: true, 35 | String: "if(Inst[OP_A] < Inst[OP_C])then InstrPoint=InstrPoint+1;else InstrPoint=Inst[OP_B];end;", 36 | Create: function(instruction) { 37 | instruction.B = instruction.A + 255 38 | instruction.C += 255 39 | instruction.A = 0 40 | 41 | return instruction 42 | } 43 | }, 44 | Ge: { 45 | Thorough: true, 46 | String: "if (Stk[Inst[OP_A]] String.fromCharCode(i)) 25 | const bytes = [] 26 | 27 | let position = 0 28 | let current 29 | 30 | while (position < bytestring.length) { 31 | const length = parseInt(bytestring[position], 36) 32 | position++ 33 | const entry = parseInt(bytestring.substring(position, position + length), 36) 34 | position += length 35 | let word 36 | 37 | if (current == undefined) { 38 | current = String.fromCharCode(entry) 39 | bytes.push(current) 40 | continue 41 | } 42 | 43 | if (words[entry]) { 44 | word = words[entry] 45 | } else { 46 | word = current + current[0] 47 | } 48 | 49 | words.push(current + word[0]) 50 | bytes.push(word) 51 | current = word 52 | } 53 | 54 | return Buffer.from(bytes.map(v => v.split("").map(x => x.charCodeAt(0) ^ key)).flat()) 55 | } 56 | 57 | function decode(bytestring, key) { 58 | const encoded = bytestring.split("\\") 59 | const bytes = [] 60 | 61 | for (let i = 0; i < encoded.length; i++) { 62 | bytes[i] = encoded[i] ^ key 63 | } 64 | 65 | return Buffer.from(bytes) 66 | } 67 | 68 | function expression(lhs, operator, rhs) { // p1000 69 | switch (operator) { 70 | case "==" : return lhs == rhs 71 | case "~=" : return lhs != rhs 72 | case "<=" : return lhs <= rhs 73 | case ">=" : return lhs >= rhs 74 | case "<" : return lhs < rhs 75 | case ">" : return lhs > rhs 76 | case "-" : return lhs - rhs 77 | case "+" : return lhs + rhs 78 | case "/" : return lhs / rhs 79 | case "^" : return lhs ^ rhs 80 | case "*" : return lhs * rhs 81 | case "%" : return lhs % rhs 82 | } 83 | 84 | throw `Unsupported operator ${operator}` 85 | } 86 | 87 | function gbit(bit, start, end) { // (bit >> start) & (end - 1) wasnt working??? extract_int_from_bit 88 | if (end) { 89 | const res = (bit / 2 ** (start - 1)) % 2 ** ((end - 1) - (start - 1) + 1) 90 | 91 | return res - res % 1 92 | } else { 93 | throw "no ended bit??" 94 | } 95 | } 96 | 97 | module.exports = { 98 | unopexpr, 99 | expression, 100 | decompress, 101 | decode, 102 | gbit 103 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/emulation.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | const chalk = require("chalk") 3 | const substring = require("unicode-substring") 4 | 5 | function decompress(compressedStr) { // very slow 6 | let codeDictSize = 1; 7 | let currentCharCode = 16; 8 | let codeDict = { 9 | codes: [], 10 | values: [] 11 | }; 12 | let dictIndex = -1; 13 | let currentIndex = currentCharCode + 1; 14 | 15 | while (true) { 16 | codeDict[substring(compressedStr, currentIndex - 1, (function() { 17 | currentIndex = codeDictSize + currentIndex 18 | return currentIndex - 1 19 | })())] = (function() { 20 | dictIndex = dictIndex + 1 21 | return dictIndex 22 | })() 23 | if (dictIndex == (16 - 1)) { 24 | dictIndex = ""; 25 | currentCharCode = 0; 26 | break 27 | } 28 | } 29 | let compressedLength = compressedStr.length 30 | while (currentIndex < compressedLength + 1) { 31 | codeDict.values[currentCharCode] = substring(compressedStr, currentIndex - 1, (function() { 32 | currentIndex = codeDictSize + currentIndex 33 | return currentIndex - 1 34 | })()) 35 | currentCharCode = currentCharCode + 1 36 | if (currentCharCode % 2 == 0) { 37 | currentCharCode = 0 38 | codeDict.codes.push(String.fromCharCode((codeDict[codeDict.values[0]] * 16) + codeDict[codeDict.values[1]])) 39 | } 40 | } 41 | return Array.from(codeDict.codes.join("")).map(char => char.charCodeAt(0)) 42 | } 43 | 44 | function string(str) { // parse a lua string 45 | return str.replace(/\\([0-9]+)/g, (match, byte) => { 46 | return String.fromCharCode(Number(byte)) 47 | }) 48 | } 49 | 50 | function decrypt_constant(A0_12, A2_14) { 51 | A0_12 = string(A0_12) 52 | 53 | let L3_15 = 1 54 | let L4_16 = "" 55 | for (let L8_20 = 0; L8_20 < A0_12.length; L8_20++) { 56 | L4_16 = L4_16 + String.fromCharCode((substring(A0_12, L8_20, L8_20 + 1).charCodeAt(0) + L3_15) % 256) 57 | L3_15 = (L3_15 + A2_14) % 256 58 | } 59 | return L4_16 60 | } 61 | 62 | // console.log(decrypt_constant("b \\209\\137,\\231\\159", 78)) -> "content" 63 | // ironbrew string encryption is far better than this? 64 | 65 | function encode_string(string) { // p1000 66 | let bytes = string.split("") 67 | 68 | return bytes.map(byte => { 69 | return `\\${byte.charCodeAt(0)}` 70 | }).join("") 71 | } 72 | 73 | function expression(lhs, operator, rhs) { // p1000 74 | switch (operator) { 75 | case "==" : return lhs == rhs 76 | case "~=" : return lhs != rhs 77 | case "<=" : return lhs <= rhs 78 | case ">=" : return lhs >= rhs 79 | case "<" : return lhs < rhs 80 | case ">" : return lhs > rhs 81 | case "-" : return lhs - rhs 82 | case "+" : return lhs + rhs 83 | case "/" : return lhs / rhs 84 | case "^" : return lhs ** rhs 85 | case "*" : return lhs * rhs 86 | case "%" : return lhs % rhs 87 | case "and" : return lhs && rhs 88 | case "or" : return lhs || rhs 89 | case ".." : return String(lhs) + String(rhs) // lua p100 90 | case "-=" : return lhs -= rhs 91 | } 92 | 93 | throw `Unsupported operator ${operator}` 94 | } 95 | 96 | module.exports = { 97 | decrypt_constant, 98 | encode_string, 99 | expression, 100 | decompress, 101 | // decode, 102 | string 103 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.1/Call.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Call: { 3 | String: `local A = Inst[OP_A] 4 | local Results = { Stk[A](Unpack(Stk, A + 1, Inst[OP_B])) }; 5 | local Edx = 0; 6 | for Idx = A, Inst[OP_C] do 7 | Edx = Edx + 1; 8 | Stk[Idx] = Results[Edx]; 9 | end`, 10 | Create: function(instruction) { 11 | instruction.B = instruction.B - instruction.A + 1 12 | instruction.C = instruction.C - instruction.A + 2 13 | 14 | return instruction 15 | } 16 | }, 17 | CallB2: { 18 | String: `local A = Inst[OP_A] 19 | local Results = { Stk[A](Stk[A + 1]) }; 20 | local Edx = 0; 21 | for Idx = A, Inst[OP_C] do 22 | Edx = Edx + 1; 23 | Stk[Idx] = Results[Edx]; 24 | end`, 25 | Create: function(instruction) { 26 | instruction.C = instruction.C - instruction.A + 2 27 | 28 | return instruction 29 | } 30 | }, 31 | CallB0: { 32 | String: `local A = Inst[OP_A] 33 | local Results = { Stk[A](Unpack(Stk, A + 1, Top)) }; 34 | local Edx = 0; 35 | for Idx = A, Inst[OP_C] do 36 | Edx = Edx + 1; 37 | Stk[Idx] = Results[Edx]; 38 | end`, 39 | Create: function(instruction) { 40 | instruction.C = instruction.C - instruction.A + 2 41 | 42 | return instruction 43 | } 44 | }, 45 | CallB1: { 46 | String: `local A = Inst[OP_A] 47 | local Results = { Stk[A]() }; 48 | local Limit = Inst[OP_C]; 49 | local Edx = 0; 50 | for Idx = A, Limit do 51 | Edx = Edx + 1; 52 | Stk[Idx] = Results[Edx]; 53 | end`, 54 | Create: function(instruction) { 55 | instruction.C = instruction.C - instruction.A + 2 56 | 57 | return instruction 58 | } 59 | }, 60 | CallC0: { 61 | String: `local A = Inst[OP_A] 62 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))) 63 | Top = Limit + A - 1 64 | local Edx = 0; 65 | for Idx = A, Top do 66 | Edx = Edx + 1; 67 | Stk[Idx] = Results[Edx]; 68 | end;`, 69 | Create: function(instruction) { 70 | instruction.B = instruction.B - instruction.A + 1 71 | 72 | return instruction 73 | } 74 | }, 75 | CallC0B2: { 76 | String: `local A = Inst[OP_A] 77 | local Results, Limit = _R(Stk[A](Stk[A + 1])) 78 | Top = Limit + A - 1 79 | local Edx = 0; 80 | for Idx = A, Top do 81 | Edx = Edx + 1; 82 | Stk[Idx] = Results[Edx]; 83 | end;`, 84 | Create: function(instruction) { 85 | instruction.B = instruction.B - instruction.A + 1 86 | 87 | return instruction 88 | } 89 | }, 90 | CallC1: { 91 | String: "local A = Inst[OP_A]\nStk[A](Unpack(Stk, A + 1, Inst[OP_B]))", 92 | Create: function(instruction) { 93 | instruction.B = instruction.B - instruction.A + 1 94 | 95 | return instruction 96 | } 97 | }, 98 | CallC1B2: { 99 | String: "local A = Inst[OP_A]\nStk[A](Stk[A + 1])", 100 | Create: function(instruction) { 101 | return instruction 102 | } 103 | }, 104 | CallB0C0: { 105 | String: `local A = Inst[OP_A] 106 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Top))) 107 | Top = Limit + A - 1 108 | local Edx = 0; 109 | for Idx = A, Top do 110 | Edx = Edx + 1; 111 | Stk[Idx] = Results[Edx]; 112 | end;`, 113 | Create: function(instruction) { 114 | return instruction 115 | } 116 | }, 117 | 118 | CallB0C1: { 119 | String: "local A = Inst[OP_A]\nStk[A](Unpack(Stk, A + 1, Top))", 120 | Create: function(instruction) { 121 | return instruction 122 | } 123 | }, 124 | CallB1C0: { 125 | String: `local A = Inst[OP_A] 126 | local Results, Limit = _R(Stk[A]()) 127 | Top = Limit + A - 1 128 | local Edx = 0; 129 | for Idx = A, Top do 130 | Edx = Edx + 1; 131 | Stk[Idx] = Results[Edx]; 132 | end;`, 133 | Create: function(instruction) { 134 | return instruction 135 | } 136 | }, 137 | CallB1C1: { 138 | String: "Stk[Inst[OP_A]]();", 139 | Create: function(instruction) { 140 | return instruction 141 | } 142 | }, 143 | 144 | CallC2: { 145 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))", 146 | Create: function(instruction) { 147 | instruction.B = instruction.B - instruction.A + 1 148 | 149 | return instruction 150 | } 151 | }, 152 | CallC2B2: { 153 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Stk[A + 1]) ", 154 | Create: function(instruction) { 155 | return instruction 156 | } 157 | }, 158 | CallB0C2: { 159 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Top))", 160 | Create: function(instruction) { 161 | return instruction 162 | } 163 | }, 164 | CallB1C2: { 165 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A]()", 166 | Create: function(instruction) { 167 | return instruction 168 | } 169 | }, 170 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/opcodes/Call.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Call: { 3 | String: `local A = Inst[OP_A] 4 | local Results = { Stk[A](Unpack(Stk, A + 1, Inst[OP_B])) }; 5 | local Edx = 0; 6 | for Idx = A, Inst[OP_C] do 7 | Edx = Edx + 1; 8 | Stk[Idx] = Results[Edx]; 9 | end`, 10 | Create: function(instruction) { 11 | instruction.B = instruction.B - instruction.A + 1 12 | instruction.B = instruction.B - instruction.A + 1 13 | 14 | return instruction 15 | } 16 | }, 17 | CallB2: { 18 | String: `local A = Inst[OP_A] 19 | local Results = { Stk[A](Stk[A + 1]) }; 20 | local Edx = 0; 21 | for Idx = A, Inst[OP_C] do 22 | Edx = Edx + 1; 23 | Stk[Idx] = Results[Edx]; 24 | end`, 25 | Create: function(instruction) { 26 | instruction.C = instruction.C - instruction.A + 2 27 | 28 | return instruction 29 | } 30 | }, 31 | CallB0: { 32 | String: `local A = Inst[OP_A] 33 | local Results = { Stk[A](Unpack(Stk, A + 1, Top)) }; 34 | local Edx = 0; 35 | for Idx = A, Inst[OP_C] do 36 | Edx = Edx + 1; 37 | Stk[Idx] = Results[Edx]; 38 | end`, 39 | Create: function(instruction) { 40 | instruction.C = instruction.C - instruction.A + 2 41 | 42 | return instruction 43 | } 44 | }, 45 | CallB1: { 46 | String: `local A = Inst[OP_A] 47 | local Results = { Stk[A]() }; 48 | local Limit = Inst[OP_C]; 49 | local Edx = 0; 50 | for Idx = A, Limit do 51 | Edx = Edx + 1; 52 | Stk[Idx] = Results[Edx]; 53 | end`, 54 | Create: function(instruction) { 55 | instruction.C = instruction.C - instruction.A + 2 56 | 57 | return instruction 58 | } 59 | }, 60 | CallC0: { 61 | String: `local A = Inst[OP_A] 62 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))) 63 | Top = Limit + A - 1 64 | local Edx = 0; 65 | for Idx = A, Top do 66 | Edx = Edx + 1; 67 | Stk[Idx] = Results[Edx]; 68 | end;`, 69 | Create: function(instruction) { 70 | instruction.B = instruction.B - instruction.A + 1 71 | 72 | return instruction 73 | } 74 | }, 75 | CallC0B2: { 76 | String: `local A = Inst[OP_A] 77 | local Results, Limit = _R(Stk[A](Stk[A + 1])) 78 | Top = Limit + A - 1 79 | local Edx = 0; 80 | for Idx = A, Top do 81 | Edx = Edx + 1; 82 | Stk[Idx] = Results[Edx]; 83 | end;`, 84 | Create: function(instruction) { 85 | instruction.B = instruction.B - instruction.A + 1 86 | 87 | return instruction 88 | } 89 | }, 90 | CallC1: { 91 | String: "local A = Inst[OP_A]\nStk[A](Unpack(Stk, A + 1, Inst[OP_B]))", 92 | Create: function(instruction) { 93 | instruction.B = instruction.B - instruction.A + 1 94 | 95 | return instruction 96 | } 97 | }, 98 | CallC1B2: { 99 | String: "local A = Inst[OP_A]\nStk[A](Stk[A + 1])", 100 | Create: function(instruction) { 101 | return instruction 102 | } 103 | }, 104 | CallB0C0: { 105 | String: `local A = Inst[OP_A] 106 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Top))) 107 | Top = Limit + A - 1 108 | local Edx = 0; 109 | for Idx = A, Top do 110 | Edx = Edx + 1; 111 | Stk[Idx] = Results[Edx]; 112 | end;`, 113 | Create: function(instruction) { 114 | return instruction 115 | } 116 | }, 117 | 118 | CallB0C1: { 119 | String: "local A = Inst[OP_A]\nStk[A](Unpack(Stk, A + 1, Top))", 120 | Create: function(instruction) { 121 | return instruction 122 | } 123 | }, 124 | CallB1C0: { 125 | String: `local A = Inst[OP_A] 126 | local Results, Limit = _R(Stk[A]()) 127 | Top = Limit + A - 1 128 | local Edx = 0; 129 | for Idx = A, Top do 130 | Edx = Edx + 1; 131 | Stk[Idx] = Results[Edx]; 132 | end;`, 133 | Create: function(instruction) { 134 | return instruction 135 | } 136 | }, 137 | CallB1C1: { 138 | String: "Stk[Inst[OP_A]]();", 139 | Create: function(instruction) { 140 | return instruction 141 | } 142 | }, 143 | 144 | CallC2: { 145 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))", 146 | Create: function(instruction) { 147 | instruction.B = instruction.B - instruction.A + 1 148 | 149 | return instruction 150 | } 151 | }, 152 | CallC2B2: { 153 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Stk[A + 1]) ", 154 | Create: function(instruction) { 155 | return instruction 156 | } 157 | }, 158 | CallB0C2: { 159 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Top))", 160 | Create: function(instruction) { 161 | return instruction 162 | } 163 | }, 164 | CallB1C2: { 165 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A]()", 166 | Create: function(instruction) { 167 | return instruction 168 | } 169 | }, 170 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/opcodes/2.7.0/Call.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | Call: { 3 | String: `local A=Inst[OP_A];local Args={};local Edx=0;local Limit=A+Inst[OP_B]-1;for Idx=A+1,Limit do Edx=Edx+1;Args[Edx]=Stk[Idx];end;local Results={Stk[A](Unpack(Args,1,Limit-A))};local Limit=A+Inst[OP_C]-2;Edx=0;for Idx=A,Limit do Edx=Edx+1;Stk[Idx]=Results[Edx];end;Top=Limit;`, 4 | Create: function(instruction) { 5 | instruction.B = instruction.B - instruction.A + 1 6 | instruction.C = instruction.C - instruction.A + 2 7 | 8 | return instruction 9 | } 10 | }, 11 | CallB2: { 12 | String: `local A = Inst[OP_A] 13 | local Results = { Stk[A](Stk[A + 1]) }; 14 | local Edx = 0; 15 | for Idx = A, Inst[OP_C] do 16 | Edx = Edx + 1; 17 | Stk[Idx] = Results[Edx]; 18 | end`, 19 | Create: function(instruction) { 20 | instruction.C = instruction.C - instruction.A + 2 21 | 22 | return instruction 23 | } 24 | }, 25 | CallB0: { 26 | String: `local A = Inst[OP_A] 27 | local Results = { Stk[A](Unpack(Stk, A + 1, Top)) }; 28 | local Edx = 0; 29 | for Idx = A, Inst[OP_C] do 30 | Edx = Edx + 1; 31 | Stk[Idx] = Results[Edx]; 32 | end`, 33 | Create: function(instruction) { 34 | instruction.C = instruction.C - instruction.A + 2 35 | 36 | return instruction 37 | } 38 | }, 39 | CallB1: { 40 | String: `local A = Inst[OP_A]; 41 | local Results, Limit = { Stk[A]() }; 42 | local Limit = A + Inst[OP_C] - 2; 43 | local Edx = 0; 44 | for Idx = A, Limit do 45 | Edx = Edx + 1; 46 | Stk[Idx] = Results[Edx]; 47 | end; 48 | Top = Limit;`, 49 | Create: function(instruction) { 50 | instruction.C = instruction.C - instruction.A + 2 51 | 52 | return instruction 53 | } 54 | }, 55 | CallC0: { 56 | String: `local A = Inst[OP_A] 57 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))) 58 | Top = Limit + A - 1 59 | local Edx = 0; 60 | for Idx = A, Top do 61 | Edx = Edx + 1; 62 | Stk[Idx] = Results[Edx]; 63 | end;`, 64 | Create: function(instruction) { 65 | instruction.B = instruction.B - instruction.A + 1 66 | 67 | return instruction 68 | } 69 | }, 70 | CallC0B2: { 71 | String: `local A = Inst[OP_A] 72 | local Results, Limit = _R(Stk[A](Stk[A + 1])) 73 | Top = Limit + A - 1 74 | local Edx = 0; 75 | for Idx = A, Top do 76 | Edx = Edx + 1; 77 | Stk[Idx] = Results[Edx]; 78 | end;`, 79 | Create: function(instruction) { 80 | instruction.B = instruction.B - instruction.A 81 | 82 | return instruction 83 | } 84 | }, 85 | CallC1: { 86 | String: `local A=Inst[OP_A];local Args={};local Edx=0;local Limit=A+Inst[OP_B]-1;for Idx=A+1,Limit do Edx=Edx+1;Args[Edx]=Stk[Idx];end;Stk[A](Unpack(Args,1,Limit-A));Top=A;`, 87 | Create: function(instruction) { 88 | // instruction.B = instruction.B - instruction.A + 1 89 | 90 | return instruction 91 | } 92 | }, 93 | CallC1B2: { 94 | String: "local A = Inst[OP_A]\nStk[A](Stk[A + 1])", 95 | Create: function(instruction) { 96 | return instruction 97 | } 98 | }, 99 | CallB0C0: { 100 | String: `local A = Inst[OP_A] 101 | local Results, Limit = _R(Stk[A](Unpack(Stk, A + 1, Top))) 102 | Top = Limit + A - 1 103 | local Edx = 0; 104 | for Idx = A, Top do 105 | Edx = Edx + 1; 106 | Stk[Idx] = Results[Edx]; 107 | end;`, 108 | Create: function(instruction) { 109 | return instruction 110 | } 111 | }, 112 | 113 | CallB0C1: { 114 | String: "local A = Inst[OP_A]\nStk[A](Unpack(Stk, A + 1, Top))", 115 | Create: function(instruction) { 116 | return instruction 117 | } 118 | }, 119 | CallB1C0: { 120 | String: `local A = Inst[OP_A] 121 | local Results, Limit = _R(Stk[A]()) 122 | Top = Limit + A - 1 123 | local Edx = 0; 124 | for Idx = A, Top do 125 | Edx = Edx + 1; 126 | Stk[Idx] = Results[Edx]; 127 | end;`, 128 | Create: function(instruction) { 129 | return instruction 130 | } 131 | }, 132 | CallB1C1: { 133 | String: "Stk[Inst[OP_A]]();", 134 | Create: function(instruction) { 135 | return instruction 136 | } 137 | }, 138 | 139 | CallC2: { 140 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Inst[OP_B]))", 141 | Create: function(instruction) { 142 | instruction.B = instruction.B - instruction.A + 1 143 | 144 | return instruction 145 | } 146 | }, 147 | CallC2B2: { 148 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Stk[A + 1]) ", 149 | Create: function(instruction) { 150 | return instruction 151 | } 152 | }, 153 | CallB0C2: { 154 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A](Unpack(Stk, A + 1, Top))", 155 | Create: function(instruction) { 156 | return instruction 157 | } 158 | }, 159 | CallB1C2: { 160 | String: "local A = Inst[OP_A]\nStk[A] = Stk[A]()", 161 | Create: function(instruction) { 162 | return instruction 163 | } 164 | }, 165 | } -------------------------------------------------------------------------------- /utility/printer.js: -------------------------------------------------------------------------------- 1 | let get_const_str = function(consts, idx) { 2 | const constant = consts[idx] 3 | 4 | switch (typeof constant) { 5 | case "boolean": 6 | return String(constant) 7 | case "number": 8 | return constant 9 | case "string": 10 | return `"${constant}"` 11 | case "object": 12 | return "nil" 13 | } 14 | } 15 | 16 | let get_operation = function(chunk, ins) { 17 | const constants = chunk.Constants 18 | 19 | let rk = function(r) { 20 | return r > 255 ? get_const_str(constants, r - 256) : `R${r}` 21 | } 22 | 23 | switch (ins.OpName) { 24 | case "Move": 25 | return `R${ins.A} = R${ins.B}` 26 | case "LoadK": 27 | return `R${ins.A} = ${get_const_str(constants, ins.B)}` 28 | case "LoadBool": 29 | return `R${ins.A} = ${String(Boolean(ins.B))} ${ins.C != 0 ? "; goto " + (ins.PC + 2) : ""}` 30 | case "LoadNil": 31 | let src = "" 32 | 33 | for (let i = ins.A + 1; i < ins.A + ins.B; i++) { 34 | src += `R${i}, ` 35 | } 36 | 37 | src = src.substring(0, src.length - 2) 38 | 39 | return `${src} = nil` 40 | case "GetUpval": 41 | return `R${ins.A} = Upvalues[${ins.B}]` 42 | case "GetGlobal": 43 | return `R${ins.A} = _ENV[${get_const_str(constants, ins.B)}]` 44 | case "GetTable": 45 | return `R${ins.A} = R${ins.B}[${rk(ins.C)}]` 46 | case "SetUpval": 47 | return `Upvalues[${ins.B}] = R${ins.A}` 48 | case "SetGlobal": 49 | return `_ENV[${get_const_str(constants, ins.B)}] = R${ins.A}` 50 | case "SetTable": 51 | return `R${ins.A}[${rk(ins.B)}] = ${rk(ins.C)}` 52 | case "NewTable": 53 | return `R${ins.A} = {}` 54 | case "Self": 55 | return `R${ins.A + 1} = R${ins.B}; R${ins.A} = R${ins.B}[${rk(ins.C)}]` 56 | case "Add": 57 | return `R${ins.A} = ${rk(ins.B)} + ${rk(ins.C)}` 58 | case "Sub": 59 | return `R${ins.A} = ${rk(ins.B)} - ${rk(ins.C)}` 60 | case "Mul": 61 | return `R${ins.A} = ${rk(ins.B)} * ${rk(ins.C)}` 62 | case "Div": 63 | return `R${ins.A} = ${rk(ins.B)} / ${rk(ins.C)}` 64 | case "Mod": 65 | return `R${ins.A} = ${rk(ins.B)} % ${rk(ins.C)}` 66 | case "Pow": 67 | return `R${ins.A} = ${rk(ins.B)} ^ ${rk(ins.C)}` 68 | case "Unm": 69 | return `R${ins.A} = -R${ins.B}` 70 | case "Not": 71 | return `R${ins.A} = not R${ins.B}` 72 | case "Len": 73 | return `R${ins.A} = #R${ins.B}` 74 | case "Concat": 75 | return `R${ins.A} = R${ins.B} .. R${ins.C}` 76 | case "Jmp": 77 | return `goto ${ins.PC + ins.B + 1}` 78 | case "Eq": 79 | return `if ${rk(ins.B)} ${ins.A == 0 ? "==" : "~="} ${rk(ins.C)} goto ${ins.PC + 2}`; 80 | case "Lt": 81 | return `if ${rk(ins.B)} ${ins.A == 0 ? "< " : "> "} ${rk(ins.C)} goto ${ins.PC + 2}`; 82 | case "Le": 83 | return `if ${rk(ins.B)} ${ins.A == 0 ? "<=" : ">="} ${rk(ins.C)} goto ${ins.PC + 2}`; 84 | case "Test": 85 | return `` 86 | case "TestSet": 87 | return `` 88 | case "Call": 89 | let str = "" 90 | 91 | if (ins.C == 0) { 92 | str += `R${ins.A + 1} -> ??? = ` 93 | } else if (ins.C == 1) { 94 | 95 | } else { 96 | // str += `R${ins.A} -> R${ins.A + ins.C - 2} = ` 97 | 98 | for (let i = ins.A; i < ins.A + ins.C - 1; i++) { 99 | str += `R${i}, ` 100 | } 101 | 102 | str = str.substring(0, str.length - 2) 103 | str += " = " 104 | } 105 | 106 | str += `R${ins.A}(` 107 | 108 | if (ins.B == 0) { 109 | str += `R${ins.A} -> R${chunk.Registers}` 110 | } else if (ins.B == 1) { 111 | 112 | } else { 113 | // str += `R${ins.A + 1} -> R${ins.A + ins.B - 1}` 114 | 115 | for (let i = ins.A + 1; i < ins.A + ins.B; i++) { 116 | str += `R${i}, ` 117 | } 118 | 119 | str = str.substring(0, str.length - 2) 120 | } 121 | 122 | return str + ")" 123 | } 124 | } 125 | 126 | module.exports = function(devirtualized) { 127 | let chunk_count = 1 128 | 129 | console.log(" ") 130 | 131 | let do_print = function(chunk, depth) { 132 | const padding = "\t".repeat(depth) 133 | const chunk_idx = chunk_count 134 | 135 | chunk_count += 1 136 | 137 | console.log(padding + `function func${chunk_idx}(${Array.from({length: chunk.Parameters}, (_, i) => `arg${i + 1}`).join(", ")})`) 138 | console.log() 139 | 140 | for (let i = 0; i < chunk.Constants.length; i++) { 141 | let constant = chunk.Instructions[i] 142 | 143 | console.log(padding + `\t.const ${get_const_str(chunk.Constants, i)}`) 144 | } 145 | 146 | console.log() 147 | 148 | let longest_opname = -1 149 | let counter_len = String(chunk.Instructions.length).length 150 | 151 | for (let i = 0; i < chunk.Instructions.length; i++) { 152 | let instruction = chunk.Instructions[i] 153 | let instruction_len = instruction.OpName.length 154 | 155 | if (instruction_len > longest_opname) { 156 | longest_opname = instruction_len 157 | } 158 | } 159 | 160 | for (let i = 0; i < chunk.Instructions.length; i++) { 161 | let instruction = chunk.Instructions[i] 162 | 163 | let info = get_operation(chunk, instruction) 164 | 165 | info = info ? " | " + info : "" 166 | 167 | // console.log(instruction) 168 | 169 | console.log(padding + `\t[${String(i).padStart(counter_len, "0")}] => ${instruction.OpName.padStart(longest_opname)}: { -, -, - }${info}`) 170 | } 171 | 172 | console.log() 173 | 174 | for (let i = 0; i < chunk.Prototypes.length; i++) { 175 | do_print(chunk.Prototypes[i], depth + 1) 176 | } 177 | 178 | console.log(padding + "end") 179 | } 180 | 181 | do_print(devirtualized, 0) 182 | } -------------------------------------------------------------------------------- /utility/binary.js: -------------------------------------------------------------------------------- 1 | const { SmartBuffer } = require("smart-buffer") 2 | 3 | const OpCodes = [ 4 | "Move", 5 | "LoadK", 6 | "LoadBool", 7 | "LoadNil", 8 | "GetUpval", 9 | "GetGlobal", 10 | "GetTable", 11 | "SetGlobal", 12 | "SetUpval", 13 | "SetTable", 14 | "NewTable", 15 | "Self", 16 | "Add", 17 | "Sub", 18 | "Mul", 19 | "Div", 20 | "Mod", 21 | "Pow", 22 | "Unm", 23 | "Not", 24 | "Len", 25 | "Concat", 26 | "Jmp", 27 | "Eq", 28 | "Lt", 29 | "Le", 30 | "Test", 31 | "TestSet", 32 | "Call", 33 | "TailCall", 34 | "Return", 35 | "ForLoop", 36 | "ForPrep", 37 | "TForLoop", 38 | "SetList", 39 | "Close", 40 | "Closure", 41 | "VarArg" 42 | ] 43 | 44 | const OpCodeTypes = [ 45 | "AB", // Move 46 | "ABx", // LoadK 47 | "ABC", // LoadBool 48 | "AB", // LoadNil 49 | "AB", // GetUpval 50 | "ABx", // GetGlobal 51 | "ABC", // GetTable 52 | "ABx", // SetGlobal 53 | "AB", // SetUpval 54 | "ABC", // SetTable 55 | "ABC", // NewTable 56 | "ABC", // Self 57 | "ABC", // Add 58 | "ABC", // Sub 59 | "ABC", // Mul 60 | "ABC", // Div 61 | "ABC", // Mod 62 | "ABC", // Pow 63 | "AB", // Unm 64 | "AB", // Not 65 | "AB", // Len 66 | "ABC", // Concat 67 | "sBx", // Jmp 68 | "ABC", // Eq 69 | "ABC", // Lt 70 | "ABC", // Le 71 | "AC", // Test 72 | "ABC", // TestSet 73 | "ABC", // Call 74 | "ABC", // TailCall 75 | "AB", // Return 76 | "AsBx", // ForLoop 77 | "AsBx", // ForPrep 78 | "AC", // TForLoop 79 | "ABC", // SetList 80 | "A", // Close 81 | "ABx", // Closure 82 | "AB" // VarArg 83 | ] 84 | 85 | function maskSize(value, size) { 86 | value = value & ((1 << size) - 1) 87 | return value 88 | } 89 | 90 | /** 91 | * 92 | * @param {SmartBuffer} buffer 93 | */ 94 | function writeString(buffer, str) { 95 | buffer.writeUInt32LE(str.length + 1) 96 | buffer.writeStringNT(str, "ascii") 97 | } 98 | 99 | function writeHeader(buffer) { 100 | buffer.writeString("\x1bLua") 101 | buffer.writeUInt8(0x51) 102 | buffer.writeUInt8(0) 103 | buffer.writeUInt8(1) 104 | buffer.writeUInt8(4) 105 | buffer.writeUInt8(4) 106 | buffer.writeUInt8(4) 107 | buffer.writeUInt8(8) 108 | buffer.writeUInt8(0) 109 | } 110 | 111 | function writeChunkHeader(buffer, chunk) { 112 | writeString(buffer, chunk.Top ? "@Peak#7550" : "") 113 | 114 | buffer.writeUInt32LE(0) 115 | buffer.writeUInt32LE(0) 116 | buffer.writeUInt8(0) 117 | buffer.writeUInt8(chunk.Parameters) 118 | buffer.writeUInt8(chunk.VarArg ? 3 : 2) 119 | //console.log(chunk.Registers) 120 | //buffer.writeUInt8(255) // cba to count the number of registers becuaes idk if its right 121 | 122 | let max_stack_size = 0 123 | 124 | for (let i = 0; i < chunk.Instructions.length; i++) { 125 | if (chunk.Instructions[i].A + 1 > max_stack_size) { 126 | max_stack_size = chunk.Instructions[i].A + 1 127 | } 128 | } 129 | 130 | buffer.writeUInt8(max_stack_size) 131 | 132 | } 133 | 134 | function writeConstant(buffer, constant) { 135 | //console.log("const.", typeof constant, ":", constant) 136 | switch (typeof constant) { 137 | case "boolean": 138 | buffer.writeUInt8(1) 139 | buffer.writeUInt8(Number(constant)) 140 | break; 141 | case "number": 142 | buffer.writeUInt8(3) 143 | buffer.writeDoubleLE(constant) 144 | break; 145 | case "string": 146 | buffer.writeUInt8(4) 147 | writeString(buffer, constant) 148 | break; 149 | case "object": 150 | buffer.writeUInt8(0) 151 | break; 152 | default: 153 | throw (`Attempt to write constant with invalid type "${typeof constant}"`) 154 | } 155 | } 156 | 157 | function writeInstruction(buffer, instruction) { 158 | let data = instruction.OpCode 159 | 160 | switch (instruction.Type) { 161 | case "A": 162 | data = data | maskSize(instruction.A, 8) << 6; 163 | break; 164 | case "AB": 165 | data = data | maskSize(instruction.A, 8) << 6; 166 | data = data | maskSize(instruction.B, 9) << 23; 167 | break; 168 | case "AC": 169 | data = data | maskSize(instruction.A, 8) << 6; 170 | data = data | maskSize(instruction.C, 9) << 14; 171 | break; 172 | case "ABC": 173 | data = data | maskSize(instruction.A, 8) << 6; 174 | data = data | maskSize(instruction.B, 9) << 23; 175 | data = data | maskSize(instruction.C, 9) << 14; 176 | break; 177 | case "ABx": 178 | data = data | maskSize(instruction.A, 8) << 6; 179 | data = data | maskSize(instruction.B, 18) << 14; 180 | break; 181 | case "AsBx": 182 | data = data | maskSize(instruction.A, 8) << 6; 183 | data = data | maskSize(instruction.B + 131071, 18) << 14; 184 | break; 185 | case "sBx": 186 | data = data | maskSize(instruction.B + 131071, 18) << 14; 187 | break; 188 | } 189 | 190 | data = data >>> 0 // Unsigned Right Shift Operator (convert to uint32 cus life sucks) 191 | buffer.writeUInt32LE(data); 192 | } 193 | 194 | function writeChunkFooter(buffer) { 195 | buffer.writeUInt32LE(0) 196 | buffer.writeUInt32LE(0) 197 | buffer.writeUInt32LE(0) 198 | } 199 | 200 | function writeLength(buffer, length) { 201 | buffer.writeUInt32LE(length) 202 | } 203 | 204 | function sterilize(topchunk) { 205 | const bytecode = new SmartBuffer() 206 | 207 | writeHeader(bytecode) 208 | 209 | function write(chunk) { 210 | writeChunkHeader(bytecode, chunk) 211 | 212 | writeLength(bytecode, chunk.Instructions.length) 213 | 214 | for (let i = 0; i < chunk.Instructions.length; i++) { 215 | writeInstruction(bytecode, chunk.Instructions[i]) 216 | } 217 | 218 | writeLength(bytecode, chunk.Constants.length) 219 | 220 | for (let i = 0; i < chunk.Constants.length; i++) { 221 | writeConstant(bytecode, chunk.Constants[i]) 222 | } 223 | 224 | writeLength(bytecode, chunk.Prototypes.length) 225 | 226 | for (let i = 0; i < chunk.Prototypes.length; i++) { 227 | write(chunk.Prototypes[i]) 228 | } 229 | 230 | writeChunkFooter(bytecode) 231 | } 232 | 233 | write(topchunk) 234 | 235 | return bytecode.toBuffer() 236 | } 237 | 238 | module.exports = {sterilize, OpCodeTypes, OpCodes} -------------------------------------------------------------------------------- /obfuscators/ironbrew/analyze.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const emulation = require("./emulation") 3 | const SmartBuffer = require("smart-buffer").SmartBuffer 4 | 5 | function getstr(StringLiteral) { 6 | return StringLiteral.Token.Source.match(/(?<=['"[\]])[A-Z0-9\\]+=*/g)[0] 7 | } 8 | 9 | module.exports = function(body, debug) { 10 | if (debug) console.log("") 11 | 12 | const isAztup = body[0].Type == "ReturnStat" 13 | // if (debug) console.log(`[${chalk.yellow("DEBUG")}] Version: ${isAztup ? "AztupBrew" : "IronBrew"}`) 14 | 15 | const statements = isAztup ? body[0].ExprList[0].Base.Expression.Body.StatementList : body 16 | const functions = statements.filter(s=>s.Type=="LocalFunctionStat") 17 | const varaibles = statements.filter(s=>s.Type=="LocalVarStat") 18 | 19 | const gBits16 = functions.find(s=> { 20 | const bufferPosMods = s.FunctionStat.Body.StatementList.filter(x=>x.Type=="AssignmentStat") 21 | 22 | if (bufferPosMods) { 23 | for (let k = 0; k < bufferPosMods.length; k++) { 24 | const bufferPosMod = bufferPosMods[k] 25 | 26 | if (bufferPosMod && bufferPosMod.Rhs[0].Type == "BinopExpr") { 27 | let addStat = bufferPosMod.Rhs[0] 28 | 29 | if (addStat.Rhs.Type == "NumberLiteral" && addStat.Rhs.Token.Source == "2") { 30 | return true 31 | } 32 | } 33 | } 34 | } 35 | }) 36 | 37 | const version = `${isAztup ? "AztupBrew" : "IronBrew"} V2.7.${isAztup ? 2 : (gBits16 ? 1 : 0)}` 38 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] Version: ${version}`) 39 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] bit16: '${gBits16 ? gBits16.FunctionStat.NameChain[0].Source : "null"}'`) 40 | 41 | const gbits32 = functions.find(s => s.FunctionStat.Body.StatementList.length > 1 && s.FunctionStat.Body.StatementList[1].Type == "AssignmentStat") 42 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] bit32: '${gbits32.FunctionStat.NameChain[0].Source}'`) 43 | 44 | const xorkey = parseInt(gbits32.FunctionStat.Body.StatementList[1].Rhs[0].FunctionArguments.ArgList[1].Token.Source) 45 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] XorKeyA: ${xorkey}`) 46 | 47 | const compression = functions[0].FunctionStat.Body.StatementList.length >= 3 48 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] Compressed: ${compression ? "True" : "False"}`) 49 | 50 | const bytestring = getstr(compression ? varaibles.find(s=>s.ExprList[0].Type=="CallExpr").ExprList[0].FunctionArguments.ArgList[0] : varaibles.find(s=>s.ExprList[0].Type=="StringLiteral").ExprList[0]) 51 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] ByteString: ${bytestring.substring(0, 7)}...`) 52 | 53 | const bytecode = compression ? emulation.decompress(bytestring, xorkey) : emulation.decode(bytestring, xorkey) 54 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] Bytecode: ${bytecode.length} Bytes`) 55 | 56 | const deserialize = functions.find(s => s.FunctionStat.Body.StatementList.filter(s=>s.Type=="NumericForStat").length > 1) 57 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] Deserialize: '${deserialize.FunctionStat.NameChain[0].Source}'`) 58 | 59 | const dbody = deserialize.FunctionStat.Body.StatementList, dname = deserialize.FunctionStat.NameChain[0].Source 60 | const bformat = [], cformat = [] 61 | let primary = xorkey, secondary, tertiary 62 | for (let i = 0; i < dbody.length; i++) { 63 | const operation = dbody[i] 64 | const type = operation.Type 65 | 66 | if (type == "NumericForStat" && operation.RangeList[1].Type == "VariableExpr") { 67 | bformat.push("Constants") 68 | 69 | const ifstats = operation.Body.StatementList.filter(s=>s.Type=="IfStat") 70 | if (ifstats.length > 1) { 71 | cformat.Bool = Number(ifstats[0].Condition.Expression.Rhs.Token.Source) 72 | cformat.Float = Number(ifstats[1].Condition.Expression.Rhs.Token.Source) 73 | cformat.String = Number(ifstats[2].Condition.Expression.Rhs.Token.Source) 74 | } else { 75 | const checks = ifstats[0] 76 | const clauses = checks.ElseClauseList 77 | cformat.Bool = Number(checks.Condition.Expression.Rhs.Token.Source) 78 | cformat.Float = Number(clauses[0].Condition.Expression.Rhs.Token.Source) 79 | cformat.String = Number(clauses[1].Condition.Expression.Rhs.Token.Source) 80 | } 81 | } else if (type == "NumericForStat" && operation.Body.StatementList[0].Type == "LocalVarStat") { 82 | bformat.push("Instructions") 83 | 84 | if (version == "IronBrew V2.7.0") { // has secondary and tertiary bitxor keys 85 | const vars = operation.Body.StatementList.filter(s=>s.Type=="LocalVarStat"&&s.ExprList.length>0&&s.ExprList[0].Type=="CallExpr") 86 | 87 | // will make better if breaks 88 | secondary = parseInt(vars[0].ExprList[0].FunctionArguments.ArgList[1].Token.Source) 89 | tertiary = parseInt(vars[1].ExprList[0].FunctionArguments.ArgList[1].Token.Source) 90 | } 91 | } else if (type == "NumericForStat" && operation.Body.StatementList[0].Rhs[0].Base.Token.Source == dname) { 92 | bformat.push("Prototypes") 93 | } else if (type == "NumericForStat") { 94 | bformat.push("Debug") 95 | } else if (type == "AssignmentStat") { 96 | switch (operation.Rhs[0].Type) { 97 | case "CallExpr": 98 | bformat.push("Parameters") 99 | continue; 100 | case "VariableExpr": 101 | // 2.7.0 weird constant thing 102 | continue; 103 | default: 104 | throw "unexpected thing" 105 | } 106 | } 107 | } 108 | 109 | const wrap = isAztup ? 110 | functions.find(s => {let l = s.FunctionStat.Body.StatementList.slice(-1)[0]; return l.Type == "ReturnStat" && l.ExprList[0].Type == "ParenExpr"}) : 111 | functions.find(s => {let l = s.FunctionStat.Body.StatementList.slice(-1)[0]; return l.Type == "ReturnStat" && l.ExprList[0].Type == "FunctionLiteral"}) 112 | 113 | const wbody = isAztup ? 114 | wrap.FunctionStat.Body.StatementList.slice(-1)[0].ExprList[0].Expression.Body.StatementList : 115 | wrap.FunctionStat.Body.StatementList.slice(-1)[0].ExprList[0].Body.StatementList 116 | 117 | const interpreter = wbody.find(s => s.Type == "WhileStat").Body.StatementList 118 | const pcountloop = wbody.find(s => s.Type == "NumericForStat") 119 | 120 | const pc = wbody.find(s=>s.Type=="LocalVarStat"&&s.ExprList.length>0&&s.ExprList[0].Type=="NumberLiteral"&&s.ExprList[0].Token.Source=="1").VarList[0].Source 121 | const top = wbody.find(s=>s.Type=="LocalVarStat"&&s.ExprList.length>0&&s.ExprList[0].Type=="UnopExpr"&&s.ExprList[0].Rhs.Token.Source=="1").VarList[0].Source 122 | const stk = pcountloop.Body.StatementList[0].ElseClauseList[0].Body.StatementList[0].Lhs[0].Base.Token.Source 123 | 124 | let Const 125 | 126 | if (version == "IronBrew V2.7.0") { 127 | const first_def = wrap.FunctionStat.Body.StatementList.filter(s=>s.Type=="LocalVarStat").find(s=>s.ExprList[0].Index.Token.Source=="2") 128 | const second_def = wbody.filter(s=>s.Type=="LocalVarStat").find(s=>s.ExprList.length>0&&s.ExprList[0].Type=="VariableExpr"&&s.ExprList[0].Variable.Name==first_def.VarList[0].Source) 129 | 130 | Const = second_def.VarList[0].Source 131 | } 132 | 133 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] BFormat: ${chalk.magentaBright(`[${bformat.join(", ")}]`)}`) 134 | if (debug) console.log(`[${chalk.yellow("DEBUG")}] CFormat: ${chalk.magentaBright(`{Bool: ${cformat.Bool}, Float: ${cformat.Float}, String: ${cformat.String}}`)}`) 135 | if (!debug) console.log(` ${chalk.greenBright("Success")}`) 136 | 137 | // require("fs").writeFileSync("optimized.lua", bytecode) 138 | 139 | return { 140 | Version: version, 141 | BytecodeFormat: bformat, 142 | ConstantFormat: cformat, 143 | Bytecode: SmartBuffer.fromBuffer(bytecode), 144 | Tokens: { 145 | Clauses: interpreter.find(s => s.Type == "IfStat"), 146 | Top: top, 147 | Stk: stk, 148 | Env: wrap.FunctionStat.ArgList[2].Source, 149 | Wrap: wrap.FunctionStat.NameChain[0].Source, 150 | Enum: interpreter[1].Lhs[0].Variable.Name, 151 | Inst: interpreter[0].Lhs[0].Variable.Name, 152 | Const, 153 | Chunk: wrap.FunctionStat.ArgList[0].Source, 154 | Unpack: varaibles.find(s=>s.ExprList.length>0&& 155 | (s.ExprList[0].Type=="BinopExpr"&& 156 | s.ExprList[0].Rhs.Type=="FieldExpr"&& 157 | s.ExprList[0].Token_Op.Source=="or")|| 158 | (s.ExprList[0].Type=="VariableExpr"&& 159 | s.ExprList[0].Variable.Type=="Global"&& 160 | s.ExprList[0].Variable.Name.toLowerCase()=="unpack")).VarList[0].Source, 161 | Upvalues: wrap.FunctionStat.ArgList[1].Source, 162 | InstrPoint: pc, 163 | }, 164 | Keys: { 165 | Primary: primary, 166 | Secondary: secondary, 167 | Tertiary: tertiary 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/deserialize.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const { SmartBuffer } = require("smart-buffer") 3 | const emulation = require("../ironbrew/emulation") 4 | 5 | function xor(a,b) { // lua xor is different from js when numbers bigger than (int|uint) 6 | let p=1,c=0 7 | while (a>0 && b>0) { 8 | let ra=a%2,rb=b%2 9 | if (ra!=rb) { c=c+p } 10 | a=(a-ra)/2,b=(b-rb)/2,p=p*2 11 | } 12 | if (a0) { 14 | let ra=a%2 15 | if (ra>0) { c=c+p } 16 | a=(a-ra)/2,p=p*2 17 | } 18 | return c 19 | } 20 | 21 | module.exports = function(vmdata, debug) { 22 | if (debug) console.log() 23 | 24 | /** @type {SmartBuffer} */ 25 | const bytecode = vmdata.Bytecode 26 | const bformat = vmdata.BytecodeFormat 27 | const cformat = vmdata.ConstantFormat 28 | let curchunk = 0 29 | 30 | function deserialize() { 31 | const constants = [], 32 | instructions = [], 33 | prototypes = [], 34 | lineinfo = [], 35 | top = curchunk == 0 36 | 37 | let parameters 38 | 39 | let registers = [] 40 | 41 | function add_register(register) { 42 | if (register != undefined && registers.indexOf(Math.abs(register)) == -1 && Math.abs(register) < 256) { // > 255 is reserved for constants 43 | registers.push(Math.abs(register)) 44 | } 45 | } 46 | 47 | curchunk++ 48 | 49 | for (let i = 0; i < bformat.length; i++) { 50 | switch (bformat[i]) { 51 | case "Constants": { 52 | const count = bytecode.readUInt32LE() 53 | 54 | for (let k = 0; k < count; k++) { 55 | switch (bytecode.readUInt8()) { 56 | case cformat.Bool: 57 | constants.push(!!bytecode.readUInt8()) 58 | continue 59 | case cformat.Float: 60 | constants.push(bytecode.readDoubleLE()) 61 | continue 62 | case cformat.String: 63 | constants.push(bytecode.readString(bytecode.readUInt32LE())) 64 | continue 65 | default: 66 | constants.push(null) // pretty sure they just use loadnil but whatever 67 | continue 68 | } 69 | } 70 | 71 | continue; 72 | } 73 | case "Instructions": { 74 | const count = bytecode.readUInt32LE() 75 | 76 | for (let k = 0; k < count; k++) { 77 | if (vmdata.Version == "IronBrew V2.7.0") { 78 | const data1 = xor(bytecode.readUInt32LE(), vmdata.Keys.Secondary) // bytecode.readUInt32LE() ^ vmdata.Keys.Secondary 79 | const data2 = xor(bytecode.readUInt32LE(), vmdata.Keys.Tertiary) // bytecode.readUInt32LE() ^ vmdata.Keys.Tertiary 80 | 81 | const type = emulation.gbit(data1, 1, 2) 82 | const opco = emulation.gbit(data2, 1, 11) 83 | 84 | const instruction = { 85 | Enum: opco, 86 | Data: data2 87 | } 88 | 89 | switch (type) { 90 | case 0: // ABC 91 | instruction.A = emulation.gbit(data1, 3, 11) 92 | instruction.B = emulation.gbit(data1, 12, 20) 93 | instruction.C = emulation.gbit(data1, 21, 29) 94 | break; 95 | case 1: // ABx 96 | instruction.A = emulation.gbit(data1, 3, 11) 97 | // instruction.B = emulation.gbit(data1, 12, 20) 98 | instruction.B = emulation.gbit(data2, 12, 33) 99 | break; 100 | case 2: // AsBx 101 | instruction.A = emulation.gbit(data1, 3, 11) 102 | // instruction.B = emulation.gbit(data1, 12, 20) - 1048575 103 | instruction.B = emulation.gbit(data2, 12, 32) - 1048575 104 | break; 105 | case 3: // AsBxC 106 | instruction.A = emulation.gbit(data1, 3, 11) 107 | // instruction.B = emulation.gbit(data1, 12, 20) - 1048575 108 | instruction.B = emulation.gbit(data2, 12, 32) - 1048575 109 | instruction.C = emulation.gbit(data1, 21, 29) 110 | break; 111 | } 112 | 113 | add_register(instruction.A) 114 | add_register(instruction.B) 115 | add_register(instruction.C) 116 | 117 | instructions.push(instruction) 118 | } else { 119 | const descriptor = bytecode.readUInt8() 120 | 121 | if ((descriptor & 0b00000001) == 0) { 122 | const instruction = { 123 | Enum: bytecode.readUInt16LE() 124 | } 125 | 126 | switch ((descriptor & 0b00000110) >> 1) { // if its not data 127 | case 0: // ABC 128 | instruction.A = bytecode.readUInt16LE() 129 | instruction.B = bytecode.readUInt16LE() 130 | instruction.C = bytecode.readUInt16LE() 131 | break; 132 | case 1: // ABx 133 | instruction.A = bytecode.readUInt16LE() 134 | instruction.B = bytecode.readUInt32LE() 135 | break; 136 | case 2: // AsBx 137 | instruction.A = bytecode.readUInt16LE() 138 | instruction.B = bytecode.readUInt32LE() - 65536 139 | break; 140 | case 3: // AsBxC 141 | instruction.A = bytecode.readUInt16LE() 142 | instruction.B = bytecode.readUInt32LE() - 65536 143 | instruction.C = bytecode.readUInt16LE() 144 | break; 145 | } 146 | 147 | add_register(instruction.A) 148 | add_register(instruction.B) 149 | add_register(instruction.C) 150 | 151 | instructions.push(instruction) 152 | } 153 | } 154 | } 155 | 156 | continue; 157 | } 158 | case "Prototypes": { 159 | const count = bytecode.readUInt32LE() 160 | 161 | /*if (debug) { 162 | console.log(`[${chalk.magentaBright("OUT")}] Chunk [${curchunk}]:`) 163 | console.log(`[${chalk.magentaBright("OUT")}] ${constants.length} Constants`) 164 | console.log(`[${chalk.magentaBright("OUT")}] ${instructions.length} Instructions`) 165 | console.log(`[${chalk.magentaBright("OUT")}] ${count} Prototypes`) 166 | console.log(`[${chalk.magentaBright("OUT")}] ${parameters.Size} Parameters`) 167 | }*/ 168 | 169 | //console.log(curchunk, ":", constants) 170 | 171 | /*console.log({ 172 | Constants: constants, 173 | Instructions: instructions, 174 | Prototypes: prototypes, 175 | Parameters: parameters, 176 | })*/ 177 | 178 | //constants.forEach((a, b) => console.log(b, a)) 179 | 180 | //throw "lollfsdfsdfsdfsdf" 181 | 182 | for (let k = 0; k < count; k++) { 183 | prototypes.push(deserialize()) 184 | } 185 | 186 | continue; 187 | } 188 | case "Parameters": { 189 | parameters = bytecode.readUInt8() 190 | 191 | continue; 192 | } 193 | case "Debug": { 194 | const count = bytecode.readUInt32LE() 195 | 196 | for (let k = 0; k < count; k++) { 197 | lineinfo.push(bytecode.readUInt32LE()) 198 | } 199 | 200 | continue; 201 | } 202 | } 203 | } 204 | 205 | return { 206 | Constants: constants, 207 | Instructions: instructions, 208 | Prototypes: prototypes, 209 | Parameters: parameters, 210 | Registers: registers.length + parameters, 211 | LineInfo: lineinfo, 212 | Top: top 213 | } 214 | } 215 | 216 | if (!debug) console.log(` ${chalk.greenBright("Success")}`) 217 | 218 | const x = deserialize() 219 | 220 | // console.log(x) 221 | 222 | return { 223 | Chunk: x, 224 | Tokens: vmdata.Tokens, 225 | Version: vmdata.Version 226 | } 227 | } -------------------------------------------------------------------------------- /obfuscators/moonsec/deserialize.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const { SmartBuffer } = require("smart-buffer") 3 | const emulation = require("../moonsec/emulation") 4 | const substring = require("unicode-substring") 5 | 6 | function gBit(L_75_arg0, L_76_arg1, L_77_arg2) { 7 | if (L_77_arg2) { 8 | let L_78_ = (L_75_arg0 / 2 ** (L_76_arg1 - 1)) % 2 ** ((L_77_arg2 - 1) - (L_76_arg1 - 1) + 1) 9 | 10 | return L_78_ - L_78_ % 1 11 | } else { 12 | let L_79_ = 2 ** (L_76_arg1 - 1) 13 | 14 | return (L_75_arg0 % (L_79_ + L_79_) >= L_79_) ? 1 : 0 15 | } 16 | 17 | /*let mask = ((1<<(end-start+1))-1) << start 18 | return (num & mask) >> start*/ 19 | } 20 | 21 | function ldexp(mantissa, exponent) { 22 | var steps = Math.min(3, Math.ceil(Math.abs(exponent) / 1023)); 23 | var result = mantissa; 24 | for (var i = 0; i < steps; i++) 25 | result *= Math.pow(2, Math.floor((exponent + i) / steps)); 26 | return result; 27 | } 28 | 29 | class moonsec_reader { // pasted from moonsec $$$ 30 | constructor (bytes, stuff) { 31 | this.L_47_ = bytes 32 | this.L_50_ = stuff.C - 1 // should be 0 (position of reader) 33 | this.L_48_ = stuff.A 34 | this.L_49_ = stuff.B 35 | } 36 | 37 | gAscii(len = 1) { 38 | let bytes = [] 39 | 40 | for (let i = 0; i < len; i++) { 41 | bytes.push(this.L_47_[this.L_50_]) 42 | 43 | this.L_50_ += 1 44 | } 45 | 46 | return bytes 47 | } 48 | 49 | gBits32() { 50 | let [ L_65_, L_66_, L_67_, L_68_ ] = this.gAscii(4) 51 | 52 | this.L_49_ = (this.L_49_ + (this.L_48_ * 4)) % 256 53 | 54 | return (((L_68_ + this.L_49_ - (this.L_48_) + 2048) % 256) * (16777216)) + (((L_67_ + this.L_49_ - (this.L_48_ * 2) + 2048) % 256) * (65536)) + (((L_66_ + this.L_49_ - (this.L_48_ * 3) + 2048) % 256) * 256) + ((L_65_ + this.L_49_ - (this.L_48_ * 4) + 2048) % 256) 55 | } 56 | 57 | gBits8() { 58 | let L_72_ = this.gAscii()[0] 59 | 60 | this.L_49_ = (this.L_49_ + (this.L_48_)) % 256 61 | 62 | return ((L_72_ + this.L_49_ - (this.L_48_) + 2048) % 256) 63 | } 64 | 65 | gBits16() { 66 | let [ L_73_, L_74_ ] = this.gAscii(2) 67 | 68 | this.L_49_ = (this.L_49_ + (this.L_48_ * 2)) % 256 69 | 70 | return (((L_74_ + this.L_49_ - (this.L_48_) + 2048) % 256) * 256) + ((L_73_ + this.L_49_ - (this.L_48_ * 2) + 2048) % 256) 71 | } 72 | 73 | gFloat() { 74 | let Left = this.gBits32(); 75 | let Right = this.gBits32(); 76 | let IsNormal = 1 77 | let Mantissa = (gBit(Right, 1, 20) * (2 ** 32)) + Left; 78 | 79 | let Exponent = gBit(Right, 21, 31); 80 | let Sign = ((-1) ** gBit(Right, 32)); 81 | 82 | if (Exponent == 0) { 83 | if (Mantissa == 0) { 84 | return Sign * 0 // +-0 85 | } else { 86 | Exponent = 1 87 | IsNormal = 0 88 | } 89 | } else if (Exponent == 2047) { 90 | if (Mantissa == 0) { 91 | return Sign * (1 / 0) // +-Inf 92 | } else { 93 | return Sign * (0 / 0) // +-Q/Nan 94 | } 95 | } 96 | 97 | // sign * 2**e-1023 * isNormal.mantissa 98 | return ldexp(Sign, Exponent - 1023) * (IsNormal + (Mantissa / (2 ** 52))) 99 | } 100 | 101 | gString(L_86_arg0, L_87_arg1, L_88_arg2) { 102 | let L_89_; 103 | if (L_86_arg0 == undefined) { 104 | L_86_arg0 = this.gBits32(); 105 | if (L_86_arg0 == 0) { 106 | return ""; 107 | }; 108 | }; 109 | L_89_ = this.L_47_.map(s=>String.fromCharCode(s)).join("").substring(this.L_50_, this.L_50_ + L_86_arg0); 110 | this.L_50_ = this.L_50_ + L_86_arg0; 111 | let L_90_ = "" 112 | for (let L_91_forvar0 = 1; L_91_forvar0 < L_89_.length + 1; L_91_forvar0++) { 113 | L_90_ = L_90_ + String.fromCharCode(((L_89_.substring(L_91_forvar0 - 1, L_91_forvar0)).charCodeAt(0) + this.L_49_) % 256) // string + string -> concat 114 | this.L_49_ = (this.L_49_ + this.L_48_) % 256 115 | } 116 | return L_90_; 117 | } 118 | } 119 | 120 | module.exports = function(vmdata, debug) { 121 | if (debug) console.log() 122 | 123 | let bformat = vmdata.BytecodeFormat 124 | let cformat = vmdata.ConstantFormat 125 | let rconsts = vmdata.ReaderConsts 126 | 127 | let reader = new moonsec_reader(vmdata.Bytecode, rconsts) 128 | let count = 0 129 | 130 | function deserialize() { 131 | let constants = [], 132 | instructions = [], 133 | prototypes = [], 134 | parameters, 135 | top = count == 0 136 | 137 | let registers = [] 138 | 139 | function add_register(register) { 140 | if (register != undefined && registers.indexOf(Math.abs(register)) == -1 && Math.abs(register) < 256) { // > 255 is reserved for constants 141 | registers.push(Math.abs(register)) 142 | } 143 | } 144 | 145 | // console.log("NEW_CHUNK") 146 | 147 | count++ 148 | 149 | for (let i = 0; i < bformat.length; i++) { 150 | switch (bformat[i]) { 151 | case "Parameters": 152 | parameters = reader.gBits8() 153 | // console.log("Parameters", parameters) 154 | 155 | continue 156 | case "Prototypes": 157 | let proto_count = reader.gBits32() 158 | // console.log("Prototypes", proto_count) 159 | 160 | for (let k = 1; k < proto_count + 1; k++) { 161 | // console.log(k - 1) --> freak? 162 | prototypes[k - 1] = deserialize() 163 | //prototypes.push(deserialize()) 164 | } 165 | 166 | continue 167 | case "Constants": 168 | let const_count = reader.gBits32() 169 | // console.log("Constants", const_count) 170 | 171 | for (let k = 0; k < const_count; k++) { 172 | let L_110_ = reader.gBits8() 173 | 174 | switch (L_110_ % rconsts.D) { 175 | case cformat.Bool: 176 | constants.push(!(0 == reader.gBits8())) 177 | 178 | break 179 | case cformat.Float: 180 | constants.push(reader.gFloat()) 181 | 182 | break 183 | case cformat.String: 184 | constants.push(reader.gString()) 185 | 186 | break 187 | case cformat.Encoded: 188 | let L_104_ = reader.gString() 189 | let L_105_ = "" 190 | let L_106_ = 1 191 | for (let L_107_forvar0 = 0; L_107_forvar0 < L_104_.length; L_107_forvar0++) { 192 | L_106_ = (L_106_ + rconsts.CKey) % 256 193 | L_105_ = L_105_ + String.fromCharCode(((substring(L_104_, L_107_forvar0 + 1, L_107_forvar0)).charCodeAt(0) + L_106_) % 256) 194 | } 195 | 196 | constants.push(L_105_) 197 | 198 | break 199 | } 200 | } 201 | 202 | continue 203 | case "Instructions": 204 | let inst_count = reader.gBits32() 205 | 206 | for (let k = 0; k < inst_count; k++) { 207 | let L_114_ = reader.gBits8() 208 | if (gBit(L_114_, 1, 1) == 0) { 209 | let L_115_ = gBit(L_114_, 2, 3) 210 | let L_116_ = gBit(L_114_, 4, 6) 211 | let L_117_ = { 212 | Enum: reader.gBits16(), 213 | A: reader.gBits16(), 214 | } 215 | 216 | switch (L_115_) { 217 | case 0: 218 | L_117_.B = reader.gBits16() 219 | L_117_.C = reader.gBits16() 220 | 221 | break 222 | case 1: 223 | L_117_.B = reader.gBits32() 224 | 225 | break 226 | case 2: 227 | L_117_.B = reader.gBits32() - 65536 228 | 229 | break 230 | case 3: 231 | L_117_.B = reader.gBits32() - 65536 232 | L_117_.C = reader.gBits16() 233 | 234 | break 235 | } 236 | 237 | add_register(L_117_.A) 238 | add_register(L_117_.B) 239 | add_register(L_117_.C) 240 | 241 | // not sure if i need to do this?? i dont think so as its still the correct index within the constants but we'll see 242 | // ok ignore ubove, so the obfuscator has a feature called "anti dump" that just fucks the indexes of the constants 243 | // so i can use this to get the correct index 244 | 245 | if (gBit(L_116_, 1, 1) == 1) { 246 | //L_117_.KstA = constants[L_117_.A] 247 | //console.log(`${L_117_.A} -> ${constants[L_117_.A - 1]}`) 248 | } 249 | if (gBit(L_116_, 2, 2) == 1) { 250 | //L_117_.KstB = constants[L_117_.B] 251 | //console.log(`${L_117_.B} -> ${constants[L_117_.B - 1]}`) 252 | } 253 | if (gBit(L_116_, 3, 3) == 1) { 254 | //L_117_.KstC = constants[L_117_.C] 255 | //console.log(`${L_117_.C} -> ${constants[L_117_.C - 1]}`) 256 | } 257 | 258 | instructions.push(L_117_) 259 | } 260 | } 261 | 262 | //console.log(instructions) 263 | //throw "iyo" 264 | 265 | continue 266 | } 267 | } 268 | 269 | //console.log(constants) 270 | 271 | return { 272 | Constants: constants, 273 | Instructions: instructions, 274 | Prototypes: prototypes, 275 | Parameters: parameters, 276 | Registers: registers.length + parameters, 277 | Top: top 278 | } 279 | } 280 | 281 | vmdata.Chunk = deserialize() 282 | 283 | //console.log(vmdata.Chunk) 284 | //console.log(JSON.stringify(vmdata.Chunk, null, 4)) 285 | 286 | return vmdata 287 | } -------------------------------------------------------------------------------- /obfuscators/ironbrew/devirtualize.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | const chalk = require("chalk") 3 | const luamin = require("../../utility/luamin") 4 | const binary = require("../../utility/binary") 5 | const emulation = require("./emulation") 6 | const opcodes = {} 7 | 8 | function createNL(n) { 9 | return { 10 | Type: "NumberLiteral", 11 | Token: { 12 | Type: "Number", 13 | LeadingWhite: "", 14 | Source: n 15 | }, 16 | GetFirstToken: () => {}, 17 | GetLastToken: () => {} 18 | } 19 | } 20 | 21 | let replace_known 22 | let replace_unknown 23 | 24 | function find(Enum, tokens, clause, parent) { 25 | clause = clause || tokens.Clauses 26 | 27 | let ifstat = clause.Condition 28 | const elsestats = clause.ElseClauseList 29 | 30 | if (ifstat.Type != "BinopExpr" || ifstat.Lhs.Type != "VariableExpr") { 31 | return parent 32 | } 33 | 34 | if (ifstat.Lhs.Variable.Name != tokens.Enum) { 35 | return parent 36 | } 37 | 38 | if (ifstat.Rhs.Type == "UnopExpr") { 39 | let solved = emulation.unopexpr(ifstat.Rhs) 40 | 41 | if (solved) { 42 | ifstat.Rhs = createNL(solved) 43 | } else { 44 | return 45 | } 46 | } else if (ifstat.Rhs.Type != "NumberLiteral") { 47 | throw "Unhandled comparison in control flow" 48 | } 49 | 50 | function handle(clause) { 51 | if (clause.Body.StatementList[0].Type == "IfStat") { 52 | return find(Enum, tokens, clause.Body.StatementList[0], clause.Body.StatementList) 53 | } else { 54 | return clause.Body.StatementList 55 | } 56 | } 57 | 58 | if (emulation.expression(Enum, ifstat.Token_Op.Source, ifstat.Rhs.Token.Source)) { 59 | return handle(clause) 60 | } 61 | 62 | for (let i = 0; i < elsestats.length; i++) { 63 | clause = elsestats[i] 64 | ifstat = clause.Condition 65 | 66 | if (clause.ClauseType == "elseif") { 67 | if (ifstat.Rhs.Type == "UnopExpr") { 68 | let solved = emulation.unopexpr(ifstat.Rhs) 69 | 70 | if (solved) { 71 | ifstat.Rhs = createNL(solved) 72 | } else { 73 | return 74 | } 75 | } else if (ifstat.Rhs.Type != "NumberLiteral") { 76 | console.log(ifstat.Rhs) 77 | throw "Unhandled comparison in control flow" 78 | } 79 | 80 | if (emulation.expression(Enum, ifstat.Token_Op.Source, ifstat.Rhs.Token.Source)) { 81 | return handle(clause) 82 | } 83 | } else if (clause.ClauseType == "else") { // else? 84 | return handle(clause) 85 | } 86 | } 87 | } 88 | 89 | function match(instruction, operands, pc, tokens, nolocal) { 90 | // could impimet operand name resolver? but again havent ran into problems yet 91 | 92 | function compare(srcstr, thorough) { 93 | let structure, list, ast 94 | 95 | structure = function(a, b) { 96 | if (a.Type != b.Type) { 97 | if (b.Type == "NumberLiteral" && a.Type == "UnopExpr") { 98 | let solved = emulation.unopexpr(a) 99 | 100 | if (solved) { 101 | a = createNL(solved) 102 | } else { 103 | return false 104 | } 105 | } else { 106 | return false 107 | } 108 | } 109 | 110 | if (a.Type == "AssignmentStat") { 111 | return list(a.Rhs, b.Rhs) && list(a.Lhs, b.Lhs) 112 | } else if (a.Type == "IndexExpr") { 113 | let names = true 114 | 115 | if (thorough && a.Base.Variable != undefined && b.Base.Type == "VariableExpr") { 116 | names = a.Base.Variable.Name == b.Base.Token.Source 117 | } 118 | 119 | // console.log(a.Base.Variable && a.Base.Variable.Name) 120 | 121 | return names && structure(a.Base, b.Base) && structure(a.Index, b.Index) 122 | } else if (a.Type == "VariableExpr") { 123 | return true 124 | } else if (a.Type == "NumberLiteral") { 125 | return a.Source == b.Source 126 | } else if (a.Type == "LocalVarStat") { 127 | return list(a.ExprList, b.ExprList) 128 | } else if (a.Type == "CallExprStat") { 129 | const e1 = a.Expression, e2 = b.Expression 130 | return structure(e1.Base, e2.Base) && list(e1.FunctionArguments.ArgList, e2.FunctionArguments.ArgList) 131 | } else if (a.Type == "CallExpr") { 132 | return structure(a.Base, b.Base) && list(a.FunctionArguments.ArgList, b.FunctionArguments.ArgList) 133 | } else if (a.Type == "BinopExpr") { 134 | const t1 = a.Token_Op, t2 = b.Token_Op 135 | /*console.log("-------------------------------------------------------------------------------") 136 | console.log(t1.Source, t2.Source) 137 | console.log(luamin.Print({Type:"StatList", StatementList: instruction, SemicolonList: []})) 138 | console.log(srcstr)*/ 139 | return t1.Source == t2.Source && structure(a.Rhs, b.Rhs) && structure(a.Lhs, b.Lhs) 140 | } else if (a.Type == "DoStat") { 141 | return list(a.Body.StatementList, b.Body.StatementList) 142 | } else if (a.Type == "ReturnStat") { 143 | return list(a.ExprList, b.ExprList) 144 | } else if (a.Type == "NilLiteral") { 145 | return true 146 | } else if (a.Type == "TableLiteral") { 147 | return true 148 | } else if (a.Type == "NumericForStat") { 149 | return list(a.RangeList, b.RangeList) && list(a.Body.StatementList, b.Body.StatementList) 150 | } else if (a.Type == "ParenExpr") { 151 | return structure(a.Expression, b.Expression) 152 | } else if (a.Type == "UnopExpr") { 153 | return a.Token_Op.Source == b.Token_Op.Source && structure(a.Rhs, b.Rhs) 154 | } else if (a.Type == "IfStat") { 155 | if (!structure(a.Condition, b.Condition)) { 156 | return false 157 | } 158 | 159 | if (thorough && !list(a.Body.StatementList, b.Body.StatementList)) { 160 | return false 161 | } 162 | 163 | const o1 = a.ElseClauseList 164 | const o2 = b.ElseClauseList 165 | 166 | if (o1.length != o2.length) { 167 | return false 168 | } 169 | 170 | for (let i = 0; i < o1.length; i++) { 171 | const c1 = o1[i], c2 = o2[i] 172 | const t1 = c1.ClauseType, t2 = c2.ClauseType 173 | 174 | if (t1 != t2) { 175 | return false 176 | } 177 | 178 | if (t1 == "elseif") { 179 | // havent ran into problems yet? so... who cares 180 | } 181 | 182 | if (!list(c1.Body.StatementList, c2.Body.StatementList)) { 183 | return false 184 | } 185 | } 186 | 187 | 188 | return list(a.Body.StatementList, b.Body.StatementList) 189 | } 190 | 191 | console.log(a) 192 | console.log(b) 193 | 194 | return false 195 | } 196 | 197 | list = function(a, b) { 198 | if(a.length != b.length) { 199 | return false 200 | } else if (a.length == 0) { 201 | return true 202 | } 203 | 204 | for (let i = 0; i < a.length; i++) { 205 | if (!structure(a[i], b[i])) { 206 | return false 207 | } 208 | } 209 | 210 | return true 211 | } 212 | 213 | if (nolocal) { 214 | srcstr = srcstr.replace(/local/g, "") 215 | } 216 | 217 | // Problem where vars can repeat so i might beautifiy it first /shrug 218 | // Edit ^^ i did 219 | 220 | // console.log(luamin.Beautify(srcstr, {})) 221 | 222 | srcstr = replace_known(srcstr) 223 | 224 | ast = luamin.Parse(srcstr)//[0] 225 | 226 | // here is a fix for that one nigga obfuscator 227 | /*(if (instruction.length>1&&instruction[0].Type=="AssignmentStat"&&instruction[0].Rhs[0].Type=="IndexExpr") { 228 | const index = instruction[0].Rhs[0] 229 | 230 | if (index.Base.Type == "VariableExpr"&&index.Base.Token.Source==tokens.Inst) { 231 | 232 | 233 | 234 | } 235 | }*/ 236 | 237 | return list(instruction, ast.StatementList) 238 | } 239 | 240 | function isSuperJump(s) { 241 | if (s.Type != "AssignmentStat") return false 242 | const r = s.Rhs[0], l = s.Lhs[0] 243 | 244 | return (r.Type=="BinopExpr"&& 245 | r.Lhs.Type == "VariableExpr"&& 246 | r.Lhs.Variable.Name==tokens.InstrPoint&& 247 | r.Rhs.Type == "NumberLiteral"&& 248 | r.Rhs.Token.Source=="1"&& 249 | l.Type =="VariableExpr"&& 250 | l.Variable.Name==tokens.InstrPoint) // || () 251 | } 252 | 253 | for (opcode in opcodes) { 254 | const alises = opcodes[opcode] 255 | 256 | for (v of Object.values(alises)) { 257 | if ((v.Match != undefined && v.Match(instruction)) || (v.String != undefined && compare(v.String, v.Thorough))) { 258 | //console.log(operands[pc]) 259 | operands[pc].PC = pc 260 | 261 | const op = v.Create(operands[pc]) 262 | op.OpCode = binary.OpCodes.indexOf(opcode) 263 | op.OpName = binary.OpCodes[op.OpCode] 264 | op.Type = binary.OpCodeTypes[op.OpCode] 265 | 266 | // console.log(opcode) 267 | 268 | /*if (opcode == "Lt") { 269 | console.log(luamin.Print({Type:"StatList", StatementList: instruction, SemicolonList: []})) 270 | console.log(v.String) 271 | }*/ 272 | 273 | return op 274 | } 275 | } 276 | } 277 | 278 | if (instruction.find(s => isSuperJump(s))) { 279 | let sub = [] 280 | instruction.Instructions = [] 281 | instruction.SuperInstruction = true 282 | instruction.MatchedInstructions = [] 283 | instruction.SubCount = instruction.filter(s => isSuperJump(s)).length 284 | instruction.Instructions.push(sub) 285 | 286 | for (let spc = 0; spc < instruction.length; spc++) { 287 | const operation = instruction[spc] 288 | 289 | if (isSuperJump(operation)) { 290 | spc++ 291 | sub = [] 292 | instruction.Instructions.push(sub) 293 | continue 294 | } else if (operation.Type == "LocalVarStat") { 295 | continue 296 | } else { 297 | sub.push(operation) 298 | } 299 | } 300 | 301 | for (let spc = 0; spc < instruction.Instructions.length; spc++) { 302 | const vminstruction = instruction.Instructions[spc] 303 | const instructionmt = match(vminstruction, operands, pc + spc, tokens, true) 304 | 305 | if (instructionmt != null) { 306 | instructionmt.Enum = spc 307 | instruction.MatchedInstructions.push(instructionmt) 308 | } else { 309 | instruction.MatchedInstructions.push({ 310 | PlaceHolder: true, 311 | Enum: spc 312 | }) 313 | } 314 | } 315 | 316 | return instruction 317 | } 318 | } 319 | 320 | module.exports = function(vmdata) { 321 | 322 | // console.log(vmdata.Chunk.Instructions) 323 | 324 | if (vmdata.Version == "IronBrew V2.7.0") { 325 | fs.readdirSync("./obfuscators/ironbrew/opcodes/2.7.0").forEach(opcode => { 326 | opcodes[opcode.split(".")[0]] = require(`./opcodes/2.7.0/${opcode}`) 327 | }) 328 | } else if (vmdata.Version == "IronBrew V2.7.1" || vmdata.Version == "AztupBrew V2.7.2") { 329 | fs.readdirSync("./obfuscators/ironbrew/opcodes/2.7.1").forEach(opcode => { 330 | opcodes[opcode.split(".")[0]] = require(`./opcodes/2.7.1/${opcode}`) 331 | }) 332 | } 333 | 334 | replace_known = (str) => { 335 | let res = str.replace(/OP_A/g, "2") 336 | .replace(/OP_B/g, "3") 337 | .replace(/InstrPoint/g, vmdata.Tokens.InstrPoint) 338 | .replace(/Upvalues/g, vmdata.Tokens.Upvalues) 339 | .replace(/Unpack/g, vmdata.Tokens.Unpack) 340 | .replace(/Const/g, vmdata.Tokens.Const) 341 | .replace(/Wrap/g, vmdata.Tokens.Wrap) 342 | .replace(/Inst/g, vmdata.Tokens.Inst) 343 | .replace(/Top/g, vmdata.Tokens.Top) 344 | .replace(/Stk/g, vmdata.Tokens.Stk) 345 | .replace(/Env/g, vmdata.Tokens.Env) 346 | 347 | if (vmdata.Version == "IronBrew V2.7.0") { 348 | res = res.replace(/OP_C/g, "5") 349 | } else { 350 | res = res.replace(/OP_C/g, "4") 351 | } 352 | 353 | return res 354 | } 355 | 356 | replace_unknown = (str) => { 357 | let res = str.replace(/\[2/g, "[OP_A") 358 | .replace(/\[3/g, "[OP_B") 359 | .replace(/\[4/g, "[OP_C") 360 | .replace(new RegExp(vmdata.Tokens.InstrPoint, "g"), "InstrPoint") 361 | .replace(new RegExp(vmdata.Tokens.Upvalues, "g"), "Upvalues") 362 | .replace(new RegExp(vmdata.Tokens.Unpack, "g"), "Unpack") 363 | .replace(new RegExp(vmdata.Tokens.Const, "g"), "Const") 364 | .replace(new RegExp(vmdata.Tokens.Wrap, "g"), "Wrap") 365 | .replace(new RegExp(vmdata.Tokens.Inst, "g"), "Inst") 366 | .replace(new RegExp(vmdata.Tokens.Top, "g"), "Top") 367 | .replace(new RegExp(vmdata.Tokens.Stk, "g"), "Stk") 368 | .replace(new RegExp(vmdata.Tokens.Env, "g"), "Env") 369 | 370 | if (vmdata.Version == "IronBrew V2.7.0") { 371 | res = res.replace(/\[5/g, "[OP_C") 372 | } else { 373 | res = res.replace(/\[4/g, "[OP_C") 374 | } 375 | 376 | return res 377 | } 378 | 379 | function devirtualize(chunk) { 380 | const instructions = chunk.Instructions 381 | const prototypes = chunk.Prototypes 382 | const matched = [] 383 | const tokens = vmdata.Tokens 384 | 385 | console.log() 386 | 387 | process.title = `0/${instructions.length}` 388 | 389 | for (let pc = 0; pc < instructions.length; pc++) { 390 | const Enum = instructions[pc].Enum, vminstruction = find(Enum, tokens) 391 | 392 | if (vminstruction != null) { 393 | const instructionmt = match(vminstruction, instructions, pc, tokens) 394 | 395 | if (instructionmt != null) { 396 | if (instructionmt.SuperInstruction) { 397 | const subInstructions = instructionmt.MatchedInstructions 398 | console.log(`[${chalk.magentaBright("OUT")}] No ${chalk.magentaBright("Matched")} Instruction For #${Enum} ... SuperInstruction?`) 399 | pc += instructionmt.SubCount 400 | 401 | for (let i = 0; i < subInstructions.length; i++) { 402 | if (!subInstructions[i].PlaceHolder) { 403 | 404 | 405 | // bs fix for that shit script 406 | const subInstruction = subInstructions[i] 407 | 408 | /*if (i == 7 && binary.OpCodes[subInstruction.OpCode] == "Call") { 409 | if (binary.OpCodes[subInstructions[i - 1].OpCode] == "Call" && binary.OpCodes[subInstructions[i - 2].OpCode] == "Self") { 410 | subInstruction.A = 0 411 | subInstruction.B = 1 412 | subInstruction.C = 0 413 | } 414 | }*/ 415 | 416 | matched.push(subInstruction) 417 | console.log(`[${chalk.magentaBright("OUT")}] Matched Sub-Instruction For #${subInstructions[i].Enum + 1}: ${binary.OpCodes[subInstructions[i].OpCode].toUpperCase()}`) 418 | } else { 419 | 420 | let str = luamin.Print({Type:"StatList", StatementList: instructionmt.Instructions[subInstructions[i].Enum], SemicolonList: []}) 421 | 422 | console.log(tokens) 423 | // str = replace_unknown(str) 424 | 425 | console.log(str) 426 | console.log(`[${chalk.magentaBright("OUT")}] No Matched Sub-Instruction For #${subInstructions[i].Enum + 1}`) 427 | 428 | throw "ayo" 429 | } 430 | } 431 | } else { 432 | matched.push(instructionmt) 433 | console.log(`[${chalk.magentaBright("OUT")}] Matched Instruction #${Enum}: ${binary.OpCodes[instructionmt.OpCode].toUpperCase()}`) 434 | } 435 | } else { 436 | 437 | let str = luamin.Print({Type:"StatList", StatementList: vminstruction, SemicolonList: []}) 438 | 439 | str = replace_unknown(str) 440 | 441 | 442 | 443 | //console.log(tokens) 444 | 445 | console.log(str) 446 | console.log(`[${chalk.magentaBright("OUT")}] No ${chalk.magentaBright("Matched")} Instruction #${Enum}`) 447 | 448 | throw "ayo" 449 | } 450 | } else { 451 | console.log(`[${chalk.magentaBright("OUT")}] No ${chalk.magentaBright("Found")} Instruction #${Enum}`) 452 | } 453 | 454 | process.title = `${pc}/${instructions.length}` 455 | } 456 | 457 | for (let i = 0; i < prototypes.length; i++) { 458 | prototypes[i] = devirtualize(prototypes[i]) 459 | } 460 | 461 | chunk.Instructions = matched 462 | 463 | return chunk 464 | } 465 | 466 | console.log() 467 | 468 | let devirtualized = devirtualize(vmdata.Chunk) 469 | 470 | let do_vararg = function(chunk) { 471 | for (let i = 0; i < chunk.Instructions.length; i++) { 472 | let instruction = chunk.Instructions[i] 473 | let instruction_name = binary.OpCodes[instruction.OpCode] 474 | 475 | if (instruction_name == "VarArg") { 476 | chunk.VarArg = true 477 | 478 | continue 479 | } 480 | } 481 | 482 | for (let i = 0; i < chunk.Prototypes.length; i++) { 483 | do_vararg(chunk.Prototypes[i]) 484 | } 485 | } 486 | 487 | do_vararg(devirtualized) 488 | 489 | // console.log(devirtualized) 490 | 491 | return devirtualized 492 | } --------------------------------------------------------------------------------