0

I am a exploiter for roblox which mean that I execute scripts via an external program called an exploit on running roblox games. To make script for my exploits, I have to use debugging library and decompilation.

Roblox have released a new lua vm some months ago vm which removed the debug information which make the reverse enginering of roblox games process much harder than it used to be.

One of the difficulty that I face is that the compilation are harder to understand. I would like to seek for tips understanding the decommpilation as I don't have any information on the variable name. It has to be noted that luau keep the function name information in it's bytecode.

Here is a exemple of a decompilation result :

-- Decompiled with the Synapse X Luau decompiler.

local v1 = 2250;
local v2 = 750;
local l__Enemies__3 = workspace:WaitForChild("Enemies");
local l__CurrentCamera__4 = workspace.CurrentCamera;
local l__Unloaded__5 = game.ReplicatedStorage:WaitForChild("Unloaded");
local v6 = game:GetService("CollectionService"):GetTagged("Detail");
local v7 = {};
local l__next__8 = next;
local v9, v10 = workspace:WaitForChild("Map"):GetChildren();
while true do
    local v11, v12 = l__next__8(v9, v10);
    if not v11 then
        break;
    end;
    v10 = v11;
    local v13 = {};
    local v14 = {};
    for v15, v16 in next, v6 do
        if v16:IsDescendantOf(v12) then
            table.insert(v14, v16);
        else
            table.insert(v13, v16);
        end;
    end;
    v7[v12] = {
        Position = v12:GetModelCFrame().p, 
        Details = v14, 
        Rendering = true
    };
    v6 = v13;
end;
local u1 = {};
local function v17(p1)
    if u1[p1] then
        return;
    end;
    p1:WaitForChild("CharacterReady");
    local l__HumanoidRootPart__18 = p1:WaitForChild("HumanoidRootPart", 1);
    if u1[p1] then
        return;
    end;
    if l__HumanoidRootPart__18 then
        u1[p1] = {
            Model = p1, 
            HRP = l__HumanoidRootPart__18, 
            Rendering = true
        };
    end;
end;
l__Enemies__3.ChildAdded:Connect(v17);
local l__next__19 = next;
local v20, v21 = l__Enemies__3:GetChildren();
while true do
    local v22, v23 = l__next__19(v20, v21);
    if not v22 then
        break;
    end;
    v21 = v22;
    spawn(function()
        v17(v23);
    end);
end;
while wait(1) do
    local l__p__24 = l__CurrentCamera__4.CFrame.p;
    local l__next__25 = next;
    local v26 = nil;
    while true do
        local v27, v28 = l__next__25(v7, v26);
        if not v27 then
            break;
        end;
        local v29 = false;
        local v30 = v1 < (v28.Position - l__p__24).magnitude;
        if v28.Rendering and v30 then
            v28.Rendering = false;
            for v31, v32 in next, v28.Details do
                v32.Parent = l__Unloaded__5;
            end;
            v29 = true;
        elseif v28.Rendering == false and v30 == false then
            v28.Rendering = true;
            for v33, v34 in next, v28.Details do
                v34.Parent = v27;
            end;
            v29 = true;
        end;
        if v29 then

        end;    
    end;
    local v35 = 0;
    for v36, v37 in next, u1 do
        if not v37.Model or not v37.Model.Parent then
            u1[v36] = nil;
        else
            v35 = v35 + 1;
            local v38 = v2 < (v37.HRP.Position - l__p__24).magnitude;
            if v37.Rendering and v38 then
                v37.Rendering = false;
                v37.Model.Parent = game.ReplicatedStorage;
            elseif v37.Rendering == false and v38 == false then
                v37.Rendering = true;
                v37.Model.Parent = l__Enemies__3;
            end;
        end;
    end;
    if (game.PlaceId == 3275089863 or game.Players.LocalPlayer.Name == "Robotmega") and math.random(1, 100) == 1 then
        print("Enemies registered: ", v35);
    end;
end;

Luau also remove debug infomration as such debug information via the debug library is not availaible. As exemple debug.getupvalue return numbers indice instead of the upvalue name. Here is a exemple on the following script :

Game script :

-- game script
local health = 10
local ammo = 100
local state = "standing"

function showStats()
  print("Health: "..health.."\nAmmo: "..ammo.."\nState: "..state)
end

Exploit Script :

-- exploit script
-- note: getsenv() is a custom function of a exploit that allow you to see the environement of a script. It only return the function of a script and the script path. It only work when it's on a running script.
for k,v in pairs(debug.getupvalues(getsenv().Players.LocalPlayer.PlayerScripts.stat).showStats) do
    print(k,v)
end

This would return the following :

1 10
2 100
3 standing

To sum up my question, can I get tips to reverse engineer script when I don't have the debug informationa available?

So far I rename the variable name to what I decuce they are about. As for the decompilation,I ctrl+f and I deduce what the variable name are.

As for the debug library what I do is that I run the getsenv function as I showcased above and I control f the value that it return on the decompiled local script. If they are the right one I change them to make the cheat and I note the meaning of the upvalue. If I don't have any idea of what they are doing I think they are. If I have no idea I do trial and error ; I change the upvalues values see if something change in the game.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.