Newest 16:33

This commit is contained in:
Flatlogic Bot 2026-01-25 15:34:00 +00:00
parent 6d9e2d7c97
commit 6eb4a6e0d6

View File

@ -13,7 +13,7 @@ class ObfuscatorService {
let i = 0;
while (i < code.length) {
let c = code[i];
if (/\\s/.test(c)) { i++; continue; }
if (/\s/.test(c)) { i++; continue; }
if (c === '-' && code[i + 1] === '-') {
i += 2;
if (code[i] === '[' && code[i + 1] === '[') {
@ -28,15 +28,15 @@ class ObfuscatorService {
if (c === '"' || c === "'") {
const q = c; let s = ""; i++;
while (i < code.length && code[i] !== q) {
if (code[i] === '\\') { s += code[i] + (code[i + 1] || ""); i += 2; }
if (code[i] === '\\') { s += code[i] + (code[i + 1] || ""); i += 2; }
else { s += code[i]; i++; }
}
tokens.push({ type: 'string', value: s });
i++; continue;
}
if (/\\d/.test(c)) {
if (/\d/.test(c)) {
let n = "";
while (i < code.length && /[\\d\.xX]/.test(code[i])) { n += code[i]; i++; }
while (i < code.length && /[\d\.\xX]/.test(code[i])) { n += code[i]; i++; }
tokens.push({ type: 'number', value: parseFloat(n) });
continue;
}
@ -51,6 +51,32 @@ class ObfuscatorService {
return tokens;
}
static numberToExpression(n) {
if (typeof n !== 'number') return n;
const ops = ['+', '-', '*'];
let current = Math.floor(Math.random() * 200) - 100;
let expr = `(${current})`;
for (let i = 0; i < 4; i++) {
const op = ops[Math.floor(Math.random() * ops.length)];
const val = Math.floor(Math.random() * 100) + 1;
if (op === '+') { current += val; expr = `(${expr} + ${val})`; }
else if (op === '-') { current -= val; expr = `(${expr} - ${val})`; }
else if (op === '*') {
if (Math.abs(current * val) < 1000000) {
current *= val; expr = `(${expr} * ${val})`;
}
}
}
const diff = n - current;
if (diff >= 0) expr = `(${expr} + ${diff})`;
else expr = `(${expr} - ${Math.abs(diff)})`;
const noise = Math.floor(Math.random() * 255);
return `bit32.bxor(bit32.bxor(${expr}, ${noise}), ${noise})`;
}
static compile(tokens) {
const constants = [];
const getC = (v) => {
@ -58,65 +84,119 @@ class ObfuscatorService {
if (idx === -1) { idx = constants.length; constants.push({ value: v, type: typeof v }); }
return idx;
};
const ops = {LOADK:0, GETG:1, SETG:2, CALL:3, RET:4, GETT:5, GETS:6};
const ops = {
LOADK: 0, GETG: 1, SETG: 2, CALL: 3, RET: 4, GETT: 5, GETS: 6,
NEWTABLE: 7, SETTABLE: 8, GETLOCAL: 9, SETLOCAL: 10
};
const bc = [];
let ti = 0;
const pExpr = (reg) => {
let t = tokens[ti]; if (!t) return;
const locals = {};
let nextLocal = 0;
const peek = () => tokens[ti];
const consume = () => tokens[ti++];
const parseExpr = (reg) => {
let t = peek(); if (!t) return;
if (t.type === 'number' || t.type === 'string') {
bc.push(ops.LOADK, reg, getC(t.value)); ti++;
bc.push(ops.LOADK, reg, getC(consume().value));
} else if (t.type === 'identifier') {
const name = t.value; ti++;
if (tokens[ti]?.value === '(') { ti--; pCall(reg); }
else if (tokens[ti]?.value === ':') {
ti++; const m = tokens[ti].value; ti++;
bc.push(ops.GETG, reg, getC(name));
bc.push(ops.GETS, reg, reg, getC(m));
pArgs(reg, true);
} else if (tokens[ti]?.value === '.') {
bc.push(ops.GETG, reg, getC(name));
while (tokens[ti]?.value === '.') {
ti++; const k = tokens[ti].value; ti++;
bc.push(ops.GETT, reg, reg, getC(k));
let name = consume().value;
if (peek()?.value === '(') {
ti--; parseCall(reg);
} else {
emitGet(reg, name);
while (peek()?.value === '.' || peek()?.value === ':') {
let op = consume().value;
let key = consume().value;
if (op === ':') {
bc.push(ops.GETS, reg, reg, getC(key));
parseArgs(reg, true);
} else {
bc.push(ops.GETT, reg, reg, getC(key));
if (peek()?.value === '(') parseArgs(reg);
}
}
} else { bc.push(ops.GETG, reg, getC(name)); }
}
} else if (t.value === '{') {
parseTable(reg);
}
};
const pArgs = (reg, isM) => {
if (tokens[ti]?.value !== '(') return;
ti++; let ac = isM ? 1 : 0;
while (ti < tokens.length && tokens[ti].value !== ')') {
if (tokens[ti].value === ',') { ti++; continue; }
ac++; pExpr(reg + ac);
const parseTable = (reg) => {
bc.push(ops.NEWTABLE, reg); consume(); // {
while (ti < tokens.length && peek().value !== '}') {
if (peek().value === ',') { consume(); continue; }
let t = peek();
if (tokens[ti+1]?.value === '=') {
let key = consume().value; consume(); // =
parseExpr(reg + 1);
bc.push(ops.SETTABLE, reg, getC(key), reg + 1);
} else {
parseExpr(reg + 1);
}
if (peek()?.value === ',') consume();
}
if (peek()?.value === '}') consume();
};
const emitGet = (reg, name) => {
if (locals[name] !== undefined) bc.push(ops.GETLOCAL, reg, locals[name]);
else bc.push(ops.GETG, reg, getC(name));
};
const parseArgs = (reg, isM) => {
if (peek()?.value !== '(') return;
consume(); let ac = isM ? 1 : 0;
while (ti < tokens.length && peek().value !== ')') {
if (peek().value === ',') { consume(); continue; }
ac++; parseExpr(reg + ac);
}
bc.push(ops.CALL, reg, ac + 1, 1);
if (tokens[ti]?.value === ')') ti++;
if (peek()?.value === ')') consume();
};
const pCall = (reg) => {
const fn = tokens[ti].value; ti++;
bc.push(ops.GETG, reg, getC(fn)); pArgs(reg);
const parseCall = (reg) => {
let fn = consume().value;
emitGet(reg, fn);
parseArgs(reg);
};
while (ti < tokens.length) {
let t = tokens[ti];
if (t.type === 'identifier' && tokens[ti+1]?.value === '=') {
const vn = t.value; ti += 2; pExpr(0);
bc.push(ops.SETG, 0, getC(vn)); continue;
let t = peek();
if (t.value === 'local') {
consume();
let name = consume().value;
if (peek()?.value === '=') {
consume(); parseExpr(nextLocal);
locals[name] = nextLocal++;
} else {
locals[name] = nextLocal++;
}
} else if (t.type === 'identifier' && tokens[ti+1]?.value === '=') {
let vn = consume().value; consume();
parseExpr(nextLocal);
if (locals[vn] !== undefined) bc.push(ops.SETLOCAL, locals[vn], nextLocal);
else bc.push(ops.SETG, nextLocal, getC(vn));
} else if (t.type === 'identifier' && (tokens[ti+1]?.value === '(' || tokens[ti+1]?.value === ':')) {
parseExpr(nextLocal);
} else {
ti++;
}
if (t.type === 'identifier' && (tokens[ti+1]?.value === '(' || tokens[ti+1]?.value === ':')) {
pExpr(0); continue;
}
ti++;
}
bc.push(ops.RET, 0, 1);
return { bc, constants, ops };
}
static generateVM(bc, constants, ops, seed) {
const r = () => "_" + Math.random().toString(36).substring(7);
const nL = r(), nC = r(), nR = r(), nPC = r(), nK = r(), nD = r(), nDS = r();
const r = () => "_" + Math.random().toString(36).substring(7) + "_" + Math.floor(Math.random() * 10000);
const nL = r(), nC = r(), nR = r(), nPC = r(), nK = r(), nD = r(), nDS = r(), nLOC = r();
const nENV = r(), nTIME = r(), nX = r(), nY = r();
const encC = constants.map(c => {
if (c.type === 'string') {
const e = Buffer.from(c.value).map(b => b ^ (seed & 0xFF)).toString('base64');
const key = seed & 0xFF;
const e = Buffer.from(c.value).map(b => b ^ key).toString('base64');
return `{t=1,v="${e}"}`;
}
if (c.type === 'number') {
@ -125,7 +205,33 @@ class ObfuscatorService {
}
return `{t=0}`;
}).join(',');
const xorKey = seed % 255;
const antiTamper = `
local ${nENV} = getfenv and getfenv() or _G
local ${nTIME} = tick()
local function check()
if ${nENV}.debug and ${nENV}.debug.getinfo then
local i = ${nENV}.debug.getinfo(check)
if i.what ~= "Lua" then while true do end end
end
local s = tick()
for i=1,1000 do end
if tick() - s > 1 then while true do end end
end
check()
task.spawn(function()
while true do
if tick() - ${nTIME} > 4 then
local ${nX} = nil; ${nX}.crash()
end
${nTIME} = tick()
task.wait(3)
end
end)
`;
const d = [];
d[ops.LOADK] = `function() ${nR}[${nL}[${nPC}]] = ${nD}(${nL}[${nPC}+1]); ${nPC}=${nPC}+2 end`;
d[ops.GETG] = `function() ${nR}[${nL}[${nPC}]] = _G[${nD}(${nL}[${nPC}+1])]; ${nPC}=${nPC}+2 end`;
@ -134,21 +240,49 @@ class ObfuscatorService {
d[ops.GETS] = `function() local r,t,k = ${nL}[${nPC}],${nL}[${nPC}+1],${nL}[${nPC}+2]; ${nPC}=${nPC}+3; ${nR}[r+1] = ${nR}[t]; ${nR}[r] = ${nR}[t][${nD}(k)] end`;
d[ops.CALL] = `function() local r,na,nr = ${nL}[${nPC}],${nL}[${nPC}+1],${nL}[${nPC}+2]; ${nPC}=${nPC}+3; local a={}; for i=1,na-1 do a[i]=${nR}[r+i] end; ${nR}[r]=${nR}[r](table.unpack(a)) end`;
d[ops.RET] = `function() return "EXIT" end`;
d[ops.NEWTABLE] = `function() ${nR}[${nL}[${nPC}]] = {}; ${nPC}=${nPC}+1 end`;
d[ops.SETTABLE] = `function() local t,k,v = ${nL}[${nPC}],${nL}[${nPC}+1],${nL}[${nPC}+2]; ${nPC}=${nPC}+3; ${nR}[t][${nD}(k)] = ${nR}[v] end`;
d[ops.GETLOCAL] = `function() ${nR}[${nL}[${nPC}]] = ${nLOC}[${nL}[${nPC}+1]+1]; ${nPC}=${nPC}+2 end`;
d[ops.SETLOCAL] = `function() ${nLOC}[${nL}[${nPC}]+1] = ${nR}[${nL}[${nPC}+1]]; ${nPC}=${nPC}+2 end`;
const xorKey = seed % 255;
const argCounts = {
[ops.LOADK]: 2, [ops.GETG]: 2, [ops.SETG]: 2, [ops.GETT]: 3,
[ops.GETS]: 3, [ops.CALL]: 3, [ops.RET]: 2, [ops.NEWTABLE]: 1,
[ops.SETTABLE]: 3, [ops.GETLOCAL]: 2, [ops.SETLOCAL]: 2
};
return `local function VM(...)
local ${nL} = {${bc.join(',')}}
const shuffled = Object.keys(ops).sort(() => Math.random() - 0.5);
const opMap = {};
shuffled.forEach((k, i) => opMap[ops[k]] = i);
const finalBC = [];
for (let i = 0; i < bc.length; ) {
const op = bc[i];
finalBC.push(opMap[op]);
i++;
const count = argCounts[op] || 0;
for (let j = 0; j < count; j++) {
finalBC.push(bc[i] || 0);
i++;
}
}
const dispatchFunctions = shuffled.map(k => d[ops[k]] || "function() end").join(',');
const vmCode = `local function VM(...)
${antiTamper}
local ${nL} = {${finalBC.join(',')}}
local ${nC} = {${encC}}
local ${nLOC} = {}
local ${nR} = setmetatable({}, {
__index = function(t, k) return rawget(t, bit32.bxor(k, ${xorKey})) end,
__newindex = function(t, k, v) rawset(t, bit32.bxor(k, ${xorKey}), v) end
})
local ${nPC} = 1; local ${nK} = ${seed}
local ${nPC} = ${this.numberToExpression(1)}; local ${nK} = ${this.numberToExpression(seed)}
local function ${nD}(i)
local c = ${nC}[i+1]; if not c then return end
if c.t == 1 then
local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
local s = c.v:gsub("[^"..b.."=]", ""); local res = ""
for j=1,#s,4 do
local v = 0
@ -158,13 +292,39 @@ class ObfuscatorService {
return res
elseif c.t == 2 then return bit32.bxor(c.v, bit32.band(${nK}, 65535)) - c.o end
end
local ${nDS} = {${d.join(',')}}
while ${nL}[${nPC}] do
local op = ${nL}[${nPC}]; ${nPC} = ${nPC} + 1
local ${nDS} = {${dispatchFunctions}}
while true do
local op = ${nL}[${nPC}]; if not op then break end
${nPC} = ${nPC} + 1
local f = ${nDS}[op+1]
if f then if f() == "EXIT" then break end else break end
end
end; VM(...)`
end; VM(...)`;
const wrapLayers = (code, layers) => {
let current = code;
for (let i = 0; i < layers; i++) {
const layerSeed = crypto.randomBytes(4).readUInt32BE(0);
const encoded = Buffer.from(current).map(b => b ^ (layerSeed & 0xFF)).toString('base64');
current = `local _v = "${encoded}"
local _s = ${this.numberToExpression(layerSeed)}
local function _d(s)
local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
local res = ""
for j=1,#s,4 do
local v = 0
for k=0,3 do local char = s:sub(j+k,j+k); v = v*64 + (char=="=" and 0 or (b:find(char,1,true)-1)) end
for k=2,0,-1 do if j+3-k<=#s and s:sub(j+3-k,j+3-k)~="=" then res = res..string.char(bit32.bxor(bit32.extract(v,k*8,8),bit32.band(_s,255))) end end
end
return res
end
local _f = loadstring(_d(_v))
if _f then _f() end`;
}
return current;
};
return wrapLayers(vmCode, 2);
}
}
module.exports = ObfuscatorService;