--[[
Syphon — Adonis Anti-Cheat Bypass (standalone, for review)
---------------------------------------------------------
Single-chokepoint neutralization of the Adonis client anticheat.
HOW IT WORKS
------------
Every Adonis detector (movement, metamethod, anti-kick, remote-spy,
string-scan, etc.) funnels through ONE client-side closure: `Detected`
(Adonis/MainModule/Client/Core/Anti.luau:81). That closure fires an
encrypted remote at the server ("Detected") and then locally
kicks/kills/crashes the player. If `Detected` is a no-op, ALL reporting
and ALL local punishment stops.
Adonis actively self-defends `Detected` via two checks:
1. Signature self-check (Anti.luau:417-429): compares
debug.info(Detected,"slanf") against a golden copy captured at
startup; requires arity==3, non-vararg, closure identity intact.
A mismatch -> `while true do end` hang.
2. TableCheck thread (Anti.luau:661-672): independently re-reads
client.Anti.Detected and identity-checks it -> crash.
THE KEY INSIGHT (why this doesn't freeze the game):
On a modern executor `hookfunction` patches the closure IN PLACE.
The closure reference (`closure == Detected`) and its debug.info
signature both stay identical automatically — which is exactly what
both checks require. So we need NO global debug.info hook.
(An earlier version hooked getrenv().debug.info globally with a Lua
trampoline; debug.info is on every hot path — Adonis's loops, its
metamethod detectors, and Roblox internals — so that hook multiplied
into a render-thread freeze. This version removes it entirely.)
We verify transparency up front and only fall back to a tiny,
non-recursive spoof if the executor is NOT transparent (rare).
]]
-- Services
local
game
GetService
"Players"
local
local
function
log
warn
"[Bypass]"
end
-- ===== The bypass =====
local
false
local
function
armAdonisBypass
local
typeof
or
type
-- Capability detection (defensive — every path still works if absent).
local
getType
hookfunction
"function"
local
getType
newcclosure
"function"
local
getType
"function"
local
getType
"function"
local
getType
"function"
local
getType
getrenv
"function"
local
or
and
function
local
getinfo
if
not
then
return
nil
end
return
end
-- 1) Locate the client `Detected` closure via GC.
-- The Adonis Anti table is a ReadOnly proxy whose __index returns a
-- table carrying Detected/Detectors/RLocked/AddDetector. We look for
-- any table exposing those keys; the function is the chokepoint.
local
"Detected"
"Detectors"
"RLocked"
"AddDetector"
local
function
rawHas
for
in
ipairs
do
if
rawget
nil
then
return
false
end
end
return
true
end
local
function
findDetected
if
not
then
return
nil
end
local
getgc
true
for
1
do
local
pcall
function
return
end
if
and
getType
"table"
and
rawHas
then
local
rawget
"Detected"
if
getType
"function"
then
return
end
end
if
1024
0
then
task
wait
end
-- breathe; never stall render
end
return
nil
end
-- Retry until Adonis is loaded and Detected is found.
local
nil
0
while
not
do
1
local
pcall
if
and
then
else
if
1
or
10
0
then
log
"Detected closure not found, attempt"
end
task
wait
1
end
end
-- 2) Capture the GOLDEN debug.info signature BEFORE hooking.
-- Adonis caches ("s","l","a","n","f") on startup and re-reads them
-- every ~5s; they must remain identical after the hook.
local
pcall
function
debug_info
"slan"
debug_info
"f"
end
-- 3) Neutralize `Detected` in place.
-- Arity 3, non-vararg, returns true (Adonis' liveness probe at
-- Anti.luau:425 requires the "_" action to return true).
-- hookfunction keeps closure identity + signature intact on every
-- modern executor, so the self-check and TableCheck both pass.