diff --git a/core/__pycache__/obfuscator.cpython-311.pyc b/core/__pycache__/obfuscator.cpython-311.pyc index b76d8c6..fc7c4f1 100644 Binary files a/core/__pycache__/obfuscator.cpython-311.pyc and b/core/__pycache__/obfuscator.cpython-311.pyc differ diff --git a/core/obfuscator.py b/core/obfuscator.py index 316a9dc..717d755 100644 --- a/core/obfuscator.py +++ b/core/obfuscator.py @@ -16,19 +16,19 @@ class LuauVMObfuscator: "FORLOOP", "FORPREP", "TFORLOOP", "SETLIST", "CLOSE", "CLOSURE", "VARARG" ] - self.k1 = random.randint(100, 500) - self.k2 = random.randint(100, 500) - self.k3 = random.randint(100, 500) + self.k1 = random.randint(1000, 5000) + self.k2 = random.randint(1000, 5000) + self.k3 = random.randint(1000, 5000) - self.op_to_id = {name: (((self.opcodes.index(name) + self.k1) ^ self.k2) + self.k3) % 4096 for name in self.opcodes} + self.op_to_id = {name: (((self.opcodes.index(name) + self.k1) ^ self.k2) + self.k3) % 65536 for name in self.opcodes} self.var_map = {} self.used_vars = set() def get_var(self, hint="var"): if hint in self.var_map: return self.var_map[hint] - chars = "lI" - length = random.randint(8, 16) # Shorter vars for single-line efficiency + chars = "lI1" + length = random.randint(32, 48) new_var = "_" + "".join(random.choice(chars) for _ in range(length)) while new_var in self.used_vars: new_var = "_" + "".join(random.choice(chars) for _ in range(length)) @@ -36,19 +36,19 @@ class LuauVMObfuscator: self.var_map[hint] = new_var return new_var - def to_expr(self, n, depth=0): - if depth > 1 or (depth > 0 and random.random() < 0.5): + def to_expr(self, n, bit32_var="bit32", depth=0): + if depth > 2 or (depth > 0 and random.random() < 0.2): return str(n) - r = random.randint(1, 50) + r = random.randint(1, 1000000) choice = random.choice(['add', 'sub', 'xor']) if choice == 'add': - return f"({self.to_expr(n - r, depth + 1)} + {self.to_expr(r, depth + 1)})" + return f"({self.to_expr(n - r, bit32_var, depth + 1)} + {self.to_expr(r, bit32_var, depth + 1)})" elif choice == 'sub': - return f"({self.to_expr(n + r, depth + 1)} - {self.to_expr(r, depth + 1)})" + return f"({self.to_expr(n + r, bit32_var, depth + 1)} - {self.to_expr(r, bit32_var, depth + 1)})" elif choice == 'xor': - return f"bit32.bxor({self.to_expr(n ^ r, depth + 1)}, {self.to_expr(r, depth + 1)})" + return f"{bit32_var}.bxor({self.to_expr(n ^ r, bit32_var, depth + 1)}, {self.to_expr(r, bit32_var, depth + 1)})" return str(n) @@ -62,18 +62,14 @@ class LuauVMObfuscator: return "".join(res) def minify(self, code): - # Remove comments (though we don't add them, just in case) code = re.sub(r'--.*', '', code) - # Replace multiple spaces with single space code = re.sub(r'\s+', ' ', code) - # Remove spaces around operators and delimiters where safe for op in ['==', '~=', '<=', '>=', '=', r'\+', '-', r'\*', '/', '>', '<', r'\(', r'\)', r'\{', r'\}', r'\[', r'\]', ',', ';', ':']: code = re.sub(r'\s*' + op + r'\s*', op.replace('\\', ''), code) return code.strip() def generate_vm_source(self, bytecode): raw_instructions = bytecode['instructions'] - shuffled = [] indices = list(range(len(raw_instructions))) random.shuffle(indices) @@ -95,7 +91,7 @@ class LuauVMObfuscator: inst_b64 = base64.b64encode(inst_str.encode('latin-1')).decode() encrypted_consts = [] - salt = random.randint(1000, 9999) + salt = random.randint(100000, 999999) for i, c in enumerate(bytecode['constants']): if c['type'] == 'string': key = (i * 149 + salt) % 256 @@ -109,7 +105,7 @@ class LuauVMObfuscator: V_LUA_ENV = self.get_var("lua_env") V_BIT = self.get_var("bit32") - V_B64 = self.get_var("b64") + V_B64 = self.get_var("b64_alpha") V_D = self.get_var("decode") V_INST = self.get_var("inst_raw") V_CONSTS = self.get_var("consts") @@ -127,12 +123,16 @@ class LuauVMObfuscator: V_KEY = self.get_var("key") V_RES = self.get_var("res") V_LAST = self.get_var("last") + V_UNPACK = self.get_var("unpack") + V_SPAWN = self.get_var("spawn") vm_lua = f"""local {V_LUA_ENV}=getfenv() local {V_BIT}=bit32 +local {V_UNPACK}=unpack or table.unpack +local {V_SPAWN}=task and task.spawn or spawn local {V_B64}='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' local {V_D}=function(data) - data=string.gsub(data,'[^'..{V_B64}..'=]') + data=data:gsub('[^'..{V_B64}..'=]','') return(data:gsub('.',function(x) if(x=='=')then return''end local r,f='',({V_B64}:find(x)-1) @@ -145,18 +145,18 @@ local {V_D}=function(data) end)) end local {V_INST}={V_D}('{inst_b64}') -local {V_CONSTS}=game:GetService("HttpService"):JSONDecode('{consts_json}') -local {V_SALT}={self.to_expr(salt)} +local {V_CONSTS}=game:GetService("HttpService"):JSONDecode([=[{consts_json}]=]) +local {V_SALT}={self.to_expr(salt, V_BIT)} local function {V_EXEC}() local {V_REGS}={{}} - local {V_CURR}={self.to_expr(start_idx)} + local {V_CURR}={self.to_expr(start_idx, V_BIT)} local {V_RUN}=true local function {V_GETC}(idx) local c={V_CONSTS}[idx+1] if not c then return nil end - if c.t=={self.to_expr(1)} then + if c.t=={self.to_expr(1, V_BIT)} then local raw={V_D}(c.v) - local {V_KEY}=(idx*{self.to_expr(149)}+{V_SALT})%256 + local {V_KEY}=(idx*{self.to_expr(149, V_BIT)}+{V_SALT})%256 local {V_RES}={{}} local {V_LAST}={V_KEY}%256 for i=1,#raw do @@ -181,7 +181,7 @@ local function {V_EXEC}() local next_h=string.byte({V_INST},{V_PTR}+6) {V_CURR}=next_l+(next_h*256) local op_raw=op_l+(op_h*256) - local {V_OP}=({V_BIT}.bxor(op_raw,{self.to_expr(self.k2)})-{self.to_expr(self.k1)})-{self.to_expr(self.k3)} + local {V_OP}=({V_BIT}.bxor(op_raw,{self.to_expr(self.k2, V_BIT)})-{self.to_expr(self.k1, V_BIT)})-{self.to_expr(self.k3, V_BIT)} if {V_OP}=={self.opcodes.index('MOVE')} then {V_REGS}[{V_A}]={V_REGS}[{V_B}] elseif {V_OP}=={self.opcodes.index('LOADK')} then @@ -194,14 +194,14 @@ local function {V_EXEC}() local f={V_REGS}[{V_A}] local args={{}} if {V_B}>1 then for i=1,{V_B}-1 do args[i]={V_REGS}[{V_A}+i] end end - local res={{f(unpack(args))}} + local res={{f({V_UNPACK}(args))}} if {V_C}>1 then for i=1,{V_C}-1 do {V_REGS}[{V_A}+i-1]=res[i] end end elseif {V_OP}=={self.opcodes.index('RETURN')} then {V_RUN}=false end end end -task.spawn({V_EXEC})""" +{V_SPAWN}({V_EXEC})""" return self.minify(vm_lua) def compile_to_bytecode(self, ast): @@ -267,7 +267,8 @@ task.spawn({V_EXEC})""" bytecode = self.compile_to_bytecode(ast) return self.generate_vm_source(bytecode) except Exception: - return "-- Obfuscation Error" + import traceback + return f"-- Obfuscation Error: {traceback.format_exc()}" def obfuscate(code): return LuauVMObfuscator().obfuscate(code) \ No newline at end of file