From 29aac917d534c6a95d7d46d1798d61f1621436ad Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 25 Jan 2026 17:20:14 +0000 Subject: [PATCH] 18:19 --- backend/src/services/obfuscator.js | 91 ++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/backend/src/services/obfuscator.js b/backend/src/services/obfuscator.js index c0a37e9..c1479e3 100644 --- a/backend/src/services/obfuscator.js +++ b/backend/src/services/obfuscator.js @@ -47,7 +47,7 @@ class ObfuscatorService { while (i < code.length && code[i] !== q) { if (code[i] === '\\') { i++; - if (code[i] === 'x') { s += String.fromCharCode(parseInt(code.substr(i + 1, 2), 16)); i += 3; } + if (code[i] === 'x') { s += String.fromCharCode(parseInt(code.substr(i + 1, 2), 16)); i += 3; } else if (/\d/.test(code[i])) { let d = ""; while (i < code.length && /\d/.test(code[i]) && d.length < 3) { d += code[i]; i++; } s += String.fromCharCode(parseInt(d, 10)); @@ -87,7 +87,7 @@ class ObfuscatorService { return tokens; } - static numberToExpression(n, seed = 0) { + static numberToExpression(n) { if (typeof n !== 'number') return n; let current = Math.floor(Math.random() * 1000); let expr = `(${current})`; @@ -95,13 +95,13 @@ class ObfuscatorService { for (let i = 0; i < steps; i++) { const mode = Math.floor(Math.random() * 4); const v = Math.floor(Math.random() * 200) + 1; - if (mode === 0) { current += v; expr = `(${expr} + ${v})`; } - else if (mode === 1) { current -= v; expr = `(${expr} - ${v})`; } - else if (mode === 2) { current *= 2; expr = `(${expr} * 2)`; } + if (mode === 0) { current += v; expr = `(${expr} + ${v})`; } + else if (mode === 1) { current -= v; expr = `(${expr} - ${v})`; } + else if (mode === 2) { current *= 2; expr = `(${expr} * 2)`; } else { const nv = Math.floor(Math.random() * 255); current = (current ^ nv) >>> 0; - expr = `bit32.bxor(${expr}, ${nv})`; + expr = `(bit32 or bit).bxor(${expr}, ${nv})`; } } const diff = n - current; @@ -321,7 +321,7 @@ class ObfuscatorService { static generateVM(bc, constants, ops, seed) { const r = () => "_" + crypto.randomBytes(3).toString('hex'); - const nL = r(), nC = r(), nR = r(), nPC = r(), nD = r(), nDS = r(), nENV = r(); + const nL = r(), nC = r(), nR = r(), nPC = r(), nD = r(), nDS = r(), nENV = r(), nLDR = r(), nBIT = r(); const encC = constants.map(c => { if (c.type === 'string') { @@ -345,7 +345,7 @@ class ObfuscatorService { d[ops.SETG] = `function() ${nENV}[${nD}(${nL}[${nPC}+1])] = ${nR}[${nL}[${nPC}]]; ${nPC}=${nPC}+2 end`; d[ops.GETT] = `function() local r,t,k = ${nL}[${nPC}],${nL}[${nPC}+1],${nL}[${nPC}+2]; ${nPC}=${nPC}+3; ${nR}[r] = ${nR}[t][${nD}(k)] end`; d[ops.GETS] = `function() local r,t,k = ${nL}[${nPC}],${nL}[${nPC}+1],${nL}[${nPC}+2]; ${nPC}=${nPC}+3; local o = ${nR}[t]; ${nR}[r+1] = o; ${nR}[r] = o[${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; local f = ${nR}[r]; if not f then error("Luartex VM Error: Call to nil at PC "..${nPC}) end; local res = {f(table.unpack(a))}; for i=1,nr do ${nR}[r+i-1] = res[i] end 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; local f = ${nR}[r]; if not f then error("Luartex VM Error: Call to nil at PC "..${nPC}) end; local res = {f((table.unpack or unpack)(a))}; for i=1,nr do ${nR}[r+i-1] = res[i] end 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; if k == -1 then ${nR}[t][${nR}[${nL}[${nPC}-2]]] = ${nR}[v] else ${nR}[t][${nD}(k)] = ${nR}[v] end end`; @@ -358,7 +358,7 @@ class ObfuscatorService { d[ops.EQ] = `function() ${nR}[${nL}[${nPC}]] = (${nR}[${nL}[${nPC}+1]] == ${nR}[${nL}[${nPC}+2]]); ${nPC}=${nPC}+3 end`; d[ops.LT] = `function() ${nR}[${nL}[${nPC}]] = (${nR}[${nL}[${nPC}+1]] < ${nR}[${nL}[${nPC}+2]]); ${nPC}=${nPC}+3 end`; d[ops.LE] = `function() ${nR}[${nL}[${nPC}]] = (${nR}[${nL}[${nPC}+1]] <= ${nR}[${nL}[${nPC}+2]]); ${nPC}=${nPC}+3 end`; - d[ops.CLOSURE] = `function() local r,k = ${nL}[${nPC}],${nL}[${nPC}+1]; ${nPC}=${nPC}+2; ${nR}[r] = loadstring(${nD}(k)) end`; + d[ops.CLOSURE] = `function() local r,k = ${nL}[${nPC}],${nL}[${nPC}+1]; ${nPC}=${nPC}+2; ${nR}[r] = ${nLDR}(${nD}(k)) end`; const shuffled = Object.keys(ops).sort(() => Math.random() - 0.5); const opMap = {}; shuffled.forEach((k, i) => opMap[ops[k]] = i); @@ -373,12 +373,14 @@ class ObfuscatorService { const dispatchFunctions = shuffled.map(k => d[ops[k]]).join(',\n'); const vmCode = `local function VM(...) + local ${nLDR} = loadstring or load local ${nENV} = (getfenv and getfenv()) or _G + local ${nBIT} = bit32 or bit local ${nL} = {${finalBC.join(',')}} local ${nC} = {${encC}} 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 + __index = function(t, k) return rawget(t, ${nBIT}.bxor(k, ${xorKey})) end, + __newindex = function(t, k, v) rawset(t, ${nBIT}.bxor(k, ${xorKey}), v) end }) local ${nPC} = 1 local function ${nD}(i) @@ -386,19 +388,29 @@ class ObfuscatorService { local c = ${nC}[i+1]; if not c then return end if c.t == 1 then local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - local s = c.v:gsub("[^"..b.."=]", ""); local res = "" + local s = c.v:gsub("[^" .. b .. "=]", ""); + local res = {} + local count = 0 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(${seed},255))) end end + for k=0,3 do + local char = s:sub(j+k,j+k) + local pos = b:find(char,1,true) + v = v*64 + (pos and pos-1 or 0) + end + for k=2,0,-1 do + if j+3-k<=#s and s:sub(j+3-k,j+3-k)~="=" then + count = count + 1 + res[count] = string.char(${nBIT}.bxor(${nBIT}.extract(v,k*8,8),${nBIT}.band(${seed},255))) + end + end end - return res - elseif c.t == 2 then return bit32.bxor(c.v, bit32.band(${seed}, 65535)) - c.o + return table.concat(res) + elseif c.t == 2 then return ${nBIT}.bxor(c.v, ${nBIT}.band(${seed}, 65535)) - c.o elseif c.t == 3 then return true elseif c.t == 4 then return false elseif c.t == 5 then return nil end end local ${nDS} = {${dispatchFunctions}} - -- Anti-Tamper / Opaque Predicate - local _p = function() return tick() > 0 end + local _p = function() return (os.clock() or tick() or 1) > 0 end while _p() do local op = ${nL}[${nPC}]; if not op then break end ${nPC} = ${nPC} + 1 @@ -415,21 +427,38 @@ class ObfuscatorService { for (let i = 0; i < layers; i++) { const key = (seed >> (i * 8)) & 0xFF; const encoded = Buffer.from(current).map(b => b ^ key).toString('base64'); - const sExp = this.numberToExpression(seed); + const keyExp = this.numberToExpression(key); current = `local _v = "${encoded}" - local _s = ${sExp} - 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 +local _k = ${keyExp} +local function _d(s) + local _b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+" + local _bit = bit32 or bit + local res = {} + local count = 0 + s = s:gsub("[^" .. _b:gsub("%%", "%%%%") .. "=]", "") + for j = 1, #s, 4 do + local v = 0 + for k = 0, 3 do + local char = s:sub(j + k, j + k) + local pos = _b:find(char, 1, true) + v = v * 64 + (pos and pos - 1 or 0) end - local _f, _e = loadstring(_d(_v)) - if _f then return _f() else error("Luartex Layer Error: "..tostring(_e)) end`; + for k = 2, 0, -1 do + if j + 3 - k <= #s and s:sub(j + 3 - k, j + 3 - k) ~= "=" then + count = count + 1 + res[count] = string.char(_bit.bxor(_bit.extract(v, k * 8, 8), _k)) + end + end + end + return table.concat(res) +end +local _l = loadstring or load +local _f, _e = _l(_d(_v)) +if _f then + return _f() +else + error("Luartex Layer Error: " .. tostring(_e)) +end`; } return current; }