Categories > Exploiting > Roblox >

debug.setconstant issue.

New Reply

Posts: 2

Threads: 1

Joined: Sep, 2024

Reputation: 0

Posted

hi my bypass uses debug.setconstant so if there is no debug.setconstant what function can i replace it with?

  • 0

  • Comment

RealNickk

nick / reversed-coffee

vip

Posts: 13

Threads: 2

Joined: Mar, 2023

Reputation: 7

Replied

You might be able to temporarily suspend the thread using coroutine.yield right after the variable is initialized by hooking a function. Once you pause it, you can try traversing the garbage collector registry with getgc and change the instances of the value you're looking for. Once the changes are made, you can resume the thread with coroutine.resume or task.spawn. This method might not work depending on how the variable is used down the road, and there may be side effects.

 

Edit: It may be worth looking into how the script functions if you can decompile it. There may be other indirect ways to get your intended behavior.

Comments

moeizu 0 Reputation

Commented

Can u give me a example pls @@ im confused

  • 0

  • 1

  • Comment

Added

@moeizu Something like this might work depending on your circumstances. The only true way to know is to reverse engineer your target script:

-- Scripts are NOT tested, consider it pseudocode.

---- Target script ----
-- Path: path.to.script

local value = "hello world"

-- variable exists, now it exists in the garbage collector
-- say that we index game.Players.LocalPlayer
local player = game.Players.LocalPlayer

-- we can hook the '__index' metamethod of 'game' here (that's a function that
-- will get called when indexing any object under 'game'), and it will intercept
-- the thread execution so we can change that value

print(value) --> "hello world"
-- but if we run the script below before the target, it will print "hacked"

---- Intercept script ----

local scriptToIntercept = path.to.script -- the script to intercept
local gameIndexer = debug.getmetatable(game).__index -- might be 'getrawmetatable' depending on your executor

-- this will scan the garbage collector registry for instances of "hello world"
-- and change them to "hacked"
local function scanGarbageCollector()
    local cache = setmetatable({}, { __mode = "k" }) -- prevent cyclic searching. weak table is good for this
    local queue = { getgc() } -- we'll start off at the root...(debug.getregistry might work too but i've had more success with getgc)

    -- This is a scan method that avoids recursion. Since the garbage collector registry
    -- contains a ton of objects, we don't want to keep recursing and lead to a stack overflow
    -- due to too many frames in the call stack.
    while #queue > 0 do
        local t = table.remove(queue, 1) -- pull from the front of the queue
        if type(t) == "table" then
            for k, v in pairs(t) do
                if v == "hello world" then
                    -- this is the magic here, we change the value
                    -- for a more solid approach, you could use rawset to avoid
                    -- invoking any metamethods which can detect the change
                    t[k] = "hacked"
                elseif type(v) == "table" and not cache[v] then -- queue for search
                    cache[v] = true
                    table.insert(queue, v) -- push to the back of the queue
                end
            end
        end
    end
end

-- you may not need newcclosure here if your executor is smart enough
-- generally when you hook a C closure, the destination function has to be a C
-- closure too
local oldIndex;
oldIndex = hookfunction(gameIndexer, newcclosure(function(self, key)
    if checkcaller() then
        -- Passthrough. This is for indexes done from the executor's thread
        -- context. This allows us to make indexes on instances inside this hook
        -- without triggering an infinite loop.
        return oldIndex(self, key)
    end

    -- we're gonna identify the script of the caller by pulling the function then
    -- indexing the source property
    -- you can use getcallingscript but i dont know if your exploit supports it
    -- so im just going to use a method that I know is pretty solid

    -- get global env of calling closure (traveling backwards through the callstack once)
    -- and find script. might be 3 depending on your executor, or just pull the
    -- calling func with debug.getinfo and pull global env from there (or traverse whatever you think is best)
    local callerScript = getfenv(2).script -- you might be able to use rawget here too but im not entirely sure

    -- if the caller is the target script, we're going to do some more checks
    if callerScript == scriptToIntercept then
        -- we're going to check if the key is "Players" and if it is, we're going to
        -- scan the garbage collector for the value "hello world" and change it to "hacked"
        if self == game and key == "Players" then
            scanGarbageCollector()
        end
    end

    return oldIndex(self, key)
end))
  • 1

  • Comment

former wrd mod, reverse engineer, smarty pants

github.com/reversed-coffee | www.reversed.coffee

github.com/substrant | substrant.dev

Posts: 1

Threads: 0

Joined: Sep, 2024

Reputation: 0

Replied

Thank you so much.

  • 0

  • Comment

Login to unlock the reply editor

Add your reply

Users viewing this thread:

( Members: 0, Guests: 1, Total: 1 )