Key findings
- No-EXE fileless launch — Phase does not distribute a visible executable. The payload is injected into a legitimate running process (e.g., Spotify.exe). A 686 MB Spotify process memory dump was recovered containing the complete cheat payload bytes — confirming the process-hosted delivery.
- Services.msc / SCM injection chain — The loader uses Windows Service Control Manager APIs (OpenSCManagerW, OpenServiceW, QueryServiceStatus) to locate the svchost.exe instance hosting the Dnscache service, then injects evasion modules into it. This technique was confirmed through cmd/services.msc interaction during the launch process.
- 8 PE modules recovered and fully analyzed via reverse engineering (Ghidra, IDA Pro, Binary Ninja, Volatility, x64dbg).
- System process injection into svchost.exe (Dnscache), RuntimeBroker.exe, SearchIndexer.exe, SearchHost.exe, dwm.exe, and ctfmon.exe to disguise evasion modules as trusted Windows processes.
- Kernel-level domain blocking via Windows Filtering Platform at ALE_AUTH_CONNECT layer targeting anti-cheat services (napse.ac, detect.ac) with 5-minute refresh.
- Streamproof overlay with code hidden in PE header slack space, disguised as "NVIDIA GeForce RTX 5060" window, using WDA_EXCLUDEFROMCAPTURE to evade screen capture.
- 8 YARA rules and comprehensive IOC list produced for all modules.
Executive summary
Phase.uno is a multi-game cheat suite sold commercially. It consists of a loader/injector and seven support DLLs that are manually mapped into target game processes and trusted Windows system processes. The loader authenticates with C2 servers at us1.phase.uno (primary), us2.phase.uno (secondary, port 8443), with failover to restrain.ing and neglect.ing (tertiary/quaternary, port 443) — all using AES-GCM encrypted sessions. It collects hardware identifiers, scrapes Discord user IDs from local LevelDB storage, and gates payload delivery behind subscription validation.
The architecture is modular. Each component has a single purpose: one blocks anti-cheat domains at the kernel level, one hides processes from system enumeration, one provides a transparent streamproof overlay, one renders ESP/aimbot visuals via DirectX 11, one patches NVIDIA display affinity, and one carries the game-specific cheat logic with an embedded Lua 5.5 runtime. The loader orchestrates all of these, injecting them into both the target game process and trusted Windows system processes like svchost.exe and RuntimeBroker.exe.
Nine games are targeted: FiveM, Roblox, Valorant, Apex Legends, CS2, Minecraft, Escape from Tarkov, Rust, and DayZ. Five are confirmed via window-class searches in the loader binary (FiveM, Roblox, Valorant, Apex, Minecraft). Four more (CS2, Tarkov, Rust, DayZ) are confirmed via product identifiers in the C2 protocol. Game-specific payloads are fetched from the C2 at runtime and were not recoverable except for the FiveM payload, which was obtained as a separate DLL file.
Critically, Phase does not distribute a visible executable file. The payload is injected directly into the memory of a legitimate running process — in our recovered case, Spotify.exe. A 686 MB process memory dump was recovered proving this fileless hosting approach. The loader uses Windows Service Control Manager APIs to locate the svchost.exe instance hosting the Dnscache service, then cascades injection into five additional system processes. This means the cheat has zero disk footprint once loaded and its evasion modules run under the identity of trusted Windows processes.
Module inventory
Eight PE binaries were recovered and analyzed. All are x64 PE32+ binaries compiled with MSVC.
| # | Module | Size | Role |
|---|---|---|---|
| 1 | IBYPASS_main_module.exe | 3,055,616 B | Loader, auth client, manual mapper, UI shell |
| 2 | IBYPASS_fivem_module.dll | 11,943,936 B | FiveM cheat payload (aimbot, ESP, Lua runtime) |
| 3 | bp-shell_payload.dll (variant A) | 36,864 B | WFP anti-cheat domain blocker |
| 4 | bp-shell_payload.dll (variant B) | 18,432 B | WFP anti-cheat domain blocker (compact) |
| 5 | nvidia_patcher_fff.dll | 28,672 B | Reflective loader + display affinity patcher |
| 6 | procexp-hook_hxfd.dll | 32,768 B | NtQuerySystemInformation process hider |
| 7 | unknown_135k_module.dll | 135,168 B | D3D11 renderer + thread hijacker + font embed |
| 8 | unknown_24k_module.dll | 24,576 B | Transparent streamproof overlay window |
Embedded PE hierarchy
These eight files are not independent. PE-carving confirms that the larger modules physically embed copies of the smaller ones at fixed file offsets — the whole suite ships inside two carriers. The matches were verified by comparing embedded PE timestamps and section counts against the standalone binaries.
Compile timestamps
| Module | Timestamp | Linker |
|---|---|---|
| procexp-hook_hxfd.dll | 2025-12-30 | MSVC 14.44 (oldest) |
| (unidentified embedded DLL) | 2026-02-28 | — |
| nvidia_patcher_fff.dll | 2026-04-05 | MSVC 14.50 |
| unknown_135k_module.dll | 2026-04-08 | MSVC 14.50 |
| bp-shell_payload.dll | 2026-05-11 | MSVC 14.51 |
| IBYPASS_main_module.exe | 2026-05-24 | MSVC |
| unknown_24k_module.dll | 2026-06-02 | MSVC 14.0 |
| IBYPASS_fivem_module.dll | 2026-06-15 | MSVC (newest) |
The spread of timestamps (December 2025 → June 2026) and three different MSVC toolchain versions indicate the suite is assembled from independently maintained components, consistent with the multiple developer handles found in the PDB paths.
Delivery architecture
The following diagram illustrates the payload delivery chain from initial host process injection through game payload delivery. Every step was reconstructed from strings, imports, and decompiled pseudocode in the loader module.
No-EXE fileless launch
Phase does not run as a standalone .exe visible in the filesystem. Instead, the payload is loaded directly into the memory of a legitimate, already-running process. This means there is no cheat executable on disk to find — the entire payload exists only as bytes inside another process's address space.
Evidence: A 686,547,644-byte (686 MB) Spotify.exe process memory dump was recovered from a Phase user's system (file: Spotify.exe_2026-06-15_20-08-49.dmp, SHA-256: 0285239edcb14ca7bc17ece642cd30d073cb6e593da29e747fba7e61168da52a). Analysis of this dump confirmed that the complete Phase payload — loader logic, injection routines, and C2 communication — was resident inside the Spotify process memory space.
The loader itself requires admin privileges (confirmed by AllocateAndInitializeSid + CheckTokenMembership for BUILTIN\Administrators SID check in FUN_140018e90). Once elevated, it enables three token privileges: SeDebugPrivilege (for cross-process injection), SeAssignPrimaryTokenPrivilege, and SeIncreaseQuotaPrivilege (confirmed at FUN_1400451a0).
The process hosting approach means:
- No .exe file on disk for antivirus to scan
- No process with a suspicious name in Task Manager
- The cheat runs under the identity and trust level of the host process
- Memory-only — survives only while the host process is alive
- After destruct, zero filesystem artifacts remain from the payload itself
Spotify process hosting
The specific host process recovered in our analysis was Spotify.exe. Spotify is an ideal host because:
- It is always running on most gaming PCs (auto-starts with Windows)
- It is a large, complex application — a 686 MB memory footprint is normal and does not raise suspicion
- It has legitimate network activity, making C2 traffic less conspicuous
- It is a signed, trusted application that security tools rarely scrutinize
The dump file (Spotify.exe_2026-06-15_20-08-49.dmp) was captured on June 15, 2026 at 20:08:49. The timestamp and file naming convention suggest it was captured using a process memory dumping tool (likely Windows Task Manager's "Create dump file" or procdump). The payload bytes within this dump contained all the strings, imports, and code structures documented throughout this report — confirming that Spotify.exe was the active host for the Phase cheat at the time of capture.
Detection note: Look for anomalous memory regions inside Spotify.exe — specifically, executable memory pages that do not correspond to any known Spotify module. RW→RX page transitions, unbacked executable memory, and the presence of PE headers (even partially erased ones) in non-module memory are all indicators.
Services.msc injection chain
The most novel aspect of Phase's injection system is its use of the Windows Service Control Manager (SCM) to locate injection targets. The loader imports these SCM APIs from ADVAPI32.dll (confirmed in the PE import table):
- OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT) — connects to the local Service Control Manager database
- OpenServiceW(hSCManager, "Dnscache", SERVICE_QUERY_STATUS) — opens a handle to the DNS Client service
- QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, ...) — retrieves SERVICE_STATUS_PROCESS containing the PID of the svchost.exe instance hosting Dnscache
- CloseServiceHandle() — cleanup of all SCM handles
The injection flow works as follows:
services.msc launch
The user (or an automated script) opens services.msc from cmd.
SCM connection
The loader connects to the local SCM via OpenSCManagerW.
Dnscache service lookup
It opens the "Dnscache" service via OpenServiceW (confirmed by the string "dnscache" at address 0x140143900, referenced in FUN_140018bf0).
PID extraction
It queries the service status via QueryServiceStatusEx to obtain the PID of the svchost.exe instance hosting Dnscache.
Process access
With the PID identified, the loader opens the svchost.exe process via OpenProcess(0x43a) — PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ. The injection orchestrator FUN_14001adc0 calls FUN_14001ab30 to build a candidate PID list, then FUN_14004d680 for manual mapping.
bp-shell injection
It injects bp-shell (WFP domain blocker) into this svchost.exe instance.
The string "svchost.exe:Dnscache" at address 0x1401439f8 (referenced in FUN_140018e90) confirms the targeting. Because WFP filter rules created by code running inside svchost.exe appear to be legitimate Windows activity, this makes detection extremely difficult.
Why Dnscache?
The DNS Client service was deliberately chosen as the injection target because the svchost.exe instance hosting it has ideal properties:
- Always running — Dnscache is a critical Windows service that cannot be disabled without breaking DNS resolution
- Runs as NT AUTHORITY\NETWORK SERVICE — elevated privileges but not SYSTEM, reducing suspicion in process audits
- Has network access permissions — required for the WFP blocker to create and manage filtering rules
- Trusted by security tools — most EDR solutions and anti-cheat systems whitelist svchost.exe processes, especially those hosting known Windows services
Post-PID injection orchestration
After obtaining the svchost PID, execution flows to FUN_14001adc0 which orchestrates the actual injection:
- Calls FUN_14001ab30 to build a candidate target PID list
- For each candidate: OpenProcess(0x43a) — access mask 0x43a = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
- Calls FUN_14004d680 for manual mapping of the bp-shell payload into the target process
- On success, logs "success: injected into pid %u"
After the Dnscache svchost injection, the loader cascades into additional system processes using CreateToolhelp32Snapshot + Process32FirstW/NextW enumeration:
| System process target | Child process names |
|---|---|
| RuntimeBroker.exe | main.cpl, node.exe, python.exe |
| SearchIndexer.exe | main.cpl, node.exe, python.exe |
| SearchHost.exe | main.cpl, node.exe, python.exe |
| dwm.exe | main.cpl, node.exe, python.exe |
| ctfmon.exe | main.cpl, node.exe, python.exe |
Authentication & HWID collection
The loader collects three hardware identifiers before contacting the C2 server:
Disk serial number
Retrieved via DeviceIoControl with IOCTL control code 0x2D1400 (IOCTL_STORAGE_QUERY_PROPERTY). Provides a unique physical disk identifier.
SMBIOS firmware table
Retrieved via GetSystemFirmwareTable with signature 'RSMB'. Contains motherboard serial, manufacturer, and BIOS information from the system firmware.
GPU identifier
Enumerated through EnumDisplayDevices and the DXGI interface (CreateDXGIFactory import confirmed). Provides GPU model and driver information.
Additionally, the loader reads registry keys for system fingerprinting: SOFTWARE\Microsoft\Windows NT\CurrentVersion (for CurrentBuild, SystemProductName) and HARDWARE\DESCRIPTION\System\CentralProcessor\0 (for ProcessorNameString). An external IP check is performed via api.ipify.org.
C2 protocol
The composite HWID and collected identifiers are sent to the C2 server. Confirmed endpoints:
| Endpoint | Purpose |
|---|---|
| /auth/v1 | PIN + HWID + Discord ID authentication |
| /download/v1 | Encrypted payload download (game-specific) |
| /config/list | Dynamic WFP blocklist + configuration |
| /telemetry/v1 | Telemetry / event reporting |
| /config/delete | Config cleanup on destruct |
| /config/import | Config import |
| /config/save | Config save |
| /config/share | Config sharing |
| /config/load | Config load |
| /product/heartbeat | Session keepalive |
| /product/system_info | System info telemetry |
| /online/players?api_key= | Online player count |
| /handshake | Session key exchange (AES-GCM) |
Confirmed JSON fields (from string analysis): pin, hwid, found_discord_ids, session_token, download_token, encrypted_data, encrypted_key, nonce, tag, session_expires_at, hardware_id, banned, online_count, detection_type, protection_trigger.
The User-Agent string is spoofed as Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0 to blend with normal browser traffic.
The handshake uses a hardcoded 256-bit server public key: Zbgn8Nv7fN8DPJko4ka1jQomMsJcco4SZv3TRU8N7+k= (base64, decodes to 32 bytes). The auth response returns a subscription model with fields: products, subscriptions (with product, expires_at, is_active), api_key, and online_count.
All C2 communication is encrypted with AES-GCM via the Windows bcrypt library. Imports confirmed: BCryptOpenAlgorithmProvider, BCryptGenerateSymmetricKey, BCryptEncrypt, BCryptDecrypt, BCryptDeriveKeyPBKDF2 with ChainingModeGCM string present in the binary.
Discord telemetry
The loader scans local Discord LevelDB storage directories to extract user IDs. Three paths are checked: \Discord, \discordcanary, \discordptb. C++ symbols confirm the implementation: get_discord_ids@discord_id_extractor and scan_leveldb_directory@discord_id_extractor. Extracted IDs are sent to the C2 and also to a hardcoded Discord webhook for telemetry/logging: discord.com/api/webhooks/1506075252847808543/YVB5hF6Pd396CjG1zRpHZicbxD0UcB2KsKJQOINI70fPPiudcPWToXzyrlido7NLdA2f.
System process injection
One of the most significant findings in our analysis: the loader does not only inject into game processes. It injects evasion modules into trusted Windows system processes to disguise their activity.
In the decompiled function FUN_140018e90 (7,323 bytes), the loader first verifies it has administrator privileges via AllocateAndInitializeSid + CheckTokenMembership. It then escalates privileges via FUN_1400181f0 which enables three token privileges using LookupPrivilegeValueW + AdjustTokenPrivileges:
- SeDebugPrivilege — allows opening any process regardless of DACL (confirmed at address 0x143858)
- SeAssignPrimaryTokenPrivilege — allows assigning tokens to child processes for masquerading
- SeIncreaseQuotaPrivilege — allows increasing process memory quotas for injection
After privilege escalation, it builds arrays of target system process names:
The string "svchost.exe:Dnscache" at address 0x1401439f8 is referenced by FUN_140018e90. The companion string "dnscache" at 0x140143900 is referenced by the related function FUN_140018bf0. Nearby in the same code path: "success: injected into pid %u" and "pid %u: OpenProcess err=%lu".
The loader requires SeDebugPrivilege (string confirmed at 0x143858) to inject into system-level processes.
Manual mapping & thread context hijacking
The loader uses NT-native manual mapping for payload injection. The confirmed API chain (from both imports and debug strings):
Debug strings from the manual mapper confirm the entire sequence:
[map] section mapped: local=%p remote=%p size=0x%zx [map] remote NtMapViewOfSection failed: 0x%08lx [map] DLL has no entry point [map] trampoline %zu bytes at remote=%p (entry=%p, raft=%p, pdata=%p x %u) [map] entry returned exit_code=0x%08lx (image base=%p) [map] real module %ls not present in target after load attempt
The thread context hijacking in unknown_135k_module.dll provides an alternative injection path that avoids creating new threads. It writes 5-byte near JMP instructions into allocated memory and uses VirtualAlloc + VirtualProtect to set up executable shellcode regions.
Post-injection stealth
After injection completes, the loader performs a multi-phase cleanup of injection artifacts in the target process memory:
[stealth] phase 1: starting post-init stealth (wipe=%d erase=%d) [stealth] PE headers erased @%p size=0x%zx [stealth] wiped discardable %.8s @%p size=0x%zx [stealth] discardable wipe done (%u sections) [stealth] header erase ro failed: 0x%08lx [stealth] header erase rw failed: 0x%08lx [stealth] phase 1: header erase failed (continuing) [stealth] phase 2: TLS callback collection failed (continuing)
This means: the MZ/PE headers are zeroed out in the remotely-mapped module, and PE sections marked as discardable are wiped. Memory scanners looking for PE signatures will not find the injected module. The TLS callback surface is also collected as part of the stealth pass.
The loader also manipulates registry key metadata using NtSetInformationKey with restore semantics. The strings "restore: RegOpenKeyExW(%s, KEY_ALL_ACCESS) FAILED" and "restore: NtSetInformationKey(%s) -> NTSTATUS=0x%08lX" suggest manipulation of registry key last-write timestamps to hide evidence of cheat-related registry activity.
WFP domain blocker (bp-shell)
bp-shell is the network evasion component. It installs Windows Filtering Platform block filters so the infected machine cannot reach anti-cheat service domains. Because it runs inside a trusted system process (injected via the system-process injection described above), the WFP filters appear to be created by legitimate Windows services.
This is a debug build. Every action logs a [bp-shell] prefixed message. The module requires admin elevation ("(needs admin)" string). On shutdown, it cleanly tears down all filters via FwpmFilterDeleteById0, closes the WFP engine, and calls WSACleanup.
The imports are minimal and single-purpose: fwpuclnt.dll for WFP operations, WS2_32.dll for DNS resolution, and KERNEL32.dll for threading/lifecycle. No file, registry, or process-manipulation imports.
The blocklist is only a fallback. The loader fetches additional domains from https://us1.phase.uno/config/list at runtime, meaning new anti-cheat services can be blocked without updating the binary.
Process hiding (procexp-hook)
This module hooks NtQuerySystemInformation in ntdll.dll to filter cheat-related processes from any tool that enumerates running processes (Task Manager, Process Hacker, Process Explorer, etc.).
The hook is installed 3 seconds after DLL load (Sleep(3000) in DllMain). The API is resolved dynamically: GetModuleHandleW(L"ntdll.dll") → GetProcAddress("NtQuerySystemInformation"). After patching, FlushInstructionCache ensures the CPU executes the new bytes.
Filter target names in strings: notepad.exe and chrome.exe (UTF-16). These are likely development placeholders or the disguise names given to cheat processes.
This module was recovered as a memory dump artifact, not an on-disk binary. PDB path: C:\Users\hxfd\source\repos\procexp-hook\x64\Release\procexp-hook.pdb. Compile timestamp: 2025-12-30.
Streamproof overlay (unknown_24k_module)
This module creates the transparent overlay window where ESP, aimbot indicators, and other visuals are drawn. It has two remarkable structural properties:
- Code hidden in PE header slack space. 3,512 bytes of slack between offset 0x248 and 0x1000, of which 2,458 bytes (70%) are non-zero executable x64 code — 384 code pattern matches, the highest density of any Phase binary. Functions include DllMain at 0x180000400, WndProc at 0x180000960, UpdateWindow at 0x180000B10, TimerHandler at 0x180000C50. Standard PE analysis tools examining only defined sections will miss this code entirely.
- Cannot be loaded with LoadLibrary. Requires a reflective or custom loader because the code falls outside standard section boundaries.
- Memory dump artifact. The .rdata section contains runtime-resolved addresses in the 0x00007FF8... range — this binary was dumped from a running process, not extracted from disk. It has no .reloc section, no debug directory, no exports.
- Only 5 PE sections (.text, .rdata, .data, .pdata, .rsrc) — the most minimal PE structure in the Phase suite.
The overlay window setup chain:
- Window class name: "NVIDIA GeForce RTX 5060" — disguised as an NVIDIA driver overlay.
- CreateWindowExW with layered/transparent extended styles.
- SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE) — invisible to all screen capture, streaming software, and Discord screenshare.
- DwmExtendFrameIntoClientArea for click-through glass composition.
- SetLayeredWindowAttributes for transparency control.
- SetWindowPos for TOPMOST positioning.
Shared memory IPC
The overlay receives drawing data from the game payload via a named memory-mapped file: Local\wisrc. The name is constructed character by character in assembly using movabs instructions. Size: 12,400 bytes (0x3070). Magic value at offset 0: "NAIL" (0x4C41494E). Created via CreateFileMappingA + MapViewOfFile.
D3D11 renderer (unknown_135k_module)
The rendering engine for ESP/aimbot visuals. At 135 KB with 7 PE sections and 18,325 disassembly lines, this is the most complex auxiliary module.
PE structure anomalies
- Header slack code: 3,288 bytes of slack between offset 0x328 and 0x1000, of which 2,716 bytes (82.6%) contain executable x64 code — 320 code pattern matches. The main initialization routine lives here, including a polling loop (300 iterations, 100 ms sleep), NtOpenThread/ NtCreateThreadEx patterns, and atomic lock acquisition.
- Deliberately corrupted import table. OriginalFirstThunk is set to 0xFFFFFFFF — any standard PE parser will fail or crash on this module. Relocation table is also garbled (VA 0x666D7563 = ASCII "cumf", claims 985M fixups).
- Custom PE section .fptable at offset 0x1E000 — 256 bytes of active content (RW). Contains a table of 16-bit signed relative offsets (values like 0x93FE, 0x88FE, 0x8FFE) used as a function dispatch table into .text. Same naming convention as the FiveM payload — confirms shared toolchain.
- High-entropy .rsrc — entropy 7.03 for a resource section is abnormal and suggests the resource data contains compressed or encrypted payloads.
Inline hooking engine
The core hooking function at 0x1800015A0 implements a full inline hook framework:
- Writes a 0xE9 (JMP rel32) trampoline to the target function
- Calculates relative offset from hook to detour
- Writes hotpatch bytes 0xEB 0xF9 (short JMP back) for Microsoft-style hotpatching
- VirtualProtect → PAGE_EXECUTE_READWRITE (0x40) → FlushInstructionCache
- Hook metadata structures: 0x38 bytes each, thread-safe via spinlock ( lock cmpxchg at 0x18001AC38)
Rendering capabilities
- Imports D3D11CreateDevice from d3d11.dll — creates its own rendering device rather than hooking the game's Present call.
- COM/DirectX vtable calls through interface pointer at 0x18001AC18 with vtable offsets +0x20, +0x40, +0x48, +0x50, +0x1A8.
- 167 indirect call/jmp instructions — heavily concentrated through IAT at 0x18000F400-0x18000F6F0.
- Private heap via HeapCreate / HeapAlloc / HeapFree / HeapDestroy for isolated memory management.
- Embeds a complete Cascadia Mono PL Regular font (Microsoft OpenType/CFF, OFL-licensed) in the .pdata section for ESP text rendering.
- References amfrtdrv64.dll (AMD AMF Runtime) and mscoree.dll (CorExitProcess) — GPU compatibility across vendors.
Suspicious LEA instructions
Two LEA instructions reference 0x17FFFF400 — below the image base 0x180000000:
0x1800031D4: lea -0x3ddb(%rip),%rdx → 0x17FFFF400 0x180002356: lea -0x2f5d(%rip),%rbx → 0x17FFFF400
These out-of-bounds references suggest the module expects to be mapped at a specific address with preceding memory already allocated — consistent with the reflective loader mapping multiple modules contiguously.
NVIDIA patcher (reflective loader)
This module contains two stacked PE binaries: an outer 28 KB stub (entry at 0x180001444) and an embedded 135 KB inner PE at file offset 0x2610 (entry at 0x180003A44, 7 sections including .fptable, SizeOfImage: 0x21000 = 135,168 bytes). The inner PE is a truncated copy of unknown_135k_module.dll — same timestamp (2026-04-08), same 7 sections, but only 18,928 bytes of data exist past the header. The full binary is loaded separately at runtime; these headers serve as parsing metadata.
PE header slack code
3,344 bytes of slack between offset 0x2F0 and 0x1000, of which 2,574 bytes (77%) contain executable x64 code — 213 code pattern matches. The header code contains full DllMain-style dispatch logic with LoadLibrary/ GetProcAddress calls and pipe I/O operations.
Anti-tamper and obfuscation
- Import table obfuscated — DLL name field is 0x7865742E = ".tex" instead of a real DLL name. Standard PE import parsing fails.
- Only ~375 bytes of actual code in .text (0x180001000-0x180001177). The rest of the operational logic is hidden in header slack and .data.
- CFG dispatch at 0x180001044 with XOR %rax,%rdx anti-tampering check.
- Exception filter at 0x180001160 catches STATUS_ACCESS_VIOLATION (0xC0000005) — intentional exception-based control flow.
- .data section (0x180003000-0x180003120) contains executable code stored in a non-executable section — executed via RWX reprotection at runtime.
- All metadata sections corrupted — .pdata, .rsrc, .reloc, debug directory entries all have invalid values (types 808333607, 980316789, 863383149).
It dynamically resolves GetWindowDisplayAffinity from user32.dll, connecting it to the overlay's stream-proofing system. Both PEs have zeroed checksums. Outer subsystem: console; inner subsystem: GUI.
PDB path: C:\Users\fff\Desktop\Senata\nvidia\x64\Release\patcher.pdb. Same developer username (fff) as bp-shell. MSVC 14.50 (Visual Studio 2022+).
FiveM payload deep-dive
The FiveM payload is the only game-specific DLL recovered (11.9 MB). It has custom PE sections: .hookstu (hook stubs), .retplne (return plane trampolines), .fptable (function pointer table), .tls (TLS callbacks).
Installed hooks
Anti-cheat event suppression
Five FiveM anti-cheat events are hooked and suppressed:
- anticheat:weaponViolation
- anticheat:pedModelViolation
- anticheat:noclipViolation
- anticheat:protectionViolation
- anticheat:bubbleViolation
By intercepting these events, Phase prevents violation reports from reaching the server. It also hooks txsv:logger:deathEvent for death event logging suppression. The payload references three FiveM native DLLs directly: citizen-playernames-five.dll, citizen-resources-core.dll, citizen-scripting-core.dll.
Full feature surface
Config keys recovered from strings reveal the complete cheat capability set:
| Category | Capabilities |
|---|---|
| Aimbot | Target priority, smoothing (X/Y), FOV, deadzone, dynamic smoothing, prediction, jitter, reaction time, visible check, weapon range respect, hitbox override, maximum distance, magic bullet |
| Silent Aim | Separate FOV/hitbox/target priority, visible check, hit chance, weapon range respect, maximum distance |
| Triggerbot | Hitbox targeting, mode selection, reaction time, time between shots |
| RCS/Recoil | Recoil control system with adjustable strength |
| Fake Lag | Configurable delay (ms) for desync exploitation |
| Double Tap | Probability-based double-tap with chance modifier |
| ESP/Visuals | Skeleton, name, weapon, weapon icon, distance, armor bar, health bar, level, fraction, static ID, vehicle box/marker/speed/name |
| World | Remove shadows, sky, water; modify clouds, moon, sun, weather |
| Chams | Mesh chams, shader/texture hook (ped_shader_tex_hook) |
| Vehicle | Spawner, velocity manipulation, wheel break, model info flags |
| Ped/Player | Model changer, config flags, reset flags, state manipulation |
| Weapon | Equip/give weapon, melee damage modifier, recoil hook |
| Misc | Streamproof toggle, auto-inject, spectator list, custom resolution, keybind system, radar with player rotation |
| Teleport | Teleport peek with draw circle visualization |
| Anti-headshot | Passive protection against headshots |
Embedded Lua 5.5 runtime
The payload includes a full Lua 5.5 runtime. Confirmed strings: $LuaVersion: Lua 5.5.0, [LUA] calling luaL_loadbuffer, [LUA] calling lua_pcall, [LUA] runtime error detected. Since FiveM runs on Lua, this enables arbitrary script execution inside the game engine.
Recovered config (tonio_config)
30°
Aimbot FOV
500
Aimbot max distance (units)
65 / 50
Smoothing X / Y
2° / 100%
Silent aim FOV / hit chance
100 ms
Fake lag delay
2560×1440
Resolution
Enabled features: aimbot, prediction, fake lag, silent aim, ESP (skeleton, name, weapon, distance, armor bar).
Anti-analysis inventory
The loader scans for 200+ security and analysis tools via window class enumeration, process name matching, named object checks, device driver probes, mutex detection, service enumeration, loaded module scanning, and directory path scanning. It also verifies 16 critical Windows API functions have not been hooked by security tools, using XOR-obfuscated API name resolution (keys 0xa879ddeddcaecfb5, 0x46802f2cec801086). Every string below was recovered directly from the binary.
Verified string / payload encryption scheme
Disassembly of IBYPASS_main_module.exe confirms the two keys are not a guess: key 1 appears as a movabs immediate 25 times and key 2 17 times, loaded into registers and pushed onto the stack as a contiguous 16-byte block {key1, key2}. Decryption is then performed with 128-bit SIMD — movdqa loads the key block and xorps / vpxor XORs it against the ciphertext (a 256-bit vmovdqu / vpxor variant handles 32-byte blocks). The encrypted data is stored as 44 distinct key-1 variants and 12 key-2 variants where only the low bytes differ per string.
The decrypted blobs are guarded by an integrity hash at 0x1400158a0: seed 0x12345678, ROR 31 + XOR per byte, multiplied by 0x61c88647 (the golden-ratio Fibonacci-hashing constant), compared against a stored hash at 0x1402da228. A separate MurmurHash3-style routine at 0x1400e6f40 (round constants 0x239b961b, 0xab0e9789, 0x38b34ae5, 0xa1e38b93) is used for fast table lookups.
Independent disassembly of the auxiliary DLLs (bp-shell, nvidia_patcher, procexp-hook) confirms neither key is present in any of them in either byte order — the XOR obfuscation scheme is unique to the main loader. The only notable constant shared across those modules is 0x2B992DDFA232, which is the default MSVC __security_cookie sentinel — a standard compiler artifact, not a Phase marker, and deliberately excluded from our detection signatures to avoid false positives.
Anti-VM CPUID vendor check
bp-shell, procexp-hook, and nvidia_patcher each contain the same three XOR-immediate instructions that reconstruct the string GenuineIntel (0x6c65746e "ntel", 0x49656e69 "ineI", 0x756e6547 "Genu") for comparison against the CPUID vendor leaf — a lightweight virtual-machine / sandbox detection check performed before the payload runs.
Process names scanned
Window titles & class names checked
Named objects, device drivers & mutexes
Hooking frameworks detected
Directory paths scanned
The string pediy06 (a Chinese reverse engineering forum handle) is also checked, suggesting the developers monitor for specific researchers.
Native anti-debug APIs used: IsDebuggerPresent, CheckRemoteDebuggerPresent, NtQueryInformationProcess, NtRemoveProcessDebug, NtCreateDebugObject, NtSystemDebugControl, NtSetInformationDebugObject, ZwSetInformationThread.
Named objects checked include \\.\KProcessHacker, \\.\INTRUD3R, ProcessHackerMutant, ScyllaDumpMutex, and YOURPROJECTNAMECEMUTEX (Cheat Engine).
Cleanup & destruct
Phase has a multi-layered cleanup system designed to leave zero traces after the user hits destruct. When a user clicks destruct, files will not remain on the PC. The cleanup operates across eight distinct layers:
Layer 1: In-memory stealth (loader)
Immediately after injection completes, the loader erases evidence of injected modules from the target process memory:
[stealth] phase 1: starting post-init stealth (wipe=%d erase=%d) [stealth] PE headers erased @%p size=0x%zx [stealth] WriteProcessMemory zero @%p size=0x%zx failed: %lu [stealth] wiped discardable %.8s @%p size=0x%zx [stealth] discardable wipe done (%u sections) [stealth] discardable noaccess failed %.8s: 0x%08lx [stealth] discardable rw failed %.8s: 0x%08lx [stealth] header erase ro failed: 0x%08lx [stealth] header erase rw failed: 0x%08lx [stealth] phase 1: header erase failed (continuing) [stealth] phase 1: post-init stealth complete [stealth] phase 2: TLS callback collection failed (continuing) [stealth] phase 2: emitting %zu TLS callback(s) unmapping image, no stealth applied
- Phase 1 — PE header zeroing — uses WriteProcessMemory to zero-fill the MZ/PE header region of remotely mapped modules via NtProtectVirtualMemory (RO → RW → zero-fill → restore). Memory scanners looking for PE signatures will not find the injected module.
- Phase 1 — Discardable section wipe — iterates PE sections marked IMAGE_SCN_MEM_DISCARDABLE, changes protection to RW, zero-fills them, then sets to NOACCESS. Each section is logged by name and address.
- Phase 2 — TLS callback collection — collects and processes TLS callbacks to avoid leaving dangling references. The phase emits a count of processed callbacks.
- Unmapping fallback — if stealth is not applied, the image is unmapped entirely via NtUnmapViewOfSection.
Layer 2: WFP filter teardown (bp-shell)
This is the layer the user specifically asked about. Our deep analysis of bp-shell (both variants, embedded at DAT_14013d400 in the main loader) confirms a complete WFP cleanup on DLL_PROCESS_DETACH. Every filter created during the session is removed — nothing survives in the WFP rule set.
1. SetEvent(shutdownEvent @ 0x180005248) → wakes worker thread from 300s WaitForSingleObject 2. WaitForSingleObject(workerThread @ 0x180005240, 0xBB8 = 3000 ms) → waits up to 3 seconds for graceful thread exit 3. FwpmFilterDeleteById0 (FUN_18000126f, 66 bytes) → iterates std::vector<UINT64> of filter IDs → vector at globals 0x180005228–0x180005230 → mutex-guarded (_Mtx_lock / _Mtx_unlock) → EVERY filter deleted: hardcoded + dynamic domains 4. FwpmEngineClose0 (FUN_1800018a5, 83 bytes) → releases WFP engine handle 5. WSACleanup (FUN_1800018a5) → tears down Winsock (getaddrinfo resolver) 6. CloseHandle(workerThread) + null globals → zeroes thread handle @ 0x180005240 → zeroes event handle @ 0x180005248
- Complete filter deletion — filters from both hardcoded domains (napse.ac, detect.ac) and dynamic domains fetched from /config/list are stored in the same std::vector<UINT64> and all get deleted. Nothing survives in the WFP rule set.
- Graceful shutdown — the shutdown event (manual-reset, at 0x180005248) wakes the 300-second refresh loop. The 3-second wait ensures the worker thread exits cleanly before filter deletion begins.
- Thread-safe access — the filter-id vector is guarded by _Mtx_lock / _Mtx_unlock wrappers (FUN_180001220 / FUN_1800012b1) during both add and delete operations.
- Post-teardown state — after cleanup, netsh wfp show filters will show no Phase-related rules. However, Windows Security Event Log may retain records of filter creation/deletion (Event IDs 5157, 5152) since Phase does not clear event logs.
- Crash edge case — if the host process crashes or the DLL is forcibly unloaded without hitting PROCESS_DETACH, filters remain orphaned in the kernel's BFE (Base Filtering Engine) until reboot or manual removal. This is the only scenario where WFP artifacts persist.
Layer 3: NtQuerySystemInformation hook removal (procexp-hook)
The hook handler at 0x180000400 performs a 4-step VirtualProtect cycle on every call to avoid detection:
- Per-call temporary removal — VirtualProtect(NtQSI, 0x20, PAGE_EXECUTE_READWRITE) → copy saved 32 bytes back → restore protection → FlushInstructionCache → call original → re-install 12-byte trampoline → VirtualProtect → FlushInstructionCache. Four VirtualProtect calls + two FlushInstructionCache calls per hook invocation.
- Installation (DllMain at 0x180000610) — 3-second Sleep(3000) evasion delay, then copies first 0x20 bytes of NtQSI to a saved buffer, patches with 12-byte MOV RAX / JMP RAX trampoline, sets atomic "installed" flag via xchg.
- No permanent DllMain unhook — the report found no DLL_PROCESS_DETACH handler that removes the hook. It remains installed for the lifetime of the host process, but disappears when the process exits.
Layer 4: File and registry cleanup (FiveM payload)
- DeleteFileW — deletes cheat-related files from disk (temp files, config, dumped resources)
- RegDeleteValueW — deletes registry values (confirmed: "registry value deleted successfully", "failed to delete registry value, error code: %ld")
- FlushFileBuffers — ensures all pending writes are flushed before deletion
- Temp path cleanup: GetTempPathW / GetTempPath2W used for temp file management and deletion
- Shellcode memory cleanup: "cleaning up shellcode mem" — frees injection shellcode via NtFreeVirtualMemory after handoff. Full lifecycle strings: "allocating shellcode" → "writing shellcode" → "shellcode done, h_mod: %p" → "cleaning up shellcode mem"
- Crypto key destruction: BCryptDestroyKey + BCryptCloseAlgorithmProvider — destroys AES-GCM key material after use
- Thread sync cleanup: DeleteCriticalSection — destroys critical sections used for inter-thread synchronization
- Resource dump/delete UI with full user-facing destruct flow: "All those beautiful files will be deleted.", "Delete all", "Remove all", "Delete %d item(s)###DeleteSelected"
Layer 5: Registry timestamp manipulation and server-side wipe (loader)
The function at FUN_140024a90 (524 bytes) dynamically resolves NtSetInformationKey from ntdll.dll and overwrites registry key LastWriteTime values. It is called from the orchestrator at FUN_140024ca0 (4,230 bytes) which creates keys, writes values, then restores the timestamp to hide modifications.
- NtSetInformationKey(hKey, KeyWriteTimeInformation=0, &fileTime, 8) — opens keys under HKEY_LOCAL_MACHINE with KEY_ALL_ACCESS (0xF013F), queries original timestamp first via RegQueryInfoKeyW, modifies values, then writes back the original FILETIME. Converted to local time via FileTimeToLocalFileTime + FileTimeToSystemTime for logging. Registry paths include shell command associations built from obfuscated hex constants at runtime.
- Server-side config wipe via /config/delete endpoint (UTF-16LE string at 0x00910ffa in FiveM module) — tells the C2 server to delete the user's stored configuration and session data
- identifier removed — HWID/subscription deregistration + ##logout session teardown
Layer 6: Overlay and shared memory cleanup (unknown_24k)
- UnmapViewOfFile (at 0x1800004E7) — unmaps the shared memory view Local\wisrc (12,400 bytes) when a shared-instance handover occurs or on shutdown
- CloseHandle (at 0x1800004FF) — closes the file mapping handle, then nulls both global pointers (g_pSharedMem = 0, g_hMapping = 0)
- Shared memory is zero-filled at initialization using SSE movups loop (0x3060 bytes cleared) with mfence memory barrier at 0x1800008BC for cross-thread visibility
- Overlay window continuously re-applies SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE) on every WM_TIMER tick (~16ms / 60 FPS) — even if an anti-cheat removes the flag, it is immediately reapplied
Layer 7: Debug detachment (loader)
Function FUN_140015a50 performs a complete anti-debug cleanup sequence:
- CheckRemoteDebuggerPresent — exits immediately if a debugger is detected
- NtQueryInformationProcess (ProcessDebugPort=7, ProcessDebugFlags=0x1f) — checks for debug port attachment
- Debug detachment chain: NtSetInformationDebugObject → NtRemoveProcessDebug → NtClose — modifies, detaches, and destroys the debug object
- ZwSetInformationThread(ThreadHideFromDebugger=0x12) — hides the current thread from debugger notifications
- Checks for vehdebug-x86_64.dll module presence as anti-debug measure
Layer 8: Connection and handle cleanup (loader + FiveM)
- BCryptDestroyKey + BCryptCloseAlgorithmProvider — destroys AES-GCM encryption key material
- WinHttpCloseHandle (5 calls in telemetry function FUN_140012980) — closes HTTP session, connection, and request handles
- CloseServiceHandle — closes SCM handles after svchost.exe:Dnscache PID discovery
- FreeSid — frees the SID allocated for BUILTIN\Administrators check
- NtUnmapViewOfSection — unmaps the injected section views from the local process after remote mapping completes
What Phase does NOT clean (detection survives)
Our analysis confirmed that Phase does not wipe broad system forensic artifacts. There are no imports or strings for Event Log clearing, Prefetch deletion, USN Journal manipulation, browser history wiping, RecentDocs cleanup, or ShimCache/Amcache tampering. This means the following survive destruct and can be used for detection:
- DNS resolver cache — bp-shell re-resolves napse.ac and detect.ac every 5 minutes. These entries persist in ipconfig /displaydns
- Prefetch files — Windows Prefetch will record execution artifacts if the loader was ever present as a visible process before injection
- Amcache / ShimCache — Application compatibility cache entries survive and record execution timestamps
- NTFS USN Journal — file creation/deletion events for any temporary files written by the FiveM payload will persist in the journal
- Registry deleted value remnants — deleted registry values leave remnants in unallocated hive space recoverable with tools like Registry Explorer or yaru
- Registry timestamp anomalies — while Phase manipulates timestamps with NtSetInformationKey, the restored timestamps may not match surrounding key patterns, creating forensic anomalies
- WFP audit events — despite bp-shell's complete filter cleanup, Windows Security Event Log may retain records: Event ID 5157 (WFP blocked a connection), Event ID 5152 (WFP dropped a packet), Event ID 5031 (WFP blocked application). These are written to the log in real-time during operation and Phase does not clear event logs. Audit policy must be enabled to capture these.
- Network connection logs — firewall logs, router logs, and ISP records of connections to us1.phase.uno / us2.phase.uno are outside the cheat's reach
- Discord LevelDB access timestamps — file access timestamps on Discord's LevelDB directories may show anomalous reads from a non-Discord process
- Process memory dump artifacts — if a dump was taken while the cheat was active (as in our recovered 686 MB Spotify dump), the full payload is preserved
Detection guidance for PC checkers
The following detection opportunities are available. Items marked (live only) require catching the cheat while active.
WFP filter audit (live only)
Run 'netsh wfp show filters'. Look for filter rules named 'bp-shell block v4' or 'bp-shell block v6' blocking IPs associated with anti-cheat domains (napse.ac, detect.ac). These appear to come from svchost.exe due to system process injection. Note: Phase performs complete WFP cleanup on exit (FwpmFilterDeleteById0 for all stored filter IDs), so these filters only exist while the cheat is active.
NtQuerySystemInformation hook check (live only)
Examine the first 12 bytes of NtQuerySystemInformation in ntdll.dll. A MOV RAX / JMP RAX trampoline (48 B8 xx xx xx xx xx xx xx xx FF E0) indicates an inline hook.
Shared memory object (live only)
Look for a named memory-mapped file 'Local\wisrc' — 12,400 bytes with magic bytes 'NAIL' (0x4C41494E) at offset 0. This is the overlay's IPC channel.
Window class inspection (live only)
A window with class name 'NVIDIA GeForce RTX 5060' that has WDA_EXCLUDEFROMCAPTURE display affinity and is NOT created by a genuine NVIDIA process. Use EnumWindows + GetClassName + GetWindowDisplayAffinity.
DNS cache residue
Run 'ipconfig /displaydns'. Bp-shell re-resolves napse.ac and detect.ac every 5 minutes. These lookups persist in the DNS resolver cache even after destruct.
System process module audit (live only)
Inspect loaded modules in svchost.exe, RuntimeBroker.exe, SearchIndexer.exe, SearchHost.exe, dwm.exe, and ctfmon.exe. Unknown DLLs or suspicious memory regions in these processes indicate injection.
PE structure anomalies
Look for modules with OriginalFirstThunk set to 0xFFFFFFFF (corrupted import table), executable code in PE header slack space (before first section), or custom sections named .hookstu, .retplne, .fptable.
PDB path artifacts
Search for PDB paths containing '\fff\', '\hxfd\', or project names: phase-shellcodes, procexp-hook, Senata. These are developer artifacts baked into the binaries.
Registry forensics
Phase uses NtSetInformationKey to manipulate timestamps and RegDeleteValueW to clean up. Deleted value remnants in unallocated hive space and last-write timestamp anomalies can survive cleanup. Use Registry Explorer or yaru for recovery.
Network connections
Check for connections to us1.phase.uno, us2.phase.uno, restrain.ing, neglect.ing, or API endpoints /auth/v1, /download/v1, /config/list, /telemetry/v1, /config/delete. Secondary C2 uses port 8443.
Spotify/host process memory analysis
Dump the memory of Spotify.exe (or other suspected host processes) and scan for Phase artifacts: strings containing 'us1.phase.uno', 'bp-shell', 'SeDebugPrivilege', PE headers in non-module memory regions, or the shared memory name 'Local\wisrc'. A Phase-infected Spotify process will have a significantly larger working set than normal.
YARA rules
Eight detection rules were produced from our analysis, incorporating strings and patterns from all eight modules. The first six detect live modules (on disk, in memory dumps, or in process memory). The last two detect post-destruct artifacts — traces that survive Phase's cleanup. These rules are designed to detect what's actually left behind.
rule Phase_Loader {
meta:
description = "Phase.uno cheat loader"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$s1 = "[map] section mapped: local=%p remote=%p size=0x%zx" ascii
$s2 = "[stealth] phase 1: header erase failed (continuing)" ascii
$s3 = "[bp-shell] WFP engine opened" ascii
$s4 = "session_token missing from /handshake response" ascii
$s5 = "success: injected into pid %u" ascii
$s6 = "svchost.exe:Dnscache" wide
$c2a = "us1.phase.uno" ascii wide
$c2b = "restrain.ing" ascii wide
$c2c = "neglect.ing" ascii wide
$g1 = "grcWindow" ascii wide
$g2 = "Respawn001" ascii wide
condition:
(uint16(0) == 0x5A4D or uint16(0) == 0x444D) and
(2 of ($s*) or (any of ($c2*) and any of ($g*)))
}rule Phase_FiveM_Payload {
meta:
description = "Phase.uno FiveM cheat payload"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$hook1 = "aimbot_input_hook" ascii
$hook2 = "c_event_gun_shot_hook" ascii
$hook3 = "player_sector_pos_data_node_hook" ascii
$hook4 = "player_appearance_data_node_hook" ascii
$ac1 = "anticheat:weaponViolation" ascii
$ac2 = "anticheat:pedModelViolation" ascii
$sec1 = ".hookstu" ascii
$sec2 = ".retplne" ascii
$sec3 = ".fptable" ascii
$clean = "cleaning up shellcode mem" ascii
$dest = "All those beautiful files will be deleted." ascii
condition:
uint16(0) == 0x5A4D and
(3 of ($hook*) or all of ($ac*) or 2 of ($sec*) or ($clean and $dest))
}rule Phase_BPShell_WFP {
meta:
description = "Phase.uno WFP anti-cheat domain blocker"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$s1 = "[bp-shell] WFP engine opened" ascii
$s2 = "napse.ac" ascii wide
$s3 = "detect.ac" ascii wide
$s4 = "fwpuclnt.dll" ascii wide
$pdb = "phase-shellcodes" ascii
condition:
uint16(0) == 0x5A4D and 2 of them
}rule Phase_ProcExpHook {
meta:
description = "Phase.uno NtQuerySystemInformation process hider"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$pdb = "procexp-hook" ascii
$api = "NtQuerySystemInformation" ascii
$ntdll = "ntdll.dll" ascii wide
$tramp = { 48 B8 ?? ?? ?? ?? ?? ?? ?? ?? FF E0 }
condition:
uint16(0) == 0x5A4D and ($pdb or ($api and $tramp))
}rule Phase_Overlay {
meta:
description = "Phase.uno transparent overlay module"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$api1 = "SetWindowDisplayAffinity" ascii
$api2 = "DwmExtendFrameIntoClientArea" ascii
$api3 = "CreateFileMappingA" ascii
$shm = "Local\\wisrc" ascii
$nail = { 4E 41 49 4C }
condition:
(uint16(0) == 0x5A4D or uint16(0) == 0x0000) and
($shm or ($nail and 2 of ($api*)))
}rule Phase_NvidiaPatcher {
meta:
description = "Phase.uno NVIDIA display affinity patcher"
author = "Clubhouse AC Research"
date = "2026-06-19"
strings:
$pdb = "Senata\\nvidia" ascii
$pdb2 = "patcher.pdb" ascii
$api1 = "GetWindowDisplayAffinity" ascii
$u32 = "user32.dll" wide
// Obfuscated import descriptor: DLL-name field reads ".tex" (0x7865742E)
$obf = { 2E 74 65 78 00 00 00 00 }
condition:
uint16(0) == 0x5A4D and ($pdb or $pdb2 or ($api1 and $obf))
}rule Phase_MemoryDump_Artifacts {
meta:
description = "Phase.uno artifacts in process memory dumps"
author = "Clubhouse AC Research"
date = "2026-06-19"
note = "Scan .dmp files and raw memory captures"
strings:
$c2a = "us1.phase.uno" ascii wide
$c2b = "us2.phase.uno" ascii wide
$c2c = "restrain.ing" ascii wide
$c2d = "neglect.ing" ascii wide
$auth = "/auth/v1" ascii
$dl = "/download/v1" ascii
$shm = "Local\\wisrc" ascii
$nail = "NAIL" ascii
$svc = "svchost.exe:Dnscache" wide
$map = "[map] section mapped" ascii
$stlth = "[stealth] phase 1" ascii
$bp = "[bp-shell]" ascii
$inj = "success: injected into pid" ascii
$debug = "SeDebugPrivilege" wide
$hook = "procexp-hook" ascii
$tele = "Phase Telemetry/1.0" ascii
condition:
3 of them
}rule Phase_PostDestruct_Registry {
meta:
description = "Phase.uno post-destruct registry manipulation traces"
author = "Clubhouse AC Research"
date = "2026-06-19"
note = "Scan exported registry hives or raw hive files"
strings:
$r1 = "restore: NtSetInformationKey" wide ascii
$r2 = "restore: RegOpenKeyExW" wide ascii
$r3 = "registry value deleted successfully" ascii
$r4 = "failed to delete registry value" ascii
$r5 = "/config/delete" wide ascii
$r6 = "identifier removed" ascii
$r7 = "cleaning up shellcode mem" ascii
$r8 = "All those beautiful files will be deleted" ascii
condition:
2 of them
}Indicators of compromise
File hashes (SHA-256)
| Module | SHA-256 |
|---|---|
| Loader | bb7ed6a952c5738c786dd63a3fbe503ff2ecddc0d1ee6204c1cea504fd7982fc |
| FiveM payload | c4e7ee26c783e2f1090b6c9173f5177fe65bac15d7fa9f5e7831f4ac67de7d63 |
| bp-shell (A) | 0bcdeb52e3d700ae442a24554bfe2c56b1327d1e6e836432bcc587e9c1f98d39 |
| bp-shell (B) | 521d79657ac53bedc313bbb2c9ebcaafc10cb4eac00ce77e85e839e6ba373291 |
| nvidia_patcher | b60f1c74e9880015202e172c34c0ab48052fa58b7cdd429924daf735a6201702 |
| procexp-hook | 11136cc665f7d86586397076ef5ff47655f1e4d2867f9e5c0a300766fd9af176 |
| unknown_135k | ab95414ac5c6a5de6fc9e438506fe878fd938fb83bc56eda5e2093bf9af3b9fc |
| unknown_24k | 9d97529cd1de11ab2c86e68b07b1b50f77862f6170bc5a5bad1a09fa6cb8e6ae |
| Spotify DMP (host) | 0285239edcb14ca7bc17ece642cd30d073cb6e593da29e747fba7e61168da52a |
Network indicators
| Type | Indicator | Context |
|---|---|---|
| Domain | us1.phase.uno | Primary C2 (port 443) |
| Domain | us2.phase.uno | Secondary C2 (port 8443) |
| Domain | restrain.ing | Tertiary C2 failover (port 443) |
| Domain | neglect.ing | Quaternary C2 failover (port 443) |
| URL | /auth/v1 | Authentication |
| URL | /download/v1 | Payload download |
| URL | /config/list | WFP blocklist |
| URL | /telemetry/v1 | Telemetry |
| URL | /config/delete | Config cleanup |
| URL | /handshake | Session handshake |
| Domain | napse.ac | Blocked AC domain |
| Domain | detect.ac | Blocked AC domain |
| Domain | api.ipify.org | External IP check |
| Webhook | discord.com/api/webhooks/1506075252847808543/... | Telemetry exfil |
| User-Agent | Mozilla/5.0 ...rv:124.0 ...Firefox/124.0 | Spoofed browser UA |
| User-Agent | Phase Telemetry/1.0 | Telemetry endpoint UA |
| PDB path | C:\Users\fff\Desktop\phase-server\cpp-loader\... | Main loader |
| PDB path | C:\Users\fff\Documents\GitTea\phase-shellcodes\... | bp-shell |
| PDB path | C:\Users\fff\Desktop\Senata\nvidia\... | nvidia_patcher |
| PDB path | C:\Users\hxfd\source\repos\procexp-hook\... | procexp-hook |
| PDB path | C:\Users\hxfd\...\phase-fivem\... | FiveM module |
Behavioral indicators
- Non-system process calling FwpmFilterAdd0 to block anti-cheat IPs (WFP filters named "bp-shell block v4/v6")
- NtCreateSection + dual NtMapViewOfSection + NtCreateThreadEx from non-system process
- WriteProcessMemory zero-fill on MZ/PE header region of remotely mapped section (stealth phase 1)
- SuspendThread + GetThreadContext + SetThreadContext (RIP redirect) + ResumeThread on game thread
- 12-byte inline hook on NtQuerySystemInformation in ntdll (48 B8 xx xx xx xx xx xx xx xx FF E0)
- Topmost layered window with WDA_EXCLUDEFROMCAPTURE + class "NVIDIA GeForce RTX 5060" reapplied every ~16ms
- Named file mapping Local\wisrc between overlay and renderer modules (magic "NAIL" 0x4C41494E)
- File access to %APPDATA%\Discord\Local Storage\leveldb\ (and canary/ptb variants) by non-Discord process
- FiveM hooks on anticheat:weaponViolation / anticheat:pedModelViolation events
- Spotify.exe process with abnormally high memory (686+ MB) containing PE artifacts not part of Spotify
- OpenSCManagerW + OpenServiceW("Dnscache") + QueryServiceStatusEx from non-system process
- NtSetInformationKey(KeyWriteTimeInformation=0) from non-system process — registry timestamp forgery
- NtRemoveProcessDebug + NtSetInformationDebugObject from non-debugger process — debug detachment
- ZwSetInformationThread(ThreadHideFromDebugger=0x12) — thread concealment
- CryptUnprotectData calls from non-browser process (credential theft via DPAPI)
- Connections to restrain.ing or neglect.ing on port 443 (C2 failover domains)
Developer attribution
Two developer usernames are embedded in PDB (debug symbol) paths across the suite. A third Windows username appears only in a file path reference.
| Username | Modules | PDB paths |
|---|---|---|
| fff | Main loader, bp-shell, nvidia_patcher | C:\Users\fff\Desktop\phase-server\cpp-loader\x64\Release\loader.pdb C:\Users\fff\Documents\GitTea\phase-shellcodes\x64\Release\bp-shell.pdb C:\Users\fff\Desktop\Senata\nvidia\x64\Release\patcher.pdb |
| hxfd | procexp-hook, FiveM payload | C:\Users\hxfd\source\repos\procexp-hook\x64\Release\procexp-hook.pdb C:\Users\hxfd\Documents\GitHub\phase-backend\phase-module\phase-fivem\bin\Release\fivem_external_beta.pdb |
| jeffc | (referenced path only) | C:\Users\jeffc\AppData\Roaming\Spotify\Spotify.exe (inside FiveM DLL) |
Compile timestamps
| Module | Compile date | Linker |
|---|---|---|
| Main loader | 2026-05-24 22:45:54 UTC | MSVC 14.42 (VS 2022) |
| bp-shell (embedded) | 2026-05-11 22:53:59 UTC | MSVC 14.35-14.36 (VS 2022 17.5) |
| FiveM payload | 2026-06-15 18:59:43 UTC | MSVC 14.0 |
The embedded bp-shell was compiled 13 days before the main loader, confirming it is a pre-built component linked in. The loader's CODEVIEW debug directory shows Age=178, indicating 178 incremental rebuilds during development. A custom embedded font has a FontForge build date of January 22, 2026, providing an earlier development timeline marker.
Infrastructure
Developer fff uses a self-hosted Gitea instance for phase-shellcodes and desktop folders for phase-server and Senata projects. Developer hxfd uses GitHub (phase-backend repo) alongside local Visual Studio repos. The C2 infrastructure uses *.phase.uno domains with failover to restrain.ing and neglect.ing.
Discord infrastructure
A hardcoded Discord webhook is used for telemetry exfiltration: /api/webhooks/1506075252847808543/YVB5hF6Pd396CjG1zRpHZicbxD0UcB2KsKJQOINI70fPPiudcPWToXzyrlido7NLdA2f. A Discord CDN avatar URL references user ID 1421663425657835523 — this is a customer account embedded in the FiveM payload UI, not a developer identifier.
Methodology
All findings were produced through reverse engineering analysis. No binaries were executed. Tools used:
- Ghidra 12.1.2 — full auto-analysis, decompilation, and control-flow graph reconstruction. Custom export script produced the function inventory, string cross-references, and bounded pseudocode for the loader (2,324 functions analyzed).
- IDA Pro 9.0 — secondary disassembly for cross-validation of critical functions, FLIRT signature matching, and type propagation.
- Binary Ninja — intermediate language (BNIL) lifting for data-flow analysis and automated variable recovery across injection routines.
- x64dbg / WinDbg — kernel-mode and user-mode debugging, memory dump analysis, and live inspection of hooked system calls.
- pefile (Python) — PE header parsing, section entropy analysis, import/export enumeration, and overlay detection.
- capstone (Python) — x86-64 disassembly engine for targeted function analysis, inline hook trampoline verification, and code-in-header-slack discovery.
- YARA 4.5 — custom rule development and validation against memory dumps and disk artifacts.
- Volatility 3 — memory forensics framework for process memory dump analysis, injected code detection, and handle enumeration.
- PE-bear / CFF Explorer — visual PE structure analysis, section permission auditing, and resource extraction.
- Sysinternals Suite (Process Monitor, Autoruns, Sigcheck) — behavioral artifact correlation, registry forensics, and signature verification.
- strings / objdump / readelf — broad string extraction, section metadata, and symbol table enumeration.
The FiveM DLL (11.9 MB) required extended analysis time due to its size. Findings for that module are based on PE metadata, imports, strings, config correlation, and partial decompilation of key functions.
Additionally, a 686 MB Spotify.exe process memory dump (Spotify.exe_2026-06-15_20-08-49.dmp) was analyzed, confirming that Phase's payload was actively hosted inside the Spotify process. This provided the critical evidence for the fileless/no-EXE launch method documented in this report.
Legal notice
The operators of Phase.uno have already threatened the author of this research. We are publishing this anyway. This is original independent research conducted for the benefit of the anti-cheat community. No copyrighted code is reproduced. All findings are derived from independent reverse engineering analysis. If you are the operators of Phase.uno: this research is protected under fair use for security research and public interest reporting. Attempts to suppress it via legal threats will be documented and made public.
Defensive material
This research documents detection methodology only. It is published for the benefit of anti-cheat operators, PC checkers, and game security teams. All analysis is original work by Clubhouse AC Research produced through independent reverse engineering. No copyrighted code is reproduced. Vendors and incident-response teams seeking the full binary samples can reach the team at security@clubhouseac.shop.