Advertisement
vxste

d

Jul 4th, 2024
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.86 KB | None | 0 0
  1. --// init
  2. type userdata = {}
  3. type _function = (...any) -> (...any)
  4.  
  5. local Metatable = {
  6. --[[
  7. A list of metamethod emulators used to call individual
  8. metamethods efficiently.
  9. ]]
  10. metamethods = {
  11. __index = function(self, key)
  12. return self[key]
  13. end,
  14. __newindex = function(self, key, value)
  15. self[key] = value
  16. end,
  17. __call = function(self, ...)
  18. return self(...)
  19. end,
  20. __concat = function(self, b)
  21. return self..b
  22. end,
  23. __add = function(self, b)
  24. return self + b
  25. end,
  26. __sub = function(self, b)
  27. return self - b
  28. end,
  29. __mul = function(self, b)
  30. return self * b
  31. end,
  32. __div = function(self, b)
  33. return self / b
  34. end,
  35. __idiv = function(self, b)
  36. return self // b
  37. end,
  38. __mod = function(self, b)
  39. return self % b
  40. end,
  41. __pow = function(self, b)
  42. return self ^ b
  43. end,
  44. __tostring = function(self)
  45. return tostring(self)
  46. end,
  47. __eq = function(self, b)
  48. return self == b
  49. end,
  50. __lt = function(self, b)
  51. return self < b
  52. end,
  53. __le = function(self, b)
  54. return self <= b
  55. end,
  56. __len = function(self)
  57. return #self
  58. end,
  59. __iter = function(self)
  60. return next, self
  61. end,
  62. __namecall = function(self, ...)
  63. return self:_(...)
  64. end,
  65. __metatable = function(self)
  66. return getmetatable(self)
  67. end,
  68. }
  69. }
  70.  
  71. --// methods
  72.  
  73. --[[
  74. Interceptive hook.
  75.  
  76. Hooks `obj`'s metamethod `metamethod`
  77. ]]
  78. function Metatable.get_L_closure(metamethod: string, obj: {any} | userdata)
  79. local hooked
  80. local metamethod_emulator = Metatable.metamethods[metamethod]
  81.  
  82. xpcall(function()
  83. metamethod_emulator(obj)
  84. end, function()
  85. hooked = debug.info(2, "f")
  86. end)
  87.  
  88. return hooked
  89. end
  90.  
  91. --[[
  92. Interceptive hook.
  93.  
  94. Attempts to scan for all available metamethods
  95. ]]
  96. function Metatable.get_all_L_closures(obj: {any} | userdata)
  97. local metamethods = {}
  98. local innacurate = {}
  99.  
  100. for method, _ in Metatable.metamethods do
  101. local metamethod, accurate = Metatable.get_L_closure(method, obj)
  102. metamethods[method] = metamethod
  103. end
  104.  
  105. return metamethods
  106. end
  107.  
  108. --[[
  109. Non-recursive hook.
  110.  
  111. Calls `f` when a metamethod of `t` gets fired
  112. ]]
  113. function Metatable.metahook(t: any, f: _function)
  114. local metahook = {
  115. __metatable = getmetatable(t) or "The metatable is locked"
  116. }
  117.  
  118. for metamethod, value in Metatable.metamethods do
  119. metahook[metamethod] = function(self, ...)
  120. f()
  121.  
  122. return Metatable.metahook({}, f)
  123. end
  124. end
  125.  
  126. return setmetatable({}, metahook)
  127. end
  128.  
  129. --// Localization
  130.  
  131. local setmetatable = setmetatable
  132. local pcall = pcall
  133. local table = table.clone(table)
  134. local debug = debug
  135. local string = string
  136. local setfenv = setfenv
  137. local getfenv = getfenv
  138.  
  139. local SelectedNum = 2147483647 ^ 2
  140. local SelectedStuff = {}
  141.  
  142. table.rawlength = function(t)
  143. local r = 0
  144. for _, _ in next, t do
  145. r = r + 1
  146. end
  147. return r
  148. end
  149.  
  150. table.concat = function(t, sep)
  151. sep = sep or ''
  152. local result = ''
  153. local count = 1
  154. local length = table.rawlength(t)
  155.  
  156. for _, v in next, t do
  157. result = result .. tostring(v)
  158. if count ~= length then
  159. result = result .. sep
  160. end
  161. count = count + 1
  162. end
  163.  
  164. return result
  165. end
  166.  
  167. local luaGlobals = {
  168. 'assert',
  169. 'collectgarbage',
  170. 'dofile',
  171. 'error',
  172. 'getfenv',
  173. 'getmetatable',
  174. 'ipairs',
  175. 'load',
  176. 'loadfile',
  177. 'next',
  178. 'pairs',
  179. 'pcall',
  180. 'print',
  181. 'rawequal',
  182. 'rawget',
  183. 'rawset',
  184. 'require',
  185. 'select',
  186. 'setfenv',
  187. 'setmetatable',
  188. 'tonumber',
  189. 'tostring',
  190. 'type',
  191. 'unpack',
  192. }
  193.  
  194. local stack = {}
  195.  
  196. --// Init
  197.  
  198. local function get_param_num(f)
  199. return debug.info(f, "a")
  200. end
  201.  
  202. local function merge_t(a, b)
  203. local r = {}
  204.  
  205. for i, v in a do r[i] = v end
  206. for i, v in b do r[i] = v end
  207.  
  208. return r
  209. end
  210.  
  211. local lens = {}
  212. local removed = {}
  213.  
  214. --// Sandbox
  215. local function Sandbox(f: (...any) -> (...any), upvalues: {any}?, constants: {string}?, protos: {(...any) -> (...any)}?, i: number?, params)
  216. upvalues = upvalues or {}
  217. constants = constants or {}
  218. protos = protos or {}
  219. params = params or {}
  220. i = i or 1
  221.  
  222. local root = {
  223. root = true,
  224. children = {},
  225. stack = {},
  226. params = {},
  227. constants = constants,
  228. upvalues = upvalues,
  229. protos = protos,
  230. pc = 0,
  231. function_info = {debug.info(f, "na")},
  232. f = f,
  233. i = i
  234. }
  235.  
  236. local id_i = 0
  237. local last_func
  238.  
  239. local function wrap(parent: {pc: number?, children: {any}, arguments: {any?}?})
  240. local hooks = {}
  241. local t = {}
  242.  
  243. for metamethod in Metatable.metamethods do
  244. local SelectedNum2 = math.random(2 ^ 16, 2 ^ 24)
  245. hooks[metamethod] = function(_, ...)
  246. root.pc += 1
  247.  
  248. local pc = root.pc
  249. local stack = root.stack
  250. local self = {pc = pc, children = {}, parent = parent, arguments = {...}, metamethod = metamethod}
  251.  
  252. SelectedStuff[SelectedNum2] = SelectedNum2 * SelectedNum * pc
  253.  
  254. parent.children[pc] = self
  255.  
  256. if metamethod == "__len" then
  257. return SelectedNum2 * SelectedNum * pc
  258. end
  259.  
  260. return wrap(self)
  261. end
  262. end
  263. hooks.__tostring = function(self)
  264. return tostring(self)
  265. end
  266.  
  267. if root.pc ~= 0 then
  268. root.stack[t] = root.pc
  269. else
  270. root.stack[t] = id_i
  271. root.params[t] = id_i
  272.  
  273. id_i += 1
  274. end
  275.  
  276. return setmetatable(t, hooks)
  277. end
  278.  
  279. local env = wrap(root)
  280.  
  281. local param_num, vararg = get_param_num(f)
  282.  
  283. for i = 1, param_num do
  284. local arg = wrap(root)
  285.  
  286. table.insert(params, arg)
  287. root.params[arg] = root.i
  288.  
  289. root.i += 1
  290. end
  291.  
  292. if vararg then
  293. local vararg = wrap(root)
  294.  
  295. table.insert(params, vararg)
  296. root.params[vararg] = "..."
  297. end
  298.  
  299. local original_env = getfenv(f)
  300. local return_value = {pcall(setfenv(f, env), unpack(params))}
  301. setfenv(f, original_env)
  302.  
  303. root.return_value = table.move(return_value, 2, #return_value, 1, {})
  304. root.success = return_value[1]
  305.  
  306. return root
  307. end
  308. local function Clean(a) -- Remove spaces or illegal charcters from the text
  309. return a:match("%w+")
  310. end
  311.  
  312. function GetFullName(instance)
  313. if instance == game:GetService("Players").LocalPlayer then return 'game:GetService("Players").LocalPlayer' end
  314. local p = instance
  315. local lo = {}
  316. while (p ~= game and p.Parent ~= nil) do
  317. table.insert(lo, p)
  318. p = p.Parent
  319. end
  320. local fullName
  321. if #lo == 0 then
  322. return "nil --[[ PARENTED TO NIL OR DESTROYED ]]"
  323. end
  324. if lo[#lo].ClassName ~= "Workspace" then
  325. fullName = 'game:GetService("' .. lo[#lo].ClassName .. '")'
  326. else
  327. fullName = "workspace"
  328. end
  329. for i = #lo - 1, 1, -1 do
  330. if lo[i] then
  331. fullName = fullName .. ':FindFirstChild("' .. lo[i].Name .. '")'
  332. end
  333. end
  334. return fullName:gsub(":FindFirstChild%(." .. game:GetService("Players").LocalPlayer.Name .. '.%)', '.LocalPlayer')
  335. end
  336.  
  337. local function handle(a) -- Formats a if it's a roblox datatype
  338. local types = {
  339. Color3 = function()
  340. return `Color3.fromRGB({math.floor(a.R*255)}, {math.floor(a.G*255)}, {math.floor(a.B*255)})`
  341. end,
  342. Vector2 = function()
  343. return a == Vector2.one and 'Vector2.one' or a == Vector2.zero and 'Vector2.zero' or `Vector2.new({a.X}, {a.Y})`
  344. end,
  345. Vector3 = function()
  346. return a == Vector3.one and 'Vector3.one' or a == Vector3.zero and 'Vector3.zero' or `Vector3.new({a.X}, {a.Y}, {a.Z})`
  347. end,
  348. UDim = function()
  349. return `UDim.new({a.Scale}, {a.Offset})`
  350. end,
  351. UDim2 = function()
  352. return string.format('UDim2.new({%d, %d}, {%d, %d})', a.X.Scale, a.X.Offset, a.Y.Scale, a.Y.Offset)
  353. end,
  354. EnumItem = function()
  355. return tostring(a)
  356. end,
  357. Enum = function() return tostring(a) end,
  358. Font = function() return `Font.new({a.Family}, {a.Weight}, {a.Style})` end,
  359. CFrame = function() local components = {a:GetComponents()} return string.format("CFrame.new(%s)", table.concat(components, ", ")) end,
  360. BrickColor = function() return `BrickColor.new("{tostring(a)}")` end,
  361. boolean = function() return tostring(a) end,
  362. string = function() return `"{a}"` end,
  363. number = function() return tostring(a) end,
  364. ['nil'] = function() return 'nil' end,
  365. ['buffer'] = function()
  366. local FullString = `buffer.create({buffer.len(a)})`
  367. return FullString
  368. end,
  369. ['Instance'] = function()
  370. return GetFullName(a)
  371. end
  372. }
  373. if types[typeof(a)] then
  374. return types[typeof(a)]()
  375. else
  376. return `{typeof(a)}.new({tostring(a)})`
  377. end
  378. end
  379.  
  380. local libs = {string=string, coroutine=coroutine, buffer=buffer, os=os, task=task, utf8=utf8, math=math, table=table, bit32=bit32, debug=debug}
  381. local quickaccess = {}
  382.  
  383. function equals(tbl, tbl2) -- Shallow equals for tree.return_value
  384. if type(tbl) ~= 'table' or type(tbl2) ~= 'table' then return tbl == tbl2 end
  385. for i, v in next, tbl do
  386. if tbl2[i] ~= v then return false end
  387. end
  388. return true
  389. end
  390.  
  391. --// Disassembler
  392. local function Disassemble(tree: {any}, tabs: number?)
  393. tabs = tabs or 1
  394. local tab_formatting = (" "):rep(tabs)
  395.  
  396. local stack = tree.stack
  397. local params = tree.params
  398. local upvalues = tree.upvalues
  399. local final_pc = tree.pc
  400. local success = tree.success
  401. local function_info = tree.function_info
  402. local i = tree.i
  403.  
  404. local stack_offset do
  405. stack_offset = (final_pc > 0 and 1) or 0
  406. end
  407.  
  408. local disassembly = {}
  409. local constants = {}
  410. local protos = {}
  411.  
  412. local pc = 0
  413.  
  414. local function format(value, tabs)
  415. tabs = tabs or 1
  416. local type = type(value)
  417.  
  418. local s_index = stack[value]
  419. local p_index = params[value]
  420. local uv_index = upvalues[value]
  421.  
  422. if p_index then
  423. if p_index ~= "..." then
  424. return ("_p%d"):format(tonumber(p_index) or 0)
  425. end
  426. return p_index
  427. elseif s_index and tonumber(s_index) then
  428. return ("v%d"):format(tonumber(s_index))
  429. elseif uv_index then
  430. if not upvalues[value] then
  431. disassembly[1] = ("local _uv_%s = v%d[%s]\n"):format(uv_index, uv_index)..(disassembly[1] or "")
  432. else
  433. return ("_p%s"):format(uv_index)
  434. end
  435.  
  436. return ("_uv_%d"):format(uv_index)
  437. elseif not p_index and not s_index and not uv_index and type == 'number' then
  438. return tostring(value)
  439. end
  440.  
  441. if type == "string" then
  442.  
  443. local s = ""
  444.  
  445. for _, char in {value:byte(1, -1)} do
  446. if char > 126 or char < 32 then
  447. s ..= "\\"..char
  448. else
  449. s ..= string.char(char)
  450. end
  451. end
  452.  
  453. table.insert(constants, value)
  454.  
  455. return ('"%s"'):format(s)
  456. elseif type == "table" then
  457. local t = ""
  458. local mt = getmetatable(value)
  459. local count = 0
  460. local total = 0
  461. local a = ' '
  462. local tabf = a:rep(tabs)
  463.  
  464. for _, _ in next, value do
  465. total = total + 1
  466. end
  467.  
  468. for i, v in next, value do
  469. count = count + 1
  470. local betterI = typeof(i) == 'number' and tostring(i) or string.format('"%s"', tostring(i))
  471. local betterV = typeof(v) == 'number' and tostring(v) or format(v)
  472. t ..= ("\n%s[%s] = %s%s"):format(a:rep(tabs + 2) .. ' ', betterI, betterV, count < total and ',' or '')
  473. end
  474.  
  475. t = ("{%s%s%s%s}"):format(tabf, t, count > 0 and '\n' or '', a:rep(tabs + 1))
  476.  
  477. if typeof(mt) == 'table' then
  478. local methods = '{'
  479.  
  480. for MethodIndex, _ in Metatable.metamethods do
  481. local rg = rawget(mt, MethodIndex)
  482. if rg then
  483. methods ..= ('\n%s%s = %s;'):format(a:rep(tabs + 5), MethodIndex, format(rg, tabs + 5))
  484. end
  485. end
  486.  
  487. methods = #methods > 1 and methods .. '\n' .. a:rep(tabs + 4) .. '}\n' .. a:rep(tabs + 1) or '{}'
  488.  
  489. t = ('setmetatable(%s, %s)'):format(t, methods)
  490. end
  491.  
  492. return t
  493. elseif type == "function" then
  494. if not table.find(protos, value) and value ~= tree.f then
  495. table.insert(protos, value)
  496.  
  497. local paramcount, isvrg = debug.info(tree.f, 'a')
  498.  
  499. local pars = ''
  500.  
  501. if isvrg then
  502. pars = '...'
  503. else
  504. for i = 1, paramcount do
  505. pars = pars .. '_p' .. tostring(i)
  506. if i ~= paramcount then
  507. pars = pars .. ', '
  508. end
  509. end
  510. end
  511.  
  512. local sandbox = Sandbox(value, merge_t(table.clone(params), upvalues), constants, protos, i)
  513. local _disassembly = Disassemble(sandbox, tabs + 1)
  514.  
  515. if sandbox.function_info[1] == "" then
  516. return ("function(%s) %s\n%send"):format(pars, _disassembly, (' '):rep(tabs))
  517. else
  518. disassembly[pc + 1] = ("%slocal function %s(%s) %s\n%send\n"):format(
  519. (' '):rep(tabs),
  520. sandbox.function_info[1],
  521. pars,
  522. _disassembly,
  523. (' '):rep(tabs)
  524. )..(disassembly[pc] or "")
  525.  
  526. pc += 1 + stack_offset
  527.  
  528. return sandbox.function_info[1]
  529. end
  530. elseif value == tree.f then
  531. local func_name = debug.info(value, "n")
  532.  
  533. if func_name == "" then
  534. return "__func__"
  535. else
  536. return func_name
  537. end
  538. else
  539. return ("function() --[[ Unknown proto ]] end")
  540. end
  541. end
  542.  
  543. local val = handle(value)
  544.  
  545. return val
  546. end
  547.  
  548. local function format_tuple(...)
  549. local t = {}
  550.  
  551. local last = 0
  552. for i, index in {...} do
  553. if i - last > 1 then
  554. local void_size = i - last - 1
  555. table.move(table.create(void_size, "nil"), i, void_size, 1, t)
  556. end
  557.  
  558. table.insert(t, format(index))
  559.  
  560. last = i
  561. end
  562.  
  563. return table.concat(t, ", ")
  564. end
  565.  
  566. local function parse(branch, parent)
  567. tab_formatting = (" "):rep(math.round(tabs / 2))
  568.  
  569. if math.random(0, 2) == 0 then task.wait() end -- prevent script timeout while maintaining performance
  570.  
  571. pc = branch.pc
  572.  
  573. local metamethod = branch.metamethod
  574. local args = branch.arguments
  575.  
  576. local parent_pc = (parent and parent.pc) or 0
  577. local a, b = args[1], args[2]
  578.  
  579. a = a or '(???)'
  580.  
  581. local global = parent == nil
  582.  
  583. local argCount, isv = debug.info(tree.f, 'a')
  584.  
  585. argCount = isv and math.huge or argCount
  586.  
  587. local push = ("-- unsupported method '%s'"):format(metamethod)
  588.  
  589. local adjusted_pc = (pc - 1) % argCount + 1
  590.  
  591. if metamethod == "__index" then
  592. if global then
  593. push = ("%slocal v%d = %s"):format(tab_formatting, pc, a)
  594.  
  595. table.insert(constants, a)
  596.  
  597. stack[pc] = a
  598. else
  599. local fixed
  600. if quickaccess[a] then a = quickaccess[a] fixed = true end
  601. local bq
  602. for libname, lib in next, libs do
  603. for funcname, v in lib do
  604. if funcname == a then
  605. bq = `{libname}.{funcname}`
  606. fixed = true
  607. end
  608. end
  609. end
  610. if not fixed then
  611. push = ("%slocal v%d = %s%s"):format(tab_formatting, pc, 'v' .. tostring(parent_pc), Clean(a) == a and '.' .. a or string.format("[%s]", tostring(format(a))))
  612. else
  613. push = ("%slocal v%d = %s"):format(tab_formatting, pc, bq)
  614. end
  615.  
  616. table.insert(constants, a)
  617.  
  618. stack[pc] = not fixed and (Clean(a) == a and '.' .. a or string.format("[%s]", tostring(format(a)))) or bq
  619. if fixed and not quickaccess[a] then
  620. quickaccess[a] = 'v' .. tostring(pc)
  621. end
  622. end
  623.  
  624. elseif metamethod == "__newindex" then
  625. if global then
  626. push = ("%slocal v%d = %s"):format(tab_formatting, pc, format(b))
  627.  
  628. table.insert(constants, a)
  629.  
  630. stack[pc] = format(b)
  631. else
  632. push = ("%slocal v%d[%s] = %s"):format(tab_formatting, parent_pc, format(a), format(b))
  633.  
  634. table.insert(constants, a)
  635.  
  636. stack[pc] = format(b)
  637. end
  638. elseif metamethod == "__call" then
  639. local namecall_info = ""
  640. local namecall_stack = stack[args[1] or -1]
  641. local is_namecall = namecall_stack == parent_pc - 1
  642.  
  643. if is_namecall and (parent and parent.parent and parent.parent.arguments) then
  644. local a = parent.parent.arguments[1] or "(???)"
  645. local b = parent.arguments[1] or "(???)"
  646.  
  647. pcall(function()
  648. namecall_info = ("-- %s.%s(%s)"):format(a, b, format_tuple(unpack(args)))
  649. end)
  650. end
  651. local tpl = format_tuple(unpack(args))
  652. local rgs = tpl:split(',')
  653. local result = ''
  654. for ff, arg in rgs do
  655. local arg2 = arg:gsub(' ', '')
  656. if arg2:sub(1, 2) == '_p' and arg2:sub(3, #arg):match("%d+") == arg2:sub(3, #arg) then
  657. local index = tonumber(arg2:sub(3, #arg))
  658. local nIndex = index
  659. if argCount < index then
  660. nIndex = (index - 1) % argCount + 1
  661. end
  662. arg2 = arg2:gsub(index, nIndex)
  663. end
  664. result = result .. arg2
  665. if ff < #rgs then
  666. result = result .. ', '
  667. end
  668. end
  669. local fixedString = ''
  670. local func = stack[parent_pc]
  671. if result:split(', ')[1]:sub(1, 2) == '_p' then
  672. if not table.find(luaGlobals, func) then
  673. fixedString = (parent_pc > 0 and 'v' or '_p') .. tostring(parent_pc - 1) .. ':' .. func .. '(' .. result:gsub(result:split(', ')[1] .. ', ', '') .. ')'
  674. end
  675. end
  676. if fixedString ~= '' then
  677. push = ("%slocal v%d = %s %s"):format(tab_formatting, pc, fixedString, namecall_info)
  678. else
  679. push = ("%slocal v%d = %s(%s) %s"):format(tab_formatting, pc, quickaccess[a] or parent_pc > 0 and 'v' .. tostring(parent_pc) or '_p' .. tostring(adjusted_pc), result, namecall_info)
  680. end
  681. elseif metamethod == '__tostring' then
  682. print(a, b, '__tostring')
  683. else
  684. print("Method!!")
  685. local only_self = {
  686. __len = "#",
  687. __unm = "-",
  688. __tostring = "tostring"
  689. }
  690.  
  691. local math = {
  692. __add = "+",
  693. __sub = "-",
  694. __mul = "*",
  695. __div = "/",
  696. __idiv = "//",
  697. __pow = "^",
  698. __eq = "==",
  699. __lt = "<",
  700. __le = "<=",
  701. __mod = "%",
  702. __concat = '..'
  703. }
  704.  
  705. local self_index, math_index = only_self[metamethod], math[metamethod]
  706.  
  707. if self_index then
  708. if self_index ~= 'tostring' then
  709. local thing = self_index
  710. if parent_pc > 0 then
  711. thing = thing .. 'v'.. tostring(parent_pc)
  712. else
  713. thing = thing .. '_p'.. tostring(adjusted_pc)
  714. end
  715. push = ("%slocal v%d = %s"):format(
  716. tab_formatting,
  717. pc,
  718. lens['v' .. tostring(parent_pc)] or thing
  719. )
  720. table.insert(constants, 'v' .. tostring(pc))
  721. else
  722. push = ("%slocal v%d = %s"):format(
  723. tab_formatting,
  724. pc,
  725. parent_pc > 0 and 'v' .. tostring(parent_pc)
  726. )
  727. end
  728. elseif math_index then
  729. push = ("%slocal v%d = v%d %s %s"):format(tab_formatting, pc, parent_pc, math_index, format(a))
  730. end
  731. end
  732.  
  733. disassembly[pc + stack_offset] = push
  734.  
  735. for _, child in next, branch.children do
  736. parse(child, branch)
  737. end
  738. end
  739.  
  740. for _, child in next, tree.children do
  741. parse(child)
  742. end
  743.  
  744. if success then
  745. local return_value = tree.return_value
  746.  
  747. if final_pc > 0 then
  748. table.insert(disassembly, "")
  749. end
  750.  
  751. if #return_value > 0 then
  752. table.insert(disassembly, ("%sreturn %s;"):format((' '):rep(math.round(tabs / 2)), format_tuple(unpack(return_value))))
  753. else
  754. table.insert(disassembly, (' '):rep(math.round(tabs / 2)) .. "return nil; --[[ No return value found ]]")
  755. end
  756. end
  757.  
  758. local header = (' '):rep(tabs + 1) .. "-- %s, %d%s params, %d constants, %d protos\n\n"
  759.  
  760. header = header:format(
  761. (function_info[1] == "" and "anonymous") or ('%s'):format(function_info[1]),
  762. function_info[2],
  763. (function_info[3] and "+") or "",
  764. #constants,
  765. #protos
  766. )
  767.  
  768. disassembly = header..table.concat(disassembly, "\n"..tab_formatting)
  769.  
  770. return ((not success and ("%s-- An error occured while decompiling (@pc %d)\n"):format(tab_formatting, final_pc)) or "")..disassembly, constants, protos, success
  771. end
  772.  
  773. return Sandbox, Disassemble
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement