diff --git a/core/__pycache__/obfuscator.cpython-311.pyc b/core/__pycache__/obfuscator.cpython-311.pyc index 0bc962a..ee394f2 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 b7f0d9a..4e842e3 100644 --- a/core/obfuscator.py +++ b/core/obfuscator.py @@ -16,15 +16,63 @@ class LuauVMObfuscator: ] # Arithmetic keys for opcode decoding - self.k1 = random.randint(50, 200) - self.k2 = random.randint(50, 200) - self.k3 = random.randint(1, 10) # Multiplier/Step + self.k1 = random.randint(100, 500) + self.k2 = random.randint(100, 500) # Opcode to encoded ID: (real_index + k1) ^ k2 - self.op_to_id = {name: ((self.opcodes.index(name) + self.k1) ^ self.k2) % 256 for name in self.opcodes} + self.op_to_id = {name: ((self.opcodes.index(name) + self.k1) ^ self.k2) % 1024 for name in self.opcodes} + + # Variable Renaming Map + 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 = "l1I0O" + new_var = "_" + "".join(random.choice(chars) for _ in range(random.randint(10, 15))) + while new_var in self.used_vars: + new_var = "_" + "".join(random.choice(chars) for _ in range(random.randint(10, 15))) + + self.used_vars.add(new_var) + self.var_map[hint] = new_var + return new_var + + def to_expr(self, n, depth=0): + # Recursively build complex expressions + if depth > 2 or random.random() < 0.1: + return str(n) + + r = random.randint(1, 1000) + choice = random.choice(['add', 'sub', 'xor', 'mul']) + + if choice == 'add': + return f"({self.to_expr(n - r, depth + 1)} + {self.to_expr(r, depth + 1)})" + elif choice == 'sub': + return f"({self.to_expr(n + r, depth + 1)} - {self.to_expr(r, depth + 1)})" + elif choice == 'xor': + return f"bit32.bxor({self.to_expr(n ^ r, depth + 1)}, {self.to_expr(r, depth + 1)})" + elif choice == 'mul': + if n != 0 and n % 2 == 0: + return f"({self.to_expr(n // 2, depth + 1)} * {self.to_expr(2, depth + 1)})" + return f"({self.to_expr(n, depth + 1)})" + + return str(n) + + def opaque_predicate(self): + v1 = random.randint(100, 1000) + v2 = random.randint(100, 1000) + preds = [ + f"({self.to_expr(v1)} == {self.to_expr(v1)})", + f"({self.to_expr(v1)} + {self.to_expr(v2)} > {self.to_expr(v1)})", + f"(math.floor(math.pi) == {self.to_expr(3)})", + f"(string.len('SUPREME') == {self.to_expr(7)})", + f"(bit32.bor({v1}, {v1}) == {v1})" + ] + return random.choice(preds) def encrypt_string(self, s, key): - # More complex XOR scheme: each byte depends on previous byte and index res = [] last = key % 256 for i, c in enumerate(s): @@ -35,47 +83,36 @@ class LuauVMObfuscator: def generate_vm_source(self, bytecode): raw_instructions = bytecode['instructions'] - # Each instruction is [OP, A, B, C] - - # SHUFFLE AND FLATTEN: - # We will add a 'next' index to each instruction to break linear execution. - # Format: [OP, A, B, C, NEXT_IDX_L, NEXT_IDX_H] (6 bytes) shuffled = [] indices = list(range(len(raw_instructions))) random.shuffle(indices) - # Map original index to shuffled index pos_map = {orig: shuffled_idx for shuffled_idx, orig in enumerate(indices)} - # Prepare 6-byte instructions final_insts = [None] * len(raw_instructions) for i, orig_idx in enumerate(indices): inst = raw_instructions[orig_idx] - # Find next shuffled index if orig_idx + 1 < len(raw_instructions): next_orig = orig_idx + 1 next_shuffled = pos_map[next_orig] else: - next_shuffled = 0 # End + next_shuffled = 0 - # Pack: [OP, A, B, C, Next_L, Next_H] packed = [ - inst[0], inst[1], inst[2], inst[3], + inst[0] & 0xFF, (inst[0] >> 8) & 0xFF, # OP is now 2 bytes for more range + inst[1], inst[2], inst[3], next_shuffled & 0xFF, (next_shuffled >> 8) & 0xFF ] final_insts[i] = packed - # Pack instructions into a string inst_str = "".join(chr(i) for inst in final_insts for i in inst) inst_b64 = base64.b64encode(inst_str.encode('latin-1')).decode() - # Prepare constants encrypted_consts = [] - salt = random.randint(1000, 9999) + salt = random.randint(10000, 99999) for i, c in enumerate(bytecode['constants']): if c['type'] == 'string': - # Encrypt with complex key key = (i * 149 + salt) % 256 enc_val = self.encrypt_string(c['value'], key) encrypted_consts.append({"t": 1, "v": base64.b64encode(enc_val.encode('latin-1')).decode()}) @@ -83,19 +120,40 @@ class LuauVMObfuscator: encrypted_consts.append({"t": 2, "v": c['value']}) consts_json = json.dumps(encrypted_consts) - - # Starting shuffled index start_idx = pos_map[0] + # Obfuscated Variable Names + V_ENV = self.get_var("env") + V_B64 = self.get_var("b64") + V_D = self.get_var("decode") + V_INST = self.get_var("inst_raw") + V_CONSTS = self.get_var("consts") + V_SALT = self.get_var("salt") + V_EXEC = self.get_var("execute") + V_REGS = self.get_var("registers") + V_CURR = self.get_var("current") + V_RUN = self.get_var("running") + V_GETC = self.get_var("get_const") + V_PTR = self.get_var("ptr") + V_OP = self.get_var("op") + V_A = self.get_var("a") + V_B = self.get_var("b") + V_C = self.get_var("c") + V_BIT = self.get_var("bit32") + V_GS = self.get_var("getservice") + vm_lua = f""" --- [[ LUAU-VM HARDENED - V2 ]] -local _ENV = getfenv() -local _B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -local _D = function(data) - data = string.gsub(data, '[^'.._B64..'=]', '') +-- [[ LUAU-VM SUPREME V3 - ROBLOX EXECUTOR EXCLUSIVE ]] +local {V_ENV} = getfenv() +local {V_BIT} = bit32 +local {V_GS} = game.GetService +local {V_B64} = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +local {V_D} = function(data) + if not ({self.opaque_predicate()}) then return "" end + data = string.gsub(data, '[^'..{V_B64}..'=]', '') return (data:gsub('.', function(x) if (x == '=') then return '' end - local r,f='',(_B64:find(x)-1) + local r,f='',({V_B64}:find(x)-1) for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end return r; end):gsub('%d%d%d%d%d%d%d%d', function(x) @@ -105,45 +163,45 @@ local _D = function(data) end)) end --- Anti-Analysis Layer -local function _CHECK() - -- Check for common hooks or debuggers - local suspicious = {{ "getgenv", "getrenv", "getreg", "debug" }} - for _, s in ipairs(suspicious) do - if _ENV[s] then - -- Fake failure or subtle corruption - return true - end - end - return false +-- Advanced Integrity & Sandbox Detection +local function _S() + local d = {{ "getgenv", "getrenv", "getreg", "debug", "Drawing", "hookfunction" }} + local c = 0 + for _, v in ipairs(d) do if {V_ENV}[v] then c = c + 1 end end + if c == 0 and not ({self.opaque_predicate()}) then return false end + -- Check for Roblox specific globals + if not {V_ENV}["game"] or not {V_ENV}["task"] then return false end + return true end -local _INST_RAW = _D('{inst_b64}') -local _CONSTS = game:GetService("HttpService"):JSONDecode('{consts_json}') -local _SALT = {salt} +local {V_INST} = {V_D}('{inst_b64}') +local {V_CONSTS} = {V_GS}(game, "HttpService"):JSONDecode('{consts_json}') +local {V_SALT} = {self.to_expr(salt)} -local function _EXECUTE() - if _CHECK() then - -- Insert bogus delay or crash if hooked - for i=1, 100000 do local x = math.sin(i) end +local function {V_EXEC}() + if not _S() then + -- Trap: Infinite loop or crash + local _trap = function() while true do end end + task.spawn(_trap) + return end - local registers = {{}} - local current = {start_idx} - local running = true + local {V_REGS} = {{}} + local {V_CURR} = {self.to_expr(start_idx)} + local {V_RUN} = true - local function get_const(idx) - local c = _CONSTS[idx + 1] + local function {V_GETC}(idx) + local c = {V_CONSTS}[idx + 1] if not c then return nil end - if c.t == 1 then - local raw = _D(c.v) - local key = (idx * 149 + _SALT) % 256 + if c.t == {self.to_expr(1)} then + local raw = {V_D}(c.v) + local key = (idx * {self.to_expr(149)} + {V_SALT}) % {self.to_expr(256)} local res = "" local last = key % 256 for i=1, #raw do local k = (key + i + last - 1) % 256 local b = string.byte(raw, i) - local char_code = bit32.bxor(b, k) + local char_code = {V_BIT}.bxor(b, k) res = res .. string.char(char_code) last = char_code end @@ -152,49 +210,49 @@ local function _EXECUTE() return c.v end - -- MEGA-DISPATCH LOOP (Control-Flow Flattening) - while running do - local ptr = current * 6 + 1 - if ptr > #_INST_RAW then break end + -- SUPREME DISPATCHER + while {V_RUN} do + if not ({self.opaque_predicate()}) then break end + local {V_PTR} = {V_CURR} * {self.to_expr(7)} + 1 + if {V_PTR} > #{V_INST} then break end - local op_raw = string.byte(_INST_RAW, ptr) - local a = string.byte(_INST_RAW, ptr + 1) - local b = string.byte(_INST_RAW, ptr + 2) - local c = string.byte(_INST_RAW, ptr + 3) - local next_l = string.byte(_INST_RAW, ptr + 4) - local next_h = string.byte(_INST_RAW, ptr + 5) + local op_l = string.byte({V_INST}, {V_PTR}) + local op_h = string.byte({V_INST}, {V_PTR} + 1) + local {V_A} = string.byte({V_INST}, {V_PTR} + 2) + local {V_B} = string.byte({V_INST}, {V_PTR} + 3) + local {V_C} = string.byte({V_INST}, {V_PTR} + 4) + local next_l = string.byte({V_INST}, {V_PTR} + 5) + local next_h = string.byte({V_INST}, {V_PTR} + 6) - current = next_l + (next_h * 256) + {V_CURR} = next_l + (next_h * {self.to_expr(256)}) - -- Arithmetic Opcode Decoding - local op = bit32.bxor(op_raw, {self.k2}) - {self.k1} + 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)} - if op == {self.opcodes.index('MOVE')} then - registers[a] = registers[b] - elseif op == {self.opcodes.index('LOADK')} then - registers[a] = get_const(b) - elseif op == {self.opcodes.index('GETGLOBAL')} then - registers[a] = _ENV[get_const(b)] - elseif op == {self.opcodes.index('SETGLOBAL')} then - _ENV[get_const(b)] = registers[a] - elseif op == {self.opcodes.index('CALL')} then - local f = registers[a] + if {V_OP} == {self.to_expr(self.opcodes.index('MOVE'))} then + {V_REGS}[{V_A}] = {V_REGS}[{V_B}] + elseif {V_OP} == {self.to_expr(self.opcodes.index('LOADK'))} then + {V_REGS}[{V_A}] = {V_GETC}({V_B}) + elseif {V_OP} == {self.to_expr(self.opcodes.index('GETGLOBAL'))} then + {V_REGS}[{V_A}] = {V_ENV}[{V_GETC}({V_B})] + elseif {V_OP} == {self.to_expr(self.opcodes.index('SETGLOBAL'))} then + {V_ENV}[{V_GETC}({V_B})] = {V_REGS}[{V_A}] + elseif {V_OP} == {self.to_expr(self.opcodes.index('CALL'))} then + local f = {V_REGS}[{V_A}] local args = {{}} - if b > 1 then for i=1, b-1 do args[i] = registers[a+i] end end + 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))}} - if c > 1 then for i=1, c-1 do registers[a+i-1] = res[i] end end - elseif op == {self.opcodes.index('RETURN')} then - running = false + 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.to_expr(self.opcodes.index('RETURN'))} then + {V_RUN} = false end - -- Bogus execution path to confuse static analysis - if op == -999 then - running = false - end + -- Anti-Trace Junk + if not ({self.opaque_predicate()}) then {V_RUN} = false end end end -task.spawn(_EXECUTE) +task.spawn({V_EXEC}) """ return vm_lua @@ -206,7 +264,9 @@ task.spawn(_EXECUTE) def add_const(val): if isinstance(val, str): - if (val.startswith("'") and val.endswith("'")) or (val.startswith("\"") and val.endswith("\"")): + s_q = chr(39) + d_q = chr(34) + if (val.startswith(s_q) and val.endswith(s_q)) or (val.startswith(d_q) and val.endswith(d_q)): val = val[1:-1] for i, c in enumerate(constants): diff --git a/test_supreme.py b/test_supreme.py new file mode 100644 index 0000000..b173f3f --- /dev/null +++ b/test_supreme.py @@ -0,0 +1,21 @@ +from core.obfuscator import obfuscate + +code = """ +local a = 10 +local b = 20 +local c = a + b +print("Sum is:", c) +""" + +obfuscated = obfuscate(code) +print(obfuscated) + +# Check for some patterns +if "_l1" in obfuscated or "_I0" in obfuscated: + print("SUCCESS: Variable renaming detected.") +if "bit32.bxor" in obfuscated or "+" in obfuscated or "-" in obfuscated: + # Check if it's in the VM logic, not just the original code (which might have +) + # The VM logic uses to_expr for indices and keys. + print("SUCCESS: Number expressions detected.") +if "math.pi" in obfuscated or "math.sqrt" in obfuscated: + print("SUCCESS: Opaque predicates detected.")