-
Notifications
You must be signed in to change notification settings - Fork 4
/
module.lua
418 lines (381 loc) · 31.7 KB
/
module.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
--[==[
Simple Lua Bytecode Obfuscator
This code is licensed under the MIT License.
Copyright (c) 2023 Reboy / M0dder
Made by Reboy / M0dder (Discord: kskreboy#4721)
Obfuscator Supported Versions:
Only Lua 5.1
Supported Lua Versions:
Lua 5.1+ / RBXLua (no loadstring)
Features / How does it work:
1. Convert to bytecode
2. Encode bytecode to plain text
3. Encrypt encoded code with random password
* Minified code
* Customizable variable name, variable comment, comment
* Executable in Lua 5.1+ / RBXLua (no loadstring)
+ new cli
How to use / Example Usage:
CLI Usage:
Command (only --help for help):
lua path/to/module.lua -s "<FILE_PATH>" -o "<NEWFILE_PATH>" [..]
Example CLI:
lua path/to/module.lua -s "C:\\mycode.lua" -o "result.lua" -c "this code is obfuscated!"
Lua Code:
local module = require(path.to.module) -- this module, use require or dofile
module(contents: string (source code), option table: { -- optional
comment = "// comment", -- ex result: "--'comment'"
variablecomment = "lol you have to stop trying to deobfuscate",
cryptvarcomment = true, -- encrypt variablecomment with bytecode ex: "a" -> "\97"
variablename = "CRYPTED", -- ex: "local 'variablename' = 'variablecomment'"
}): string (obfuscated source code)
Common Issue:
lua has memory limit, so what do i do: Use luvi or srlua to convert obfuscator to binary application, limit will be up to 2gb.
Example Lua Code:
-- Obfuscate input.lua and write obfuscated code to result.lua
local codefile, cerr = io.open("input.lua",'rb')
local code
if codefile then
code = codefile:read("*a")
codefile:close()
else
error(cerr)
end
local obfuscated = module(code)
local resfile, rerr = io.open("result.lua",'w')
if resfile then
resfile:write(obfuscated)
resfile:close()
else
print(rerr)
end
Credits:
- FiOne LBI (created by same author as Rerubi) - https://github.com/Rerumu/FiOne
- ARCFOUR implementation in pure Lua - Rob Kendrick (rjek)
--]==]
local obversion = "v1.3.1"
if game ~= nil and typeof ~= nil then
print(
"This Obfuscator cannot be ran in Roblox. (but results can be ran in Roblox)"
)
return
end
-- check is this cli mode
local climode = arg ~= nil and true or false
if table.find == nil then
table.find = function(tbl,value,pos)
for i = pos or 1,#tbl do
if tbl[i] == value then
return i
end
end
end
end
local realargs = nil do
if climode == true then
if #arg <= 1 and arg[1] == "--help" or arg[1] == "-h" or arg[1] == nil then
print(
"ByteLuaObfuscator " .. obversion .. "\n" ..
"Copyright (c) 2023 Reboy / M0dder" .. "\n"
)
print(
"Usage:" .. "\n" ..
arg[0] .. " --source \"<FILE_PATH>\" --output \"<FILE_PATH>\" [OPTIONS]\n" ..
"\n" ..
"Available Arguments:" .. "\n" ..
"--help -h Shows help.\n" ..
"-S --silent Run Obfuscation without outputting to terminal anything." ..
"-s --source \"<FILE_PATH>\" Path to Lua script to obfuscate." .. "\n" ..
"-o --output \"<FILE_PATH>\" Path to Lua script to output (document will be created if there isn't)." .. "\n" ..
"Output file will be overwritten if it exists.\n" ..
"-c --comment \"<COMMENT>\" Comment Option." .. "\n" ..
"-vc --varcomm \"<COMMENT>\" Comment Option for lua variable value." .. "\n" ..
"-vn --varname \"<STRING>\" Lua variable name (Special characters, spaces will be replaced with underline)." .. "\n" ..
"-C --cryptvarcomm Encode (Decodable) comment for vartiable value." .. "\n" ..
"-f --force Ignores all warnings.\n" ..
"-of --openfile Open an obfuscated file after obfuscation. (Windows: notepad, Unix: '$EDITOR')\n" ..
"" .. "\n"
)
return
end
realargs = {}
local nextvargs = {"source","output","comment","varcomm","varname"}
local longargs = {s="source",o="output",c="comment",vc="varcomm",vn="varname",C="cryptvarcomm",f="force",S="silent",of="openfile"}
local skipdexes = {}
for i,v in pairs(arg) do
if (not table.find(skipdexes,i)) or (i > 0) then
if v:sub(1,2) == "--" then
if table.find(nextvargs,v:sub(3)) then
realargs[v:sub(3)] = arg[i+1]
table.insert(skipdexes,(#skipdexes+1),(i+1))
else
realargs[v:sub(3)] = true
end
elseif v:sub(1,1) == "-" then
if table.find(nextvargs,longargs[v:sub(2)]) then
realargs[longargs[v:sub(2)]] = arg[i+1]
table.insert(skipdexes,(#skipdexes+1),(i+1))
else
realargs[longargs[v:sub(2)]] = true
end
end
end
end
end
end
local M = {}
local charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'--64
local morecharset = charset..'!@#$%&*()-=[];\'",./_+{}:|<>?'
local fenv = getfenv or function()
return _ENV
end
--local loadstring_ = loadstring
local resources = { -- FAKE Yueliang
Yueliang = function(src,NAME)return string.dump(assert(loadstring(src,NAME)))end,
-- FiOne
FiOneCode = [==[(function()if not bit then local bit_=nil pcall(function()bit_=require('bit') end)bit=bit_ end local bit=bit or bit32 or(function()local a={_TYPE='module',_NAME='bit.numberlua',_VERSION='0.3.1.20120131'}local b=math.floor;local c=2^32;local d=c-1;local function e(f)local g={}local h=setmetatable({},g)function g:__index(i)local j=f(i)h[i]=j;return j end;return h end;local function k(h,l)local function m(n,o)local p,q=0,1;while n~=0 and o~=0 do local r,s=n%l,o%l;p=p+h[r][s]*q;n=(n-r)/l;o=(o-s)/l;q=q*l end;p=p+(n+o)*q;return p end;return m end;local function t(h)local u=k(h,2^1)local v=e(function(n)return e(function(o)return u(n,o)end)end)return k(v,2^(h.n or 1))end;function a.tobit(w)return w%2^32 end;a.bxor=t{[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0},n=4}local x=a.bxor;function a.bnot(n)return d-n end;local y=a.bnot;function a.band(n,o)return(n+o-x(n,o))/2 end;local z=a.band;function a.bor(n,o)return d-z(d-n,d-o)end;local A=a.bor;local B,C;function a.rshift(n,D)if D<0 then return B(n,-D)end;return b(n%2^32/2^D)end;C=a.rshift;function a.lshift(n,D)if D<0 then return C(n,-D)end;return n*2^D%2^32 end;B=a.lshift;function a.tohex(w,E)E=E or 8;local F;if E<=0 then if E==0 then return''end;F=true;E=-E end;w=z(w,16^E-1)return('%0'..E..(F and'X'or'x')):format(w)end;local G=a.tohex;function a.extract(E,H,I)I=I or 1;return z(C(E,H),2^I-1)end;local J=a.extract;function a.replace(E,j,H,I)I=I or 1;local K=2^I-1;j=z(j,K)local L=y(B(K,H))return z(E,L)+B(j,H)end;local M=a.replace;function a.bswap(w)local n=z(w,0xff)w=C(w,8)local o=z(w,0xff)w=C(w,8)local N=z(w,0xff)w=C(w,8)local O=z(w,0xff)return B(B(B(n,8)+o,8)+N,8)+O end;local P=a.bswap;function a.rrotate(w,D)D=D%32;local Q=z(w,2^D-1)return C(w,D)+B(Q,32-D)end;local R=a.rrotate;function a.lrotate(w,D)return R(w,-D)end;local S=a.lrotate;a.rol=a.lrotate;a.ror=a.rrotate;function a.arshift(w,D)local T=C(w,D)if w>=0x80000000 then T=T+B(2^D-1,32-D)end;return T end;local U=a.arshift;function a.btest(w,V)return z(w,V)~=0 end;a.bit32={}local function W(w)return(-1-w)%c end;a.bit32.bnot=W;local function X(n,o,N,...)local T;if o then n=n%c;o=o%c;T=x(n,o)if N then T=X(T,N,...)end;return T elseif n then return n%c else return 0 end end;a.bit32.bxor=X;local function Y(n,o,N,...)local T;if o then n=n%c;o=o%c;T=(n+o-x(n,o))/2;if N then T=Y(T,N,...)end;return T elseif n then return n%c else return d end end;a.bit32.band=Y;local function Z(n,o,N,...)local T;if o then n=n%c;o=o%c;T=d-z(d-n,d-o)if N then T=Z(T,N,...)end;return T elseif n then return n%c else return 0 end end;a.bit32.bor=Z;function a.bit32.btest(...)return Y(...)~=0 end;function a.bit32.lrotate(w,D)return S(w%c,D)end;function a.bit32.rrotate(w,D)return R(w%c,D)end;function a.bit32.lshift(w,D)if D>31 or D<-31 then return 0 end;return B(w%c,D)end;function a.bit32.rshift(w,D)if D>31 or D<-31 then return 0 end;return C(w%c,D)end;function a.bit32.arshift(w,D)w=w%c;if D>=0 then if D>31 then return w>=0x80000000 and d or 0 else local T=C(w,D)if w>=0x80000000 then T=T+B(2^D-1,32-D)end;return T end else return B(w,-D)end end;function a.bit32.extract(w,H,...)local I=...or 1;if H<0 or H>31 or I<0 or H+I>32 then error'out of range'end;w=w%c;return J(w,H,...)end;function a.bit32.replace(w,j,H,...)local I=...or 1;if H<0 or H>31 or I<0 or H+I>32 then error'out of range'end;w=w%c;j=j%c;return M(w,j,H,...)end;a.bit={}function a.bit.tobit(w)w=w%c;if w>=0x80000000 then w=w-c end;return w end;local _=a.bit.tobit;function a.bit.tohex(w,...)return G(w%c,...)end;function a.bit.bnot(w)return _(y(w%c))end;local function a0(n,o,N,...)if N then return a0(a0(n,o),N,...)elseif o then return _(A(n%c,o%c))else return _(n)end end;a.bit.bor=a0;local function a1(n,o,N,...)if N then return a1(a1(n,o),N,...)elseif o then return _(z(n%c,o%c))else return _(n)end end;a.bit.band=a1;local function a2(n,o,N,...)if N then return a2(a2(n,o),N,...)elseif o then return _(x(n%c,o%c))else return _(n)end end;a.bit.bxor=a2;function a.bit.lshift(w,E)return _(B(w%c,E%32))end;function a.bit.rshift(w,E)return _(C(w%c,E%32))end;function a.bit.arshift(w,E)return _(U(w%c,E%32))end;function a.bit.rol(w,E)return _(S(w%c,E%32))end;function a.bit.ror(w,E)return _(R(w%c,E%32))end;function a.bit.bswap(w)return _(P(w%c))end;return a end)()local unpack=table.unpack or unpack;local a3;local a4;local a5;local a6=50;local a7={[22]=18,[31]=8,[33]=28,[0]=3,[1]=13,[2]=23,[26]=33,[12]=1,[13]=6,[14]=10,[15]=16,[16]=20,[17]=26,[18]=30,[19]=36,[3]=0,[4]=2,[5]=4,[6]=7,[7]=9,[8]=12,[9]=14,[10]=17,[20]=19,[21]=22,[23]=24,[24]=27,[25]=29,[27]=32,[32]=34,[34]=37,[11]=5,[28]=11,[29]=15,[30]=21,[35]=25,[36]=31,[37]=35}local a8={[0]='ABC','ABx','ABC','ABC','ABC','ABx','ABC','ABx','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','AsBx','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','AsBx','AsBx','ABC','ABC','ABC','ABx','ABC'}local a9={[0]={b='OpArgR',c='OpArgN'},{b='OpArgK',c='OpArgN'},{b='OpArgU',c='OpArgU'},{b='OpArgR',c='OpArgN'},{b='OpArgU',c='OpArgN'},{b='OpArgK',c='OpArgN'},{b='OpArgR',c='OpArgK'},{b='OpArgK',c='OpArgN'},{b='OpArgU',c='OpArgN'},{b='OpArgK',c='OpArgK'},{b='OpArgU',c='OpArgU'},{b='OpArgR',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgR',c='OpArgN'},{b='OpArgR',c='OpArgN'},{b='OpArgR',c='OpArgN'},{b='OpArgR',c='OpArgR'},{b='OpArgR',c='OpArgN'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgK',c='OpArgK'},{b='OpArgR',c='OpArgU'},{b='OpArgR',c='OpArgU'},{b='OpArgU',c='OpArgU'},{b='OpArgU',c='OpArgU'},{b='OpArgU',c='OpArgN'},{b='OpArgR',c='OpArgN'},{b='OpArgR',c='OpArgN'},{b='OpArgN',c='OpArgU'},{b='OpArgU',c='OpArgU'},{b='OpArgN',c='OpArgN'},{b='OpArgU',c='OpArgN'},{b='OpArgU',c='OpArgN'}}local function aa(ab,s,e,d)local ac=0;for i=s,e,d do ac=ac+string.byte(ab,i,i)*256^(i-s)end;return ac end;local function ad(ae,af,ag,ah)local ai=(-1)^bit.rshift(ah,7)local aj=bit.rshift(ag,7)+bit.lshift(bit.band(ah,0x7F),1)local ak=ae+bit.lshift(af,8)+bit.lshift(bit.band(ag,0x7F),16)local al=1;if aj==0 then if ak==0 then return ai*0 else al=0;aj=1 end elseif aj==0x7F then if ak==0 then return ai*1/0 else return ai*0/0 end end;return ai*2^(aj-127)*(1+al/2^23)end;local function am(ae,af,ag,ah,an,ao,ap,aq)local ai=(-1)^bit.rshift(aq,7)local aj=bit.lshift(bit.band(aq,0x7F),4)+bit.rshift(ap,4)local ak=bit.band(ap,0x0F)*2^48;local al=1;ak=ak+ao*2^40+an*2^32+ah*2^24+ag*2^16+af*2^8+ae;if aj==0 then if ak==0 then return ai*0 else al=0;aj=1 end elseif aj==0x7FF then if ak==0 then return ai*1/0 else return ai*0/0 end end;return ai*2^(aj-1023)*(al+ak/2^52)end;local function ar(ab,s,e)return aa(ab,s,e-1,1)end;local function as(ab,s,e)return aa(ab,e-1,s,-1)end;local function at(ab,s)return ad(string.byte(ab,s,s+3))end;local function au(ab,s)local ae,af,ag,ah=string.byte(ab,s,s+3)return ad(ah,ag,af,ae)end;local function av(ab,s)return am(string.byte(ab,s,s+7))end;local function aw(ab,s)local ae,af,ag,ah,an,ao,ap,aq=string.byte(ab,s,s+7)return am(aq,ap,ao,an,ah,ag,af,ae)end;local ax={[4]={little=at,big=au},[8]={little=av,big=aw}}local function ay(S)local az=S.index;local aA=string.byte(S.source,az,az)S.index=az+1;return aA end;local function aB(S,aC)local aD=S.index+aC;local aE=string.sub(S.source,S.index,aD-1)S.index=aD;return aE end;local function aF(S)local aC=S:s_szt()local aE;if aC~=0 then aE=string.sub(aB(S,aC),1,-2)end;return aE end;local function aG(aC,aH)return function(S)local aD=S.index+aC;local aI=aH(S.source,S.index,aD)S.index=aD;return aI end end;local function aJ(aC,aH)return function(S)local aK=aH(S.source,S.index)S.index=S.index+aC;return aK end end;local function aL(S)local aM=S:s_int()local aN={}for i=1,aM do local aO=S:s_ins()local aP=bit.band(aO,0x3F)local aQ=a8[aP]local aR=a9[aP]local aS={value=aO,op=a7[aP],A=bit.band(bit.rshift(aO,6),0xFF)}if aQ=='ABC'then aS.B=bit.band(bit.rshift(aO,23),0x1FF)aS.C=bit.band(bit.rshift(aO,14),0x1FF)aS.is_KB=aR.b=='OpArgK'and aS.B>0xFF;aS.is_KC=aR.c=='OpArgK'and aS.C>0xFF elseif aQ=='ABx'then aS.Bx=bit.band(bit.rshift(aO,14),0x3FFFF)aS.is_K=aR.b=='OpArgK'elseif aQ=='AsBx'then aS.sBx=bit.band(bit.rshift(aO,14),0x3FFFF)-131071 end;aN[i]=aS end;return aN end;local function aT(S)local aM=S:s_int()local aU={}for i=1,aM do local aV=ay(S)local k;if aV==1 then k=ay(S)~=0 elseif aV==3 then k=S:s_num()elseif aV==4 then k=aF(S)end;aU[i]=k end;return aU end;local function aW(S,ab)local aM=S:s_int()local aX={}for i=1,aM do aX[i]=a5(S,ab)end;return aX end;local function aY(S)local aM=S:s_int()local aZ={}for i=1,aM do aZ[i]=S:s_int()end;return aZ end;local function a_(S)local aM=S:s_int()local b0={}for i=1,aM do b0[i]={varname=aF(S),startpc=S:s_int(),endpc=S:s_int()}end;return b0 end;local function b1(S)local aM=S:s_int()local b2={}for i=1,aM do b2[i]=aF(S)end;return b2 end;function a5(S,b3)local b4={}local ab=aF(S)or b3;b4.source=ab;S:s_int()S:s_int()b4.numupvals=ay(S)b4.numparams=ay(S)ay(S)ay(S)b4.code=aL(S)b4.const=aT(S)b4.subs=aW(S,ab)b4.lines=aY(S)a_(S)b1(S)for _,v in ipairs(b4.code)do if v.is_K then v.const=b4.const[v.Bx+1]else if v.is_KB then v.const_B=b4.const[v.B-0xFF]end;if v.is_KC then v.const_C=b4.const[v.C-0xFF]end end end;return b4 end;function a3(ab)local b5;local b6;local b7;local b8;local b9;local ba;local bb;local bc={index=1,source=ab}assert(aB(bc,4)=='\27Lua','invalid Lua signature')assert(ay(bc)==0x51,'invalid Lua version')assert(ay(bc)==0,'invalid Lua format')b6=ay(bc)~=0;b7=ay(bc)b8=ay(bc)b9=ay(bc)ba=ay(bc)bb=ay(bc)~=0;b5=b6 and ar or as;bc.s_int=aG(b7,b5)bc.s_szt=aG(b8,b5)bc.s_ins=aG(b9,b5)if bb then bc.s_num=aG(ba,b5)elseif ax[ba]then bc.s_num=aJ(ba,ax[ba][b6 and'little'or'big'])else error('unsupported float size')end;return a5(bc,'@virtual')end;local function bd(be,bf)for i,bg in pairs(be)do if bg.index>=bf then bg.value=bg.store[bg.index]bg.store=bg;bg.index='value'be[i]=nil end end end;local function bh(be,bf,bi)local bj=be[bf]if not bj then bj={index=bf,store=bi}be[bf]=bj end;return bj end;local function bk(...)return select('#',...),{...}end;local function bl(bm,bn)local ab=bm.source;local bo=bm.lines[bm.pc-1]local b3,bp,bq=string.match(bn,'^(.-):(%d+):%s+(.+)')local br='%s:%i: [%s:%i] %s'bo=bo or'0'b3=b3 or'?'bp=bp or'0'bq=bq or bn;error(string.format(br,ab,bo,b3,bp,bq),0)end;local function bs(bm)local aN=bm.code;local bt=bm.subs;local bu=bm.env;local bv=bm.upvals;local bw=bm.varargs;local bx=-1;local by={}local bi=bm.stack;local bz=bm.pc;while true do local bA=aN[bz]local aP=bA.op;bz=bz+1;if aP<18 then if aP<8 then if aP<3 then if aP<1 then for i=bA.A,bA.B do bi[i]=nil end elseif aP>1 then local bg=bv[bA.B]bi[bA.A]=bg.store[bg.index]else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB+bC end elseif aP>3 then if aP<6 then if aP>4 then local A=bA.A;local B=bA.B;local bf;if bA.is_KC then bf=bA.const_C else bf=bi[bA.C]end;bi[A+1]=bi[B]bi[A]=bi[B][bf]else bi[bA.A]=bu[bA.const]end elseif aP>6 then local bf;if bA.is_KC then bf=bA.const_C else bf=bi[bA.C]end;bi[bA.A]=bi[bA.B][bf]else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB-bC end else bi[bA.A]=bi[bA.B]end elseif aP>8 then if aP<13 then if aP<10 then bu[bA.const]=bi[bA.A]elseif aP>10 then if aP<12 then local A=bA.A;local B=bA.B;local C=bA.C;local bD;local bE,bF;if B==0 then bD=bx-A else bD=B-1 end;bE,bF=bk(bi[A](unpack(bi,A+1,A+bD)))if C==0 then bx=A+bE-1 else bE=C-1 end;for i=1,bE do bi[A+i-1]=bF[i]end else local bg=bv[bA.B]bg.store[bg.index]=bi[bA.A]end else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB*bC end elseif aP>13 then if aP<16 then if aP>14 then local A=bA.A;local B=bA.B;local bD;if B==0 then bD=bx-A else bD=B-1 end;bd(by,0)return bk(bi[A](unpack(bi,A+1,A+bD)))else local bf,bG;if bA.is_KB then bf=bA.const_B else bf=bi[bA.B]end;if bA.is_KC then bG=bA.const_C else bG=bi[bA.C]end;bi[bA.A][bf]=bG end elseif aP>16 then bi[bA.A]={}else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB/bC end else bi[bA.A]=bA.const end else local A=bA.A;local bH=bi[A+2]local bf=bi[A]+bH;local bI=bi[A+1]local bJ;if bH==math.abs(bH)then bJ=bf<=bI else bJ=bf>=bI end;if bJ then bi[bA.A]=bf;bi[bA.A+3]=bf;bz=bz+bA.sBx end end elseif aP>18 then if aP<28 then if aP<23 then if aP<20 then bi[bA.A]=#bi[bA.B]elseif aP>20 then if aP<22 then local A=bA.A;local B=bA.B;local bK={}local aM;if B==0 then aM=bx-A+1 else aM=B-1 end;for i=1,aM do bK[i]=bi[A+i-1]end;bd(by,0)return aM,bK else local aE=bi[bA.B]for i=bA.B+1,bA.C do aE=aE..bi[i]end;bi[bA.A]=aE end else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB%bC end elseif aP>23 then if aP<26 then if aP>24 then bd(by,bA.A)else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;if bB==bC==(bA.A~=0)then bz=bz+aN[bz].sBx end;bz=bz+1 end elseif aP>26 then local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;if bB<bC==(bA.A~=0)then bz=bz+aN[bz].sBx end;bz=bz+1 else local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;bi[bA.A]=bB^bC end else bi[bA.A]=bA.B~=0;if bA.C~=0 then bz=bz+1 end end elseif aP>28 then if aP<33 then if aP<30 then local bB,bC;if bA.is_KB then bB=bA.const_B else bB=bi[bA.B]end;if bA.is_KC then bC=bA.const_C else bC=bi[bA.C]end;if bB<=bC==(bA.A~=0)then bz=bz+aN[bz].sBx end;bz=bz+1 elseif aP>30 then if aP<32 then local aX=bt[bA.Bx+1]local bL=aX.numupvals;local bM;if bL~=0 then bM={}for i=1,bL do local bN=aN[bz+i-1]if bN.op==a7[0]then bM[i-1]=bh(by,bN.B,bi)elseif bN.op==a7[4]then bM[i-1]=bv[bN.B]end end;bz=bz+bL end;bi[bA.A]=a4(aX,bu,bM)else local A=bA.A;local B=bA.B;if not bi[B]==(bA.C~=0)then bz=bz+1 else bi[A]=bi[B]end end else bi[bA.A]=-bi[bA.B]end elseif aP>33 then if aP<36 then if aP>34 then local A=bA.A;local aM=bA.B;if aM==0 then aM=bw.size;bx=A+aM-1 end;for i=1,aM do bi[A+i-1]=bw.list[i]end else local A=bA.A;local bO,bI,bH;bO=assert(tonumber(bi[A]),'`for` initial value must be a number')bI=assert(tonumber(bi[A+1]),'`for` limit must be a number')bH=assert(tonumber(bi[A+2]),'`for` step must be a number')bi[A]=bO-bH;bi[A+1]=bI;bi[A+2]=bH;bz=bz+bA.sBx end elseif aP>36 then local A=bA.A;local C=bA.C;local aM=bA.B;local bP=bi[A]local bQ;if aM==0 then aM=bx-A end;if C==0 then C=bA[bz].value;bz=bz+1 end;bQ=(C-1)*a6;for i=1,aM do bP[i+bQ]=bi[A+i]end else bi[bA.A]=not bi[bA.B]end else if not bi[bA.A]==(bA.C~=0)then bz=bz+1 end end else local A=bA.A;local aH=bi[A]local bR=bi[A+1]local bf=bi[A+2]local bS=A+3;local bK;bi[bS+2]=bf;bi[bS+1]=bR;bi[bS]=aH;bK={aH(bR,bf)}for i=1,bA.C do bi[bS+i-1]=bK[i]end;if bi[bS]~=nil then bi[A+2]=bi[bS]else bz=bz+1 end end else bz=bz+bA.sBx end;bm.pc=bz end end;function a4(bR,bu,b2)local bT=bR.code;local bU=bR.subs;local bV=bR.lines;local bW=bR.source;local bX=bR.numparams;local function bY(...)local bi={}local bZ={}local b_=0;local c0,c1=bk(...)local bm;local c2,bn,bK;for i=1,bX do bi[i-1]=c1[i]end;if bX<c0 then b_=c0-bX;for i=1,b_ do bZ[i]=c1[bX+i]end end;bm={varargs={list=bZ,size=b_},code=bT,subs=bU,lines=bV,source=bW,env=bu,upvals=b2,stack=bi,pc=1}c2,bn,bK=pcall(bs,bm,...)if c2 then return unpack(bK,1,bn)else bl(bm,bn)end;return end;return bY end;return function(c3,bu)return a4(a3(c3),bu or fev(0))end end)()]==],
AES = nil,
AESCode = [==[(function()local function a(b)local c={}for d=0,255 do c[d]={}end;c[0][0]=b[1]*255;local e=1;for f=0,7 do for d=0,e-1 do for g=0,e-1 do local h=c[d][g]-b[1]*e;c[d][g+e]=h+b[2]*e;c[d+e][g]=h+b[3]*e;c[d+e][g+e]=h+b[4]*e end end;e=e*2 end;return c end;local i=a{0,1,1,0}local function j(self,k)local l,d,g=self.S,self.i,self.j;local m={}local n=string.char;for o=1,k do d=(d+1)%256;g=(g+l[d])%256;l[d],l[g]=l[g],l[d]m[o]=n(l[(l[d]+l[g])%256])end;self.i,self.j=d,g;return table.concat(m)end;local function p(self,q)local r=j(self,#q)local s={}local t=string.byte;local n=string.char;for d=1,#q do s[d]=n(i[t(q,d)][t(r,d)])end;return table.concat(s)end;local function u(self,v)local l=self.S;local g,w=0,#v;local t=string.byte;for d=0,255 do g=(g+l[d]+t(v,d%w+1))%256;l[d],l[g]=l[g],l[d]end end;function new(v)local l={}local s={S=l,i=0,j=0,generate=j,cipher=p,schedule=u}for d=0,255 do l[d]=d end;if v then s:schedule(v)end;return s end;return new end)()]==],
Base64 = {
Encode = function(a)local b=charset;return(a:gsub('.',function(c)local d,b='',c:byte()for e=8,1,-1 do d=d..(b%2^e-b%2^(e-1)>0 and'1'or'0')end;return d end)..'0000'):gsub('%d%d%d?%d?%d?%d?',function(c)if#c<6 then return''end;local f=0;for e=1,6 do f=f+(c:sub(e,e)=='1'and 2^(6-e)or 0)end;return b:sub(f+1,f+1)end)..({'','==','='})[#a%3+1]end,
Decode = function(a)local b=charset;a=string.gsub(a,'[^'..b..'=]','')return a:gsub('.',function(c)if c=='='then return''end;local d,e='',b:find(c)-1;for f=6,1,-1 do d=d..(e%2^f-e%2^(f-1)>0 and'1'or'0')end;return d end):gsub('%d%d%d?%d?%d?%d?%d?%d?',function(c)if#c~=8 then return''end;local g=0;for f=1,8 do g=g+(c:sub(f,f)=='1'and 2^(8-f)or 0)end;return string.char(g)end)end
},
Base64Code = {
Encode = [==[function(a)local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';return(a:gsub('.',function(c)local d,b='',c:byte()for e=8,1,-1 do d=d..(b%2^e-b%2^(e-1)>0 and'1'or'0')end;return d end)..'0000'):gsub('%d%d%d?%d?%d?%d?',function(c)if#c<6 then return''end;local f=0;for e=1,6 do f=f+(c:sub(e,e)=='1'and 2^(6-e)or 0)end;return b:sub(f+1,f+1)end)..({'','==','='})[#a%3+1]end]==],
Decode = [==[function(a)local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';a=string.gsub(a,'[^'..b..'=]','')return a:gsub('.',function(c)if c=='='then return''end;local d,e='',b:find(c)-1;for f=6,1,-1 do d=d..(e%2^f-e%2^(f-1)>0 and'1'or'0')end;return d end):gsub('%d%d%d?%d?%d?%d?%d?%d?',function(c)if#c~=8 then return''end;local g=0;for f=1,8 do g=g+(c:sub(f,f)=='1'and 2^(8-f)or 0)end;return string.char(g)end)end]==]
},
};
--Resources:
-- ~~Compiler: Yueliang(source, scriptname): luac string | Executor: FiOne(luac, env): function~~
-- Base64: Base64.Encode(data): string | Base64.Decode(data): string
-- "FiOneCode" loadstringable string
-- AES: AES(key) - and something
-- AESCode: src of aes
-- Base64Code: src of base64 Encode, Decode
--
function loaddata(name)
return resources[name]
end
local compile = loaddata("Yueliang")
--local execute = loaddata("FiOne")
do
--loadstring = function(contents, chunkname, env) -- wow custom loadstring
-- local bytecode = compile(contents, chunkname or nil)
-- local func = execute(bytecode, env or fenv(2))
-- return func
--end
--resources.FiOne = loadstring("return " .. loaddata("AESCode"))()
resources.AES = loadstring("return " .. loaddata("AESCode"))()
end
local _settings = { -- default options
comment = "// CRYPTED", -- "--'comment'"
variablecomment = "lol you have to stop trying to deobfuscate",
cryptvarcomment = true, -- encrypt variablecomment with bytecode
variablename = "CRYPTED", -- "local 'variablename' = 'variablecomment' or something"
}
local aes = loaddata("AES")
local base64 = loaddata("Base64")
local function aesenc(code, key)
local state = aes(key)
local unable = state:cipher(code)
local able = base64.Encode(unable)
return able
end
local function aesdec(code, key)
local state = aes(key)
local unable = base64.Decode(code)
local result = state:cipher(unable)
return result
end
local function genpass(l)
local pass = ""
for i = 1, l do
local a = math.random(1,#morecharset)
pass = pass .. morecharset:sub(a,a)
end
return pass
end
local h2b = {
['0']='0000', ['1']='0001', ['2']='0010', ['3']='0011',
['4']='0100', ['5']='0101', ['6']='0110', ['7']='0111',
['8']='1000', ['9']='1001', ['A']='1010', ['B']='1011',
['C']='1100', ['D']='1101', ['E']='1110', ['F']='1111'
}
local function d2b(n)
return ('%X'):format(n):upper():gsub(".", h2b)
end
local function genIl(a)
return d2b((a):byte(1,-1)):gsub("0","l"):gsub("1","I")
end
local silentmode = climode and realargs.silent or false
if silentmode == false then
print(
"ByteLuaObfuscator " .. obversion .. "\n" ..
"Copyright (c) 2023 Reboy / M0dder" .. "\n"
)
end
M.crypt = function(source, options)
if silentmode == false and #source >= 2000000 then
print("WARNING: Your script seems too big, the process may be crashed or the code may be corrupted.")
end
options = options or {}
for k,v in pairs(_settings) do
if options[k] == nil then
options[k] = v
end
end
options.variablename = options.variablename:gsub('[%p%c%s]', '_')
options.variablename = options.variablename:sub(1,1):gsub('[%d]','v'..options.variablename:sub(1,1)) .. options.variablename:sub(2)
local varname = options.variablename
local varcomment = options.cryptvarcomment and "\\"..table.concat({options.variablecomment:byte(1,-1)},"\\") or options.variablecomment
local comment = options.comment
-- f%d_%a -- fake
-- c%d_%a -- real
if not silentmode then print("Obfuscating | Code conversion...")end
local succ, luac = pcall(function()
return compile(source, "gg_y")
end)
if succ == false then
print("Lua Error")
return error(luac)
end
collectgarbage()
if not silentmode then print("Obfuscating | Encrypting...")end
local r_key = "return(function()"
local fv_z = ("local %s%s = \"%s\";"):format(varname, genIl("z"), varcomment)
local f1_a = ("local %s%s"):format(varname, genIl("a"))
local f2_b = ("local %s%s"):format(varname, genIl("b"))
local f3_c = ("local %s%s"):format(varname, genIl("c"))
local c1_d = ("local %s%s"):format(varname, genIl("d"))
local f4_e = ("local %s%s"):format(varname, genIl("e"))
local f5_f = ("local %s%s"):format(varname, genIl("f"))
local f6_g = ("local %s%s"):format(varname, genIl("g"))
local passkey = genpass(math.random(10,20))
local encsrc = aesenc(base64.Encode(luac), passkey)
local key64 = base64.Encode(passkey)
collectgarbage()
if not silentmode then print("Obfuscating | Code Building...")end
local f4 = f4_e .. "=" .. ("'%s'"):format(base64.Encode(genpass(math.random(10,20))))
local f5 = f5_f .. "=" .. ("'%s'"):format(varcomment)
local f6 = f6_g .. "=" .. ("'%s'"):format(base64.Encode(genpass(math.random(10,20))))
local c1 = c1_d .. "=" .. ("'%s'"):format("\\"..table.concat({key64:byte(1,-1)},"\\"))
local fks = {f4,f5,f6,c1}
local i_ = ("%s%s"):format(varname, genIl("i"))
local c2_i_b64 = ("local %s"):format(i_) .. "=" .. loaddata("Base64Code").Decode
local j_ = ("%s%s"):format(varname, genIl("j"))
local c3_j_aes = ("local %s"):format(j_) .. "=" .. loaddata("AESCode")
local k_ = ("%s%s"):format(varname, genIl("k"))
local c4_k_fne = ("local %s"):format(k_) .. "=" .. loaddata("FiOneCode")
local f7_h = [[function ]]..("%s%s"):format(varname, genIl("h"))..[[(a,b)local c=]]..i_..[[(a,b);local d=]]..f4_e:sub(7)..[[;return c,d end]]
local f8_l = ("%s%s"):format(varname, genIl("h"))..("(%s,%d)"):format(f5_f:sub(7),math.random(314,31415))
local m_ = ("%s%s"):format(varname, genIl("m"))
local c4_m = ("local %s"):format(m_) .. "=" .. "function(a,b)" ..--a.64key,b.64src
"local c="..j_.."("..i_.."(a))" ..
"local d=c[\"\\99\\105\\112\\104\\101\\114\"](c,"..i_.."(b))" ..
"return "..i_.."(d)" ..
"end"
local n_ = ("%s%s"):format(varname, genIl("n"))
local bytedsrc = nil
if encsrc:len() > 255 then -- handle lua byte library limit
local chunkedbys = {}
for i=1,#encsrc,255 do
chunkedbys[#chunkedbys+1] = {encsrc:sub(i,i+255 - 1):byte(1,-1)}
end
bytedsrc = {}
for i,v in pairs(chunkedbys) do
for i1,v1 in pairs(v) do
bytedsrc[#bytedsrc+1] = v1
end
end
else
bytedsrc = {encsrc:byte(1,-1)}
end
local c5res = "\\"..table.concat(bytedsrc,"\\")
local c5_n = ("local %s"):format(n_) .. "="..("\"%s\""):format(c5res)
local fenvhandle = "local fev=getfenv or function()return _ENV end"
local f9_o = ("local %s%s"):format(varname, genIl("o")) .. "=" .. ("'%s%s%s'"):format(base64.Encode(genpass(math.random(10,20))),base64.Encode(genpass(math.random(10,20))),base64.Encode(genpass(math.random(10,20))))
local c_end = ("return %s(%s(%s,%s),getfenv(0))()end)()"):format(k_,m_,(c1_d):sub(7),n_)--1.exe,2.c4,3.c4_a,4.c4_b
if not silentmode then print("Obfuscated!")end
return "--" .. comment .. "\n\n" ..
r_key ..
fv_z ..
fv_z ..
fv_z ..
f1_a .. "=" .. ("%d"):format(math.random(111,31415)/100) .. ";" ..
f2_b .. "=" .. ("%d"):format(math.random(111,31415)/100) .. ";" ..
f3_c .. "=" .. ("%d"):format(math.pi) .. ";" ..
c2_i_b64 .. ";" ..
f2_b .. "=" .. ("%d"):format(math.random(111,31415)/100) .. ";" ..
c3_j_aes .. ";" ..
fenvhandle .. ";" ..
c4_k_fne .. ";" ..
fks[math.random(1,#fks)] .. ";" ..
c5_n .. ";" ..
fks[math.random(1,#fks)] .. ";" ..
fks[math.random(1,#fks)] .. ";" ..
c4_m .. ";" ..
fks[math.random(1,#fks)] .. ";" ..
c1 .. ";" ..
fks[math.random(1,#fks)] .. ";" ..
f9_o .. ";" ..
f7_h .. ";" ..
c_end
end
if climode == true then
if silentmode == false and not realargs.force then
local existfile = io.open(realargs.output or "output.lua","r")
if existfile ~= nil then
io.close(existfile)
print("Output file is exist: " .. realargs.output or "output.lua")
io.write("Would you like to overwrite it? (y/N) ")
local answer = io.read()
if answer:lower():sub(1,1) ~= "y" then
print("Cancelled")
return
end
end
end
local rsuccess, readdfile, rerr = pcall(function()
return io.open(realargs.source, "rb")
end)
if rsuccess == false or readdfile == nil then
print("File (source file) Reading Error: " .. (rsuccess == false and readdfile or rerr or "Unknown"))
return
end
if not silentmode then print(("Selected source file to \"%s\"."):format(realargs.source))end
local wsuccess, wdfile, werr = pcall(function()
return io.open(realargs.output or "output.lua", "w")
end)
if wsuccess == false or wdfile == nil then
readdfile:close()
print("File (output file) Writing Error: " .. (wsuccess == false and wdfile or werr or "Unknown"))
return
end
if not silentmode then print(("Selected output file to \"%s\"."):format(realargs.output or "output.lua"))end
local clisettings = {
comment = realargs.comment or _settings.comment, -- --comment "string"
variablecomment = realargs.varcomm or _settings.variablecomment, -- --varcomm "string"
cryptvarcomment = realargs.cryptvarcomm or false, -- --cryptvarcomm
variablename = realargs.varname or _settings.variablename, -- --varname "string"
}
collectgarbage()
local starttime = os.clock()
if not silentmode then print("Starting obfuscation.")end
local kb = M.crypt(readdfile:read("*a"),clisettings) -- you need more memory if you get error at here
if not silentmode then print(("Finished obfuscation in %f seconds."):format(os.clock() - starttime))end
readdfile:close()
wdfile:write(kb)
wdfile:close()
kb = nil
if not silentmode then print(("Obfuscated code are written to \"%s\"."):format(realargs.output or "output.lua"))end
if not silentmode then print("All done.")end
if realargs.openfile then
os.execute((package.config:sub(1,1) == "\\" and "" or (os.getenv("EDITOR") .. " "))..(realargs.output or "output.lua") .. " &")
end
return
end
return setmetatable(M, {
__call = function(self, source, options)
return self.crypt(source, options)
end,
})