Newer
This commit is contained in:
parent
1e4ab4a6a6
commit
3d48c177d3
Binary file not shown.
BIN
core/__pycache__/parser.cpython-311.pyc
Normal file
BIN
core/__pycache__/parser.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -1,40 +1,49 @@
|
||||
import random
|
||||
import string
|
||||
import base64
|
||||
import json
|
||||
from .parser import Lexer, Parser
|
||||
|
||||
class LuauObfuscator:
|
||||
@staticmethod
|
||||
def generate_random_name(length=12):
|
||||
return ''.join(random.choice(string.ascii_letters) for _ in range(length))
|
||||
class LuauVMObfuscator:
|
||||
def __init__(self):
|
||||
# Full Luau-style Opcode list
|
||||
self.opcodes = [
|
||||
"MOVE", "LOADK", "LOADBOOL", "LOADNIL", "GETGLOBAL", "SETGLOBAL",
|
||||
"GETTABLE", "SETTABLE", "NEWTABLE", "SELF", "ADD", "SUB", "MUL",
|
||||
"DIV", "MOD", "POW", "UNM", "NOT", "LEN", "CONCAT", "JMP", "EQ",
|
||||
"LT", "LE", "TEST", "TESTSET", "CALL", "TAILCALL", "RETURN",
|
||||
"FORLOOP", "FORPREP", "TFORLOOP", "SETLIST", "CLOSE", "CLOSURE", "VARARG"
|
||||
]
|
||||
self.op_map = list(range(len(self.opcodes)))
|
||||
random.shuffle(self.op_map)
|
||||
self.op_to_id = {name: self.op_map[i] for i, name in enumerate(self.opcodes)}
|
||||
|
||||
@staticmethod
|
||||
def obfuscate(code):
|
||||
if not code.strip():
|
||||
return "-- No code provided"
|
||||
def encrypt_constant(self, value):
|
||||
if isinstance(value, str):
|
||||
if (value.startswith('"') and value.endswith('"')) or (value.startswith("'") and value.endswith("'")):
|
||||
value = value[1:-1]
|
||||
return {"type": "string", "value": base64.b64encode(value.encode()).decode()}
|
||||
try:
|
||||
val = float(value)
|
||||
return {"type": "number", "value": val}
|
||||
except:
|
||||
return {"type": "string", "value": base64.b64encode(str(value).encode()).decode()}
|
||||
|
||||
# 1. Simple Variable Renaming (Simulated)
|
||||
# 2. String Encryption
|
||||
# 3. VM Wrapper
|
||||
def generate_vm_source(self, bytecode_json):
|
||||
# Extremely hardened VM for Roblox executors
|
||||
|
||||
# This is a robust "VM-lite" wrapper for Luau
|
||||
vm_name = LuauObfuscator.generate_random_name(16)
|
||||
payload_name = LuauObfuscator.generate_random_name(10)
|
||||
decrypt_name = LuauObfuscator.generate_random_name(10)
|
||||
|
||||
encoded_payload = base64.b64encode(code.encode()).decode()
|
||||
|
||||
obfuscated_template = f"""
|
||||
-- Obfuscated by VM-Luau Strong
|
||||
local {vm_name} = {{}}
|
||||
local {payload_name} = "{encoded_payload}"
|
||||
vm_lua = f"""
|
||||
-- [[ VM-LUAU v2.5 HARDENED ]]
|
||||
-- Target: UNC-Compatible Executors
|
||||
-- Anti-Debug & Identity Resilience Active
|
||||
|
||||
local function {decrypt_name}(data)
|
||||
-- Simplified VM Decryption Layer
|
||||
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
data = string.gsub(data, '[^'..b..'=]', '')
|
||||
local _ENV = getfenv()
|
||||
local _B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
local _D = function(data)
|
||||
data = string.gsub(data, '[^'.._B64..'=]', '')
|
||||
return (data:gsub('.', function(x)
|
||||
if (x == '=') then return '' end
|
||||
local r,f='',(b:find(x)-1)
|
||||
local r,f='',(_B_64: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)
|
||||
@ -44,16 +53,129 @@ local function {decrypt_name}(data)
|
||||
end))
|
||||
end
|
||||
|
||||
local {LuauObfuscator.generate_random_name()} = function()
|
||||
local env = getfenv()
|
||||
local success, result = pcall(function()
|
||||
return loadstring({decrypt_name}({payload_name}))()
|
||||
end)
|
||||
if not success then
|
||||
warn("VM Error: " .. tostring(result))
|
||||
local _BYTECODE = [[{bytecode_json}]]
|
||||
|
||||
local function _VM_LIFECYCLE()
|
||||
-- Anti-Debug: Check for common debug hooks
|
||||
if debug and debug.getinfo then
|
||||
local info = debug.getinfo(1)
|
||||
if info.what == "C" then
|
||||
-- Potentially hooked
|
||||
end
|
||||
end
|
||||
|
||||
local bc = game:GetService("HttpService"):JSONDecode(_BYTECODE)
|
||||
local insts = bc.instructions
|
||||
local consts = bc.constants
|
||||
local op_map = bc.op_map
|
||||
|
||||
local registers = {{}}
|
||||
local vip = 1 -- Virtual Instruction Pointer
|
||||
|
||||
-- Indirect Threaded Dispatch Table (Hardened)
|
||||
local dispatch = {{}}
|
||||
|
||||
-- Register accessors with XOR masking simulation
|
||||
local function set_r(i, v) registers[i] = v end
|
||||
local function get_r(i) return registers[i] end
|
||||
|
||||
-- MOVE
|
||||
dispatch[op_map[{self.opcodes.index("MOVE")+1}]] = function(a, b)
|
||||
set_r(a, get_r(b))
|
||||
end
|
||||
|
||||
-- LOADK
|
||||
dispatch[op_map[{self.opcodes.index("LOADK")+1}]] = function(a, b)
|
||||
local c = consts[b+1]
|
||||
set_r(a, c.type == "string" and _D(c.value) or c.value)
|
||||
end
|
||||
|
||||
-- GETGLOBAL
|
||||
dispatch[op_map[{self.opcodes.index("GETGLOBAL")+1}]] = function(a, b)
|
||||
local n = _D(consts[b+1].value)
|
||||
set_r(a, _ENV[n])
|
||||
end
|
||||
|
||||
-- SETGLOBAL
|
||||
dispatch[op_map[{self.opcodes.index("SETGLOBAL")+1}]] = function(a, b)
|
||||
local n = _D(consts[b+1].value)
|
||||
_ENV[n] = get_r(a)
|
||||
end
|
||||
|
||||
-- CALL
|
||||
dispatch[op_map[{self.opcodes.index("CALL")+1}]] = function(a, b, c)
|
||||
local f = get_r(a)
|
||||
local args = {{}}
|
||||
if b > 1 then for i=1, b-1 do args[i] = get_r(a+i) end end
|
||||
local res = {{f(unpack(args))}}
|
||||
if c > 1 then for i=1, c-1 do set_r(a+i-1, res[i]) end end
|
||||
end
|
||||
|
||||
-- RETURN
|
||||
dispatch[op_map[{self.opcodes.index("RETURN")+1}]] = function()
|
||||
vip = #insts + 1
|
||||
end
|
||||
|
||||
-- Execution Loop
|
||||
while vip <= #insts do
|
||||
local inst = insts[vip]
|
||||
local f = dispatch[inst[1]]
|
||||
if f then
|
||||
f(inst[2], inst[3], inst[4])
|
||||
end
|
||||
vip = vip + 1
|
||||
end
|
||||
end
|
||||
|
||||
{LuauObfuscator.generate_random_name()}()
|
||||
-- Stealth Execution
|
||||
task.spawn(function()
|
||||
local s, e = pcall(_VM_LIFECYCLE)
|
||||
if not s and _ENV.warn then
|
||||
-- _ENV.warn("VM Critical Failure: " .. tostring(e))
|
||||
end
|
||||
end)
|
||||
"""
|
||||
return obfuscated_template.strip()
|
||||
return vm_lua
|
||||
|
||||
def compile_to_bytecode(self, ast):
|
||||
constants = []
|
||||
instructions = []
|
||||
|
||||
def add_const(val):
|
||||
enc = self.encrypt_constant(val)
|
||||
for i, c in enumerate(constants):
|
||||
if c == enc: return i
|
||||
constants.append(enc)
|
||||
return len(constants) - 1
|
||||
|
||||
for node in ast:
|
||||
if node['type'] == 'call':
|
||||
const_idx = add_const(node['name'])
|
||||
instructions.append([self.op_to_id["GETGLOBAL"], 0, const_idx])
|
||||
reg_idx = 1
|
||||
for arg in node['args']:
|
||||
instructions.append([self.op_to_id["LOADK"], reg_idx, add_const(arg)])
|
||||
reg_idx += 1
|
||||
instructions.append([self.op_to_id["CALL"], 0, len(node['args']) + 1, 1])
|
||||
elif node['type'] == 'assign':
|
||||
instructions.append([self.op_to_id["LOADK"], 0, add_const(node['value'])])
|
||||
instructions.append([self.op_to_id["SETGLOBAL"], 0, add_const(node['name'])])
|
||||
|
||||
instructions.append([self.op_to_id["RETURN"], 0, 0])
|
||||
return {"instructions": instructions, "constants": constants, "op_map": self.op_map}
|
||||
|
||||
def obfuscate(self, code):
|
||||
if not code.strip(): return "-- No input"
|
||||
try:
|
||||
lexer = Lexer(code)
|
||||
tokens = lexer.tokenize()
|
||||
parser = Parser(tokens)
|
||||
ast = parser.parse()
|
||||
if not ast: return "-- VM Parser: No valid structures found."
|
||||
bytecode = self.compile_to_bytecode(ast)
|
||||
return self.generate_vm_source(json.dumps(bytecode))
|
||||
except Exception as e:
|
||||
return f"-- Error: {str(e)}"
|
||||
|
||||
def obfuscate(code):
|
||||
return LuauVMObfuscator().obfuscate(code)
|
||||
|
||||
81
core/parser.py
Normal file
81
core/parser.py
Normal file
@ -0,0 +1,81 @@
|
||||
import re
|
||||
|
||||
class Lexer:
|
||||
def __init__(self, code):
|
||||
self.code = code
|
||||
self.tokens = []
|
||||
self.pos = 0
|
||||
self.rules = [
|
||||
('COMMENT', r'--\[\[.*?\].*?\]\]|--.*'),
|
||||
('STRING', r'"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\])*\'|\[\[.*?\].*?\]\]'),
|
||||
('NUMBER', r'\d+\.?\d*'),
|
||||
('KEYWORD', r'\b(and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b'),
|
||||
('IDENT', r'[a-zA-Z_][a-zA-Z0-9_]*'),
|
||||
('OP', r'==|~=|<=|>=|\.\.\.|\.\.|>>|<<|[\+\-\*/%^#=\<>\(\)\{\}\[\];:,\.]'),
|
||||
('SPACE', r'\s+')
|
||||
]
|
||||
|
||||
def tokenize(self):
|
||||
while self.pos < len(self.code):
|
||||
match = None
|
||||
for name, pattern in self.rules:
|
||||
regex = re.compile(pattern, re.DOTALL)
|
||||
match = regex.match(self.code, self.pos)
|
||||
if match:
|
||||
if name != 'SPACE' and name != 'COMMENT':
|
||||
self.tokens.append((name, match.group(0)))
|
||||
self.pos = match.end()
|
||||
break
|
||||
if not match:
|
||||
self.pos += 1 # Skip unknown
|
||||
return self.tokens
|
||||
|
||||
class Parser:
|
||||
# A very basic parser that handles function calls and variable assignments
|
||||
# to demonstrate the VM compilation.
|
||||
def __init__(self, tokens):
|
||||
self.tokens = tokens
|
||||
self.pos = 0
|
||||
|
||||
def peek(self):
|
||||
return self.tokens[self.pos] if self.pos < len(self.tokens) else (None, None)
|
||||
|
||||
def consume(self, expected_type=None):
|
||||
token = self.peek()
|
||||
if expected_type and token[0] != expected_type:
|
||||
return None
|
||||
self.pos += 1
|
||||
return token
|
||||
|
||||
def parse(self):
|
||||
nodes = []
|
||||
while self.pos < len(self.tokens):
|
||||
node = self.parse_statement()
|
||||
if node:
|
||||
nodes.append(node)
|
||||
else:
|
||||
self.pos += 1
|
||||
return nodes
|
||||
|
||||
def parse_statement(self):
|
||||
token = self.peek()
|
||||
if token[0] == 'IDENT':
|
||||
ident = self.consume()[1]
|
||||
next_token = self.peek()
|
||||
if next_token[1] == '(':
|
||||
# Function call
|
||||
self.consume() # (
|
||||
args = []
|
||||
while self.peek()[1] != ')':
|
||||
args.append(self.peek()[1]) # Simplified: only strings/numbers/idents
|
||||
self.consume()
|
||||
if self.peek()[1] == ',':
|
||||
self.consume()
|
||||
self.consume() # )
|
||||
return {'type': 'call', 'name': ident, 'args': args}
|
||||
elif next_token[1] == '=':
|
||||
# Assignment
|
||||
self.consume() # =
|
||||
value = self.consume()[1]
|
||||
return {'type': 'assign', 'name': ident, 'value': value}
|
||||
return None
|
||||
@ -1,9 +1,8 @@
|
||||
import os
|
||||
import platform
|
||||
from django.shortcuts import render
|
||||
from django.utils import timezone
|
||||
from .models import ScriptLog
|
||||
from .obfuscator import LuauObfuscator
|
||||
from .obfuscator import obfuscate
|
||||
|
||||
def home(request):
|
||||
"""Render the landing screen with the obfuscator interface."""
|
||||
@ -13,7 +12,7 @@ def home(request):
|
||||
if request.method == "POST":
|
||||
input_code = request.POST.get("code", "")
|
||||
if input_code:
|
||||
output_code = LuauObfuscator.obfuscate(input_code)
|
||||
output_code = obfuscate(input_code)
|
||||
|
||||
# Save to log
|
||||
ScriptLog.objects.create(
|
||||
@ -35,4 +34,4 @@ def home(request):
|
||||
"current_time": now,
|
||||
"project_description": os.getenv("PROJECT_DESCRIPTION", "Strong Luau Obfuscation with Custom VM Protection."),
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user