15:40
This commit is contained in:
parent
f329f2c77a
commit
ca3f7c81d2
Binary file not shown.
@ -18,9 +18,8 @@ class LuauVMObfuscator:
|
||||
|
||||
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) % 65536 for name in self.opcodes}
|
||||
self.op_to_id = {name: (self.opcodes.index(name) + self.k1) ^ self.k2 for name in self.opcodes}
|
||||
|
||||
self.var_map = {}
|
||||
self.used_vars = set()
|
||||
@ -40,7 +39,7 @@ class LuauVMObfuscator:
|
||||
if depth > 2 or (depth > 0 and random.random() < 0.2):
|
||||
return str(n)
|
||||
|
||||
r = random.randint(1, 1000000)
|
||||
r = random.randint(1, 100000)
|
||||
choice = random.choice(['add', 'sub', 'xor'])
|
||||
|
||||
if choice == 'add':
|
||||
@ -82,7 +81,7 @@ class LuauVMObfuscator:
|
||||
|
||||
packed = [
|
||||
inst[0] & 0xFF, (inst[0] >> 8) & 0xFF,
|
||||
inst[1], inst[2], inst[3],
|
||||
inst[1] & 0xFF, inst[2] & 0xFF, inst[3] & 0xFF,
|
||||
next_shuffled & 0xFF, (next_shuffled >> 8) & 0xFF
|
||||
]
|
||||
final_insts[i] = packed
|
||||
@ -103,48 +102,52 @@ class LuauVMObfuscator:
|
||||
consts_json = json.dumps(encrypted_consts)
|
||||
start_idx = pos_map[0]
|
||||
|
||||
V_LUA_ENV = self.get_var("lua_env")
|
||||
V_BIT = self.get_var("bit32")
|
||||
V_B64 = self.get_var("b64_alpha")
|
||||
V_D = self.get_var("decode")
|
||||
V_INST = self.get_var("inst_raw")
|
||||
V_ENV = self.get_var("env")
|
||||
V_BIT = self.get_var("bit")
|
||||
V_B64 = self.get_var("b64")
|
||||
V_DEC = self.get_var("dec")
|
||||
V_INST = self.get_var("inst")
|
||||
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_EXEC = self.get_var("exec")
|
||||
V_REGS = self.get_var("regs")
|
||||
V_CURR = self.get_var("curr")
|
||||
V_RUN = self.get_var("run")
|
||||
V_GETC = self.get_var("getc")
|
||||
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_UNP = self.get_var("unp")
|
||||
V_SPW = self.get_var("spw")
|
||||
V_RAW = self.get_var("raw")
|
||||
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")
|
||||
V_LST = self.get_var("lst")
|
||||
|
||||
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
|
||||
vm_lua = f"""local {V_BIT}=bit32
|
||||
local {V_ENV}=setmetatable({{}},{{__index=getfenv()}})
|
||||
local {V_UNP}=unpack or table.unpack
|
||||
local {V_SPW}=task and task.spawn or spawn
|
||||
local {V_B64}='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
local {V_D}=function(data)
|
||||
local {V_DEC}=function(data)
|
||||
data=data:gsub('[^'..{V_B64}..'=]','')
|
||||
return(data:gsub('.',function(x)
|
||||
if(x=='=')then return''end
|
||||
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)
|
||||
local r=0
|
||||
for i=1,8 do r=r+(x:sub(i,i)=='1'and 2^(8-i)or 0)end
|
||||
return string.char(r)
|
||||
end))
|
||||
local res,bits={{}},''
|
||||
for i=1,#data do
|
||||
local c=data:sub(i,i)
|
||||
if c=='=' then break end
|
||||
local f={V_B64}:find(c)-1
|
||||
for j=5,0,-1 do bits=bits..({V_BIT}.extract(f,j,1)) end
|
||||
end
|
||||
for i=1,#bits-7,8 do
|
||||
local b=0
|
||||
for j=1,8 do b=b+(bits:sub(i+j-1,i+j-1)=='1' and 2^(8-j) or 0) end
|
||||
res[#res+1]=string.char(b)
|
||||
end
|
||||
return table.concat(res)
|
||||
end
|
||||
local {V_INST}={V_D}('{inst_b64}')
|
||||
local {V_INST}={V_DEC}('{inst_b64}')
|
||||
local {V_CONSTS}=game:GetService("HttpService"):JSONDecode([=[{consts_json}]=])
|
||||
local {V_SALT}={self.to_expr(salt, V_BIT)}
|
||||
local function {V_EXEC}()
|
||||
@ -152,19 +155,20 @@ local function {V_EXEC}()
|
||||
local {V_CURR}={self.to_expr(start_idx, V_BIT)}
|
||||
local {V_RUN}=true
|
||||
local function {V_GETC}(idx)
|
||||
if not idx then return nil end
|
||||
local c={V_CONSTS}[idx+1]
|
||||
if not c then return nil end
|
||||
if c.t=={self.to_expr(1, V_BIT)} then
|
||||
local raw={V_D}(c.v)
|
||||
local {V_RAW}={V_DEC}(c.v)
|
||||
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
|
||||
local k=({V_KEY}+i+{V_LAST}-1)%256
|
||||
local b=string.byte(raw,i)
|
||||
local char_code={V_BIT}.bxor(b,k)
|
||||
{V_RES}[i]=string.char(char_code)
|
||||
{V_LAST}=char_code
|
||||
local {V_LST}={V_KEY}%256
|
||||
for i=1,#{V_RAW} do
|
||||
local k=({V_KEY}+i+{V_LST}-1)%256
|
||||
local b=string.byte({V_RAW},i)
|
||||
local char={V_BIT}.bxor(b,k)
|
||||
{V_RES}[i]=string.char(char)
|
||||
{V_LST}=char
|
||||
end
|
||||
return table.concat({V_RES})
|
||||
end
|
||||
@ -172,36 +176,40 @@ local function {V_EXEC}()
|
||||
end
|
||||
while {V_RUN} do
|
||||
local {V_PTR}={V_CURR}*7+1
|
||||
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)
|
||||
{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, V_BIT)})-{self.to_expr(self.k1, V_BIT)})-{self.to_expr(self.k3, V_BIT)}
|
||||
local op_l=string.byte({V_INST},{V_PTR}) or 0
|
||||
local op_h=string.byte({V_INST},{V_PTR}+1) or 0
|
||||
local {V_A}=string.byte({V_INST},{V_PTR}+2) or 0
|
||||
local {V_B}=string.byte({V_INST},{V_PTR}+3) or 0
|
||||
local {V_C}=string.byte({V_INST},{V_PTR}+4) or 0
|
||||
local n_l=string.byte({V_INST},{V_PTR}+5) or 0
|
||||
local n_h=string.byte({V_INST},{V_PTR}+6) or 0
|
||||
{V_CURR}=n_l+({V_BIT}.lshift(n_h,8))
|
||||
local op_raw=op_l+({V_BIT}.lshift(op_h,8))
|
||||
local {V_OP}={V_BIT}.bxor(op_raw,{self.to_expr(self.k2, V_BIT)})-{self.to_expr(self.k1, 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
|
||||
{V_REGS}[{V_A}]={V_GETC}({V_B})
|
||||
elseif {V_OP}=={self.opcodes.index('GETGLOBAL')} then
|
||||
{V_REGS}[{V_A}]={V_LUA_ENV}[{V_GETC}({V_B})]
|
||||
local n={V_GETC}({V_B})
|
||||
if n then {V_REGS}[{V_A}]={V_ENV}[n] end
|
||||
elseif {V_OP}=={self.opcodes.index('SETGLOBAL')} then
|
||||
{V_LUA_ENV}[{V_GETC}({V_B})]={V_REGS}[{V_A}]
|
||||
local n={V_GETC}({V_B})
|
||||
if n then {V_ENV}[n]={V_REGS}[{V_A}] end
|
||||
elseif {V_OP}=={self.opcodes.index('CALL')} then
|
||||
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({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
|
||||
if f then
|
||||
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({V_UNP}(args))}}
|
||||
if {V_C}>1 then for i=1,{V_C}-1 do {V_REGS}[{V_A}+i-1]=res[i] end end
|
||||
end
|
||||
elseif {V_OP}=={self.opcodes.index('RETURN')} then
|
||||
{V_RUN}=false
|
||||
end
|
||||
end
|
||||
end
|
||||
{V_SPAWN}({V_EXEC})"""
|
||||
{V_SPW}({V_EXEC})"""
|
||||
return self.minify(vm_lua)
|
||||
|
||||
def compile_to_bytecode(self, ast):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user