-- This Script is Part of the Prometheus Obfuscator by levno-710 -- -- for_statement.lua -- -- This Script contains the statement handler for the ForStatement local Ast = require("prometheus.ast"); local util = require("prometheus.util"); return function(self, statement, funcDepth) local scope = self.activeBlock.scope; local checkBlock = self:createBlock(); local innerBlock = self:createBlock(); local finalBlock = self:createBlock(); statement.__start_block = checkBlock; statement.__final_block = finalBlock; local posState = self.registers[self.POS_REGISTER]; self.registers[self.POS_REGISTER] = self.VAR_REGISTER; local initialReg = self:compileExpression(statement.initialValue, funcDepth, 1)[1]; local finalExprReg = self:compileExpression(statement.finalValue, funcDepth, 1)[1]; local finalReg = self:allocRegister(false); self:addStatement(self:copyRegisters(scope, {finalReg}, {finalExprReg}), {finalReg}, {finalExprReg}, false); self:freeRegister(finalExprReg); local incrementExprReg = self:compileExpression(statement.incrementBy, funcDepth, 1)[1]; local incrementReg = self:allocRegister(false); self:addStatement(self:copyRegisters(scope, {incrementReg}, {incrementExprReg}), {incrementReg}, {incrementExprReg}, false); self:freeRegister(incrementExprReg); local tmpReg = self:allocRegister(false); self:addStatement(self:setRegister(scope, tmpReg, Ast.NumberExpression(0)), {tmpReg}, {}, false); local incrementIsNegReg = self:allocRegister(false); local shouldSwap3 = math.random(1, 2) == 2; local shuffledRegs4 = shouldSwap3 and {incrementReg, tmpReg} or {tmpReg, incrementReg}; self:addStatement(self:setRegister(scope, incrementIsNegReg, Ast[shouldSwap3 and "LessThanExpression" or "GreaterThanExpression"](self:register(scope, shuffledRegs4[1]), self:register(scope, shuffledRegs4[2]))), {incrementIsNegReg}, {shuffledRegs4[1], shuffledRegs4[2]}, false); self:freeRegister(tmpReg); local currentReg = self:allocRegister(true); self:addStatement(self:setRegister(scope, currentReg, Ast.SubExpression(self:register(scope, initialReg), self:register(scope, incrementReg))), {currentReg}, {initialReg, incrementReg}, false); self:freeRegister(initialReg); self:addStatement(self:jmp(scope, Ast.NumberExpression(checkBlock.id)), {self.POS_REGISTER}, {}, false); self:setActiveBlock(checkBlock); scope = checkBlock.scope; -- x = x + y or x = y + x instead of just x = x + y. --> NEW: In an attempt to thwart deobfuscations, despite this being a simple comparison... Shuffling these causes problems for decompilers. --> NOTE: This isn't unstable code, I've tested it multiple times. local shuffledRegs = util.shuffle({currentReg, incrementReg}); self:addStatement(self:setRegister(scope, currentReg, Ast.AddExpression(self:register(scope, shuffledRegs[1]), self:register(scope, shuffledRegs[2]))), {currentReg}, {shuffledRegs[1], shuffledRegs[2]}, false); local tmpReg1 = self:allocRegister(false); local tmpReg2 = self:allocRegister(false); self:addStatement(self:setRegister(scope, tmpReg2, Ast.NotExpression(self:register(scope, incrementIsNegReg))), {tmpReg2}, {incrementIsNegReg}, false); local shouldSwap = math.random(1, 2) == 2; local shuffledRegs2 = shouldSwap and {currentReg, finalReg} or {finalReg, currentReg}; self:addStatement(self:setRegister(scope, tmpReg1, Ast[shouldSwap and "LessThanOrEqualsExpression" or "GreaterThanOrEqualsExpression"](self:register(scope, shuffledRegs2[1]), self:register(scope, shuffledRegs2[2]))), {tmpReg1}, {shuffledRegs2[1], shuffledRegs2[2]}, false); self:addStatement(self:setRegister(scope, tmpReg1, Ast.AndExpression(self:register(scope, tmpReg2), self:register(scope, tmpReg1))), {tmpReg1}, {tmpReg1, tmpReg2}, false); local shouldSwap2 = math.random(1, 2) == 2; local shuffledRegs3 = shouldSwap2 and {currentReg, finalReg} or {finalReg, currentReg}; self:addStatement(self:setRegister(scope, tmpReg2, Ast[shouldSwap2 and "GreaterThanOrEqualsExpression" or "LessThanOrEqualsExpression"](self:register(scope, shuffledRegs3[1]), self:register(scope, shuffledRegs3[2]))), {tmpReg2}, {shuffledRegs3[1], shuffledRegs3[2]}, false); self:addStatement(self:setRegister(scope, tmpReg2, Ast.AndExpression(self:register(scope, incrementIsNegReg), self:register(scope, tmpReg2))), {tmpReg2}, {tmpReg2, incrementIsNegReg}, false); self:addStatement(self:setRegister(scope, tmpReg1, Ast.OrExpression(self:register(scope, tmpReg2), self:register(scope, tmpReg1))), {tmpReg1}, {tmpReg1, tmpReg2}, false); self:freeRegister(tmpReg2); tmpReg2 = self:compileExpression(Ast.NumberExpression(innerBlock.id), funcDepth, 1)[1]; self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.AndExpression(self:register(scope, tmpReg1), self:register(scope, tmpReg2))), {self.POS_REGISTER}, {tmpReg1, tmpReg2}, false); self:freeRegister(tmpReg2); self:freeRegister(tmpReg1); tmpReg2 = self:compileExpression(Ast.NumberExpression(finalBlock.id), funcDepth, 1)[1]; self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(self:register(scope, self.POS_REGISTER), self:register(scope, tmpReg2))), {self.POS_REGISTER}, {self.POS_REGISTER, tmpReg2}, false); self:freeRegister(tmpReg2); self:setActiveBlock(innerBlock); scope = innerBlock.scope; self.registers[self.POS_REGISTER] = posState; local varReg = self:getVarRegister(statement.scope, statement.id, funcDepth, nil); if(self:isUpvalue(statement.scope, statement.id)) then scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction); self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {varReg}, {}, false); self:addStatement(self:setUpvalueMember(scope, self:register(scope, varReg), self:register(scope, currentReg)), {}, {varReg, currentReg}, true); else self:addStatement(self:setRegister(scope, varReg, self:register(scope, currentReg)), {varReg}, {currentReg}, false); end self:compileBlock(statement.body, funcDepth); self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(checkBlock.id)), {self.POS_REGISTER}, {}, false); self.registers[self.POS_REGISTER] = self.VAR_REGISTER; self:freeRegister(finalReg); self:freeRegister(incrementIsNegReg); self:freeRegister(incrementReg); self:freeRegister(currentReg, true); self.registers[self.POS_REGISTER] = posState; self:setActiveBlock(finalBlock); end;