Herkle Deobfuscation

Run Settings
LanguageLua
Language Version
Run Command
-- This will no longer get update because it's private from now on -- settings local getfenvhook = false local concathook = false local constant = false -- sucks local decode = false -- sucks either local loadshook = false -- prints the whole original source (only if obfuscator uses loadstring) local pairshook = false -- logs for i,v in pairs local log = true -- something like threads (not deobfuscate, logs what script does) local printf = false -- not recommended, may spam your console (on wearedevs) -- functions for lua 53+ and for deobf local object_map = {} local obj_count = 0 local old_pr = print if not loadstring then function loadstring(code) old_pr(code) return load(code) end end function typeof(v) return type(v) end function getfenv(level) level = (level or 1) + 1 local info = debug.getinfo(level, "f") if not info then return _ENV end local func = info.func if type(func) ~= "function" then return _ENV end local i = 1 while true do local name, value = debug.getupvalue(func, i) if not name then break end if name == "_ENV" then return value end i = i + 1 end return _ENV end function unpack(arg) return table.unpack(arg) end local function const(source) local constants = {} local index = {} local count = 0 local function decode(str) return (str:gsub("\\(%d%d?%d?)", function(d) return string.char(tonumber(d)) end)) end source = source:gsub("(['\"])(.-)%1", function(_, str) local decoded = decode(str) if not index[decoded] then count = count + 1 index[decoded] = count constants[count] = decoded end return ("C[%d]"):format(index[decoded]) end) local constSrc = "local C = {\n" for i, v in ipairs(constants) do constSrc = constSrc .. (" [%d] = %q,\n"):format(i, v) end constSrc = constSrc .. "}\n\n" return constSrc .. source end local function addCompoundSupport(code) local lines = {} for line in code:gmatch("([^\n\r]+)") do local startPos, endPos = line:find("%s*%+=%s*") if startPos then local left = line:sub(1, startPos - 1):match("^%s*(.-)%s*$") local right = line:sub(endPos + 1):match("^%s*(.-)%s*$") line = string.format("local _v = %s; %s = _v + %s", left, left, right) end table.insert(lines, line) end return table.concat(lines, "\n") end if log then local function serialize(v) if object_map[v] then return object_map[v] end local t = (type(v) == "table" and v.__type) or type(v) if getmetatable(v) and getmetatable(v).__type == "Instance" then t = "Instance" end if t == "string" then return string.format("%q", v) elseif t == "EnumItem" then return v.Value elseif t == "Vector3" then return "Vector3.new(" .. tostring(v) .. ")" elseif t == "Vector2" then return "Vector2.new(" .. tostring(v) .. ")" elseif t == "CFrame" then return "CFrame.new(" .. tostring(v) .. ")" elseif t == "Color3" then local constructor = v.__mode or "new" return "Color3." .. constructor .. "(" .. tostring(v) .. ")" elseif t == "ColorSequence" then local kps = {} for i, kp in ipairs(v.Keypoints) do table.insert(kps, serialize(kp)) end return "ColorSequence.new({" .. table.concat(kps, ", ") .. "})" elseif t == "ColorSequenceKeypoint" then return "ColorSequenceKeypoint.new(" .. v.Time .. ", " .. serialize(v.Value) .. ")" elseif t == "UDim2" then return "UDim2.new(" .. tostring(v) .. ")" elseif t == "UDim" then return "UDim.new(" .. tostring(v) .. ")" elseif t == "Instance" then return v:GetFullName() elseif t == "table" then local s = "{" for k, val in pairs(v) do if k ~= "__type" and k ~= "__mode" then local keyStr = type(k) == "string" and string.format("%q", k) or tostring(k) local valStr = serialize(val) s = s .. string.format("\n [%s] = %s,", keyStr, valStr) end end return s .. "\n}" elseif t == "function" then return "function" elseif t == "TweenInfo" then return string.format("TweenInfo.new(%s, %s, %s, %s, %s, %s)", v.Time, serialize(v.EasingStyle), serialize(v.EasingDirection), v.RepeatCount, v.Reverses, v.DelayTime) else return tostring(v) end end local function createDataType(name, methods) return setmetatable({}, { __index = function(_, method) return function(...) local args = {...} local out = {} for i, v in ipairs(args) do out[i] = serialize(v) end local result = methods[method](...) return result end end }) end _G.Enum = setmetatable({}, { __index = function(self, enumType) local enumObj = setmetatable({}, { __index = function(_, enumItem) return { __type = "EnumItem", Value = "Enum." .. enumType .. "." .. enumItem } end, __tostring = function() return "Enum." .. enumType end }) rawset(self, enumType, enumObj) return enumObj end }) _G.Color3 = createDataType("Color3", { new = function(r, g, b) return setmetatable({ R = r or 0, G = g or 0, B = b or 0, __type = "Color3", __mode = "new" }, { __tostring = function(t) return t.R .. ", " .. t.G .. ", " .. t.B end }) end, fromRGB = function(r, g, b) return setmetatable({ R = r or 0, G = g or 0, B = b or 0, __type = "Color3", __mode = "fromRGB" }, { __tostring = function(t) return t.R .. ", " .. t.G .. ", " .. t.B end }) end }) _G.ColorSequenceKeypoint = createDataType("ColorSequenceKeypoint", { new = function(time, color) return setmetatable({ Time = time or 0, Value = color, __type = "ColorSequenceKeypoint" }, { __tostring = function(t) return tostring(t.Time) .. " " .. serialize(t.Value) end }) end }) _G.ColorSequence = createDataType("ColorSequence", { new = function(...) local args = {...} local kps = type(args[1]) == "table" and args[1] or args return setmetatable({ Keypoints = kps, __type = "ColorSequence" }, { __tostring = function() return "ColorSequence" end }) end }) _G.Vector3 = createDataType("Vector3", { new = function(x, y, z) return setmetatable({X = x or 0, Y = y or 0, Z = z or 0, __type = "Vector3"}, {__tostring = function(t) return t.X .. ", " .. t.Y .. ", " .. t.Z end}) end }) _G.Vector2 = createDataType("Vector2", { new = function(x, y) return setmetatable({ X = x or 0, Y = y or 0, __type = "Vector2" }, { __tostring = function(t) return t.X .. ", " .. t.Y end }) end }) _G.CFrame = createDataType("CFrame", { new = function(x, y, z) return setmetatable({p = _G.Vector3.new(x, y, z), __type = "CFrame"}, { __tostring = function(t) return tostring(t.p) end }) end }) _G.UDim = createDataType("UDim", { new = function(scale, offset) return setmetatable({ Scale = scale or 0, Offset = offset or 0, __type = "UDim" }, { __tostring = function(t) return t.Scale .. ", " .. t.Offset end }) end }) _G.UDim2 = createDataType("UDim2", { new = function(sx, ox, sy, oy) return setmetatable({Sx = sx or 0, Ox = ox or 0, Sy = sy or 0, Oy = oy or 0, __type = "UDim2"}, {__tostring = function(t) return t.Sx .. ", " .. t.Ox .. ", " .. t.Sy .. ", " .. t.Oy end}) end, fromScale = function(x, y) return _G.UDim2.new(x, 0, y, 0) end, fromOffset = function(x, y) return _G.UDim2.new(0, x, 0, y) end }) _G.TweenInfo = createDataType("TweenInfo", { new = function(time, easingStyle, easingDirection, repeatCount, reverses, delay) return setmetatable({ Time = time or 1, EasingStyle = easingStyle or _G.Enum.EasingStyle.Linear, EasingDirection = easingDirection or _G.Enum.EasingDirection.Out, RepeatCount = repeatCount or 0, Reverses = reverses or false, DelayTime = delay or 0, __type = "TweenInfo" }, { __tostring = function() return "TweenInfo.new()" end }) end }) _G.Drawing = { new = function(className) obj_count = obj_count + 1 local varName = "draw_" .. obj_count old_pr(string.format("local %s = Drawing.new(%q)", varName, className)) local internal = { Visible = false, Transparency = 1, Color = _G.Color3.new(1,1,1) } local proxy = setmetatable({}, { __type = "Drawing", __index = function(_, k) if k == "Remove" or k == "Destroy" then return function() old_pr(varName .. ":Remove()") end end return internal[k] end, __newindex = function(_, k, v) internal[k] = v old_pr(string.format("%s.%s = %s", varName, k, serialize(v))) end }) object_map[proxy] = varName return proxy end } local services = {} local function createInstance(className, name, isService) obj_count = obj_count + 1 local varName = isService and ('game:GetService("' .. name .. '")') or ("obj_" .. obj_count) local internal = { ClassName = className, Name = name or className, Parent = nil } local proxy = setmetatable({}, { __type = "Instance", __index = function(_, k) if internal[k] then return internal[k] end if k == "WalkSpeed" then return 16 end if k == "Health" then return 100 end if k == "GetFullName" then return function() return "game." .. internal.Name end end if k == "WaitForChild" or k == "FindFirstChild" or k == "FindFirstChildOfClass" then return function(_, childName) local child = createInstance("Part", childName or "Child") old_pr(string.format("local %s = %s:%s(%q)", object_map[child], varName, k, tostring(childName))) return child end end if k == "SetCore" then return function(_, coreName, data) old_pr(string.format("%s:SetCore(%q, %s)", varName, coreName, serialize(data))) return nil end end if k == "GetChildren" or k == "getChildren" then return function() return {} end end if k == "Destroy" or k == "Clone" then return function() old_pr(varName .. ":" .. k .. "()") internal.Parent = nil end end if k == "JSONEncode" then return function(_, data) local res = "{}" old_pr(string.format('%s:JSONEncode(%s)', varName, serialize(data))) return res end end if k == "GenerateGUID" then return function(_, arg) local res = "00000000-0000-0000-0000-000000000000" old_pr(string.format('%s:GenerateGUID(%s)', varName, arg ~= nil and tostring(arg) or "")) return res end end if k == "Create" and internal.ClassName == "TweenService" then return function(_, obj, info, props) obj_count = obj_count + 1 local tweenVar = "obj_" .. obj_count old_pr(string.format("local %s = %s:Create(%s, %s, %s)", tweenVar, varName, serialize(obj), serialize(info), serialize(props))) local tweenProxy = { Play = function() old_pr(tweenVar .. ":Play()") end, Stop = function() old_pr(tweenVar .. ":Stop()") end, Cancel = function() old_pr(tweenVar .. ":Cancel()") end, Pause = function() old_pr(tweenVar .. ":Pause()") end, Completed = { Connect = function() return {Disconnect = function() end} end, Wait = function() end } } return tweenProxy end end local propertyObj = createInstance("Part", k) old_pr(string.format("local %s = %s.%s", tostring(object_map[propertyObj]), tostring(varName), tostring(k))) local mt = getmetatable(propertyObj) local old_idx = mt.__index mt.__index = function(t, key) if key == "Connect" or key == "connect" then return function(_, fn) old_pr(object_map[t] .. ":" .. key .. "(function()") if type(fn) == "function" then task.spawn(fn) end old_pr("end)") return { Disconnect = function() end } end elseif key == "Wait" or key == "wait" then return function() return end end return old_idx(t, key) end rawset(internal, k, propertyObj) return propertyObj end, __newindex = function(proxy, k, v) internal[k] = v local valStr = serialize(v) if (type(v) == "table" or type(v) == "userdata") and valStr == "nil" then valStr = "UnknownObject" end old_pr(varName .. "." .. tostring(k) .. " = " .. valStr) end, __tostring = function() return internal.Name end }) object_map[proxy] = varName return proxy end _G.game = setmetatable({ GetService = function(_, s) if not services[s] then services[s] = createInstance(s, s, true) end return services[s] end, HttpGet = function(_, url) old_pr(string.format('loadstring(game:HttpGet(%q))()', url)) return "" end }, { __index = function(t, k) return t:GetService(k) end }) _G.Instance = { new = function(c, p) local o = createInstance(c) old_pr("local " .. object_map[o] .. " = Instance.new(" .. serialize(c) .. ")") if p then o.Parent = p end return o end } _G.game:GetService("UserInputService") _G.workspace = _G.game:GetService("Workspace") _G.HttpService = _G.game:GetService("HttpService") _G.TweenService = _G.game:GetService("TweenService") _G.RunService = _G.game:GetService("RunService") _G.syn = { request = function(options) old_pr("syn.request(" .. serialize(options) .. ")") return {Success = true, Body = "{}", StatusCode = 200} end } _G.request = _G.syn.request end local function pretty(v) if type(v) == "table" then return tostring(v) elseif type(v) == "function" then return tostring(v) elseif type(v) == "string" then return string.format("%q", v) else return tostring(v) end end local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' local function base64_decode(data) data = data:gsub('[^'..b..'=]', '') return (data:gsub('.', function(x) if x == '=' then return '' end local r,f='',(b: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) if #x ~= 8 then return '' end local c = 0 for i=1,8 do c = c + (x:sub(i,i)=='1' and 2^(8-i) or 0) end return string.char(c) end)) end local function deobf(code) local strings = {} for encoded in code:gmatch("'([^']+)'") do pcall(function() local decoded = base64_decode(encoded:reverse()):gsub("\n","") table.insert(strings, decoded) end) end if #strings == 2 then local func = strings[1] local arg = strings[2] return string.format('%s(%q)', func, arg) end end spawn = spawn or function(fn) local co = coroutine.create(function() pcall(fn) end) coroutine.resume(co) end task = task or {} task.spawn = task.spawn or spawn task.wait = function() return 0 end task.defer = function(fn) spawn(fn) end task.delay = function(d, fn) spawn(fn) end wait = function() return 0 end if old_prf then function error(f) old_pr(f) end function warn(f) old_pr(f) end end -- hook local old_fenv = getfenv local old_concat = table.concat local old_pairs = pairs local concatQueue = {} if getfenvhook then local seen = {} local function safe(v) local t = typeof(v) if t == "string" then return string.format("%q", v) elseif t == "Instance" then return v:GetFullName() else return tostring(v) end end getfenv = function(level) local env = old_fenv(level) return setmetatable({}, { __index = function(_, key) if type(key) == "string" and not seen[key] then seen[key] = true end local val = env[key] if type(val) == "function" then return function(...) local args = {...} local out = {} for i = 1, #args do out[i] = safe(args[i]) end local re = tostring( key .. "(" .. table.concat(out, ", ") .. ")", "\n" ) if type(re) == "string" then old_pr(re, "\n") return function() end end return val(...) end end return val end }) end end if concathook then table.concat = function(tbl, sep, i) sep = sep or "" i = i or 1 local result = old_concat(tbl, sep, i) table.insert(concatQueue, result) if #concatQueue >= 2 then local a = concatQueue[#concatQueue - 1] local b = concatQueue[#concatQueue] if a == "Text" then local m = a .. " = " .. string.format("%q", b) old_pr(m) return m end end if result == "ReplicatedStorage" then result = 'local v1 = game:GetService("ReplicatedStorage")' end if result == "HttpService" then result = 'local v2 = game:GetService("HttpService")' end if result == "Lighting" then result = 'local v3 = game:GetService("Lighting")' end if result == "RunService" then result = 'local v4 = game:GetService("RunService")' end if result == "MarketplaceService" then result = 'local v5 = game:GetService("MarketplaceService")' end if result == "CollectionService" then result = 'local v6 = game:GetService("CollectionService")' end if result == "Players" then result = 'local v7 = game:GetService("Players")' end if result == "Workspace" then result = 'local v8 = game:GetService("Workspace")' end if result == "TeleportService" then result = 'local v9 = game:GetService("TeleportService")' end if result == "GetMouse" then result = 'local v9 = v7.LocalPlayer:GetMouse()' end if result == "PlayerGui" then result = 'local v10 = v7.LocalPlayer.PlayerGui' end if result == "CharacterAdded" then result = 'v7.LocalPlayer.CharacterAdded' end if result == "Died" then result = 'v7.LocalPlayer.Character.Humanoid.Died' end if result == "HumanoidRootPart" then result = 'v7.LocalPlayer.Character:FindFirstChild("HumanoidRootPart")' end if result == "Humanoid" then result = 'v7.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")' end if result == "Character" then result = 'v7.LocalPlayer.Character' end if result == "LocalPlayer" then result = 'v7.LocalPlayer' end if result == "PlaceId" then result = 'game.PlaceId' end if result == "IsLoaded" then result = 'game.IsLoaded' end if result == "spawn" then result = 'spawn(function()' end if result == "CurrentCamera" then result = 'local v10 = workspace.CurrentCamera' end if result == "ScreenGui" then result = 'local v11 = Instance.new("ScreenGui")' end if result == "Frame" then result = 'local v12 = Instance.new("Frame")' end if result == "TextLabel" then result = 'local v13 = Instance.new("TextLabel")' end if result == "TextButton" then result = 'local v14 = Instance.new("TextButton")' end if result == "Custom" then result = 'Enum.CameraType.Custom' end if result == "Color" then result = 'Color3.new' end if result == "CFrame" then result = 'CFrame.new' end if result == "Vector3" then result = 'Vector3.new' end if result == "MouseButton1Click" then result = 'v14.MouseButton1Click:Connect(function()' end old_pr(tostring(result)) return result end end if loadshook then loadstring = function(code) old_pr(tostring(code)) return function() end end end if pairshook then pairs = function(t) local iter, tbl, key = old_pairs(t) return function(_, k) local v k, v = iter(tbl, k) if k ~= nil then old_pr(string.format( "for i,v in pairs(%s) do\nprint(%s,%s)\nend\n", pretty(tbl), pretty(k), pretty(v), pretty(v) )) end return k, v end, tbl, key end end if log then print = function(...) local args, s = {...}, "" for i, v in ipairs(args) do s = s .. tostring(v) .. (i < #args and "\t" or "") end old_pr('print("' .. s .. '")') end end -- paste the script inside "script" and run local script = [====[ local plr = game:GetService("Players").LocalPlayer local char = plr.Character or plr.CharacterAdded:Wait() local hrp = char:WaitForChild("HumanoidRootPart") local part = Instance.new("Part") part.Parent = workspace part.Shape = Enum.PartType.Ball part.Color = Color3.fromRGB(255, 0, 0) part.CFrame = hrp.CFrame ]====] if constant then local res = const(deobf(script)) old_pr(res) else if decode then local decoded = deobf(script) old_pr(decoded) end script = addCompoundSupport(script) local func, err = load(script) if func then func() else old_pr("Error: " .. err) end end
Editor Settings
Theme
Key bindings
Full width
Lines