This fork is an independently maintained sys-agent build based on upstream v2.5. It keeps the original TCP protocol compatible while adding Switch-side memory search and a unified process-memory backend that can coexist with Atmosphère cheats.
Custom-build warning: this is not an official upstream release. It can read and write game-process memory and runs as an Atmosphère sysmodule. Back up the existing
atmosphere/contents/43000000000000A6directory before installing, and use it only on a console where you understand the risks.
- A unified
ProcessMemoryBackendroutes legacypeek/poke, multi, pointer, freeze, metadata, and search operations through one selected backend. - The default
autopolicy prefers Atmosphère'sdmnt:chtservice, sharing dmnt's existing debug handle instead of attempting a conflicting secondsvcDebugActiveProcessattachment. dmntanddirectpolicies are available for diagnostics. Direct-debug handles are scoped to an operation and released afterward; this fork never force-closes a dmnt-owned handle.- Asynchronous exact and typed
u8/u16/u32/u64memory search supports absolute, main, and heap-relative ranges, alignment, progress, cancellation, sessions, and paged results. - SD-backed unknown-value sessions support exact, changed, unchanged, increased, and decreased multi-pass refinement without keeping millions of candidates in the sysmodule heap.
- Search sessions pin their process ID and backend, preventing a running scan from silently switching to a different process or debug owner.
- An isolated, low-priority FTP worker exposes the SD card at
ftp://switch:6001while a game remains open. It supports normal file and directory CRUD and can be controlled over the existing sys-agent TCP connection. - Grouped system-management commands report system, power, storage, network, account, application, and process state. Additive actions cover normal reboot/shutdown, wireless and lock-screen settings, foreground-application termination, and one-shot Hekate emuMMC reboot.
- The original controller, screen-capture, and memory commands remain available. New commands are additive so existing clients can continue to ignore capabilities they do not use.
See commands.md, the memory-backend design, the exact-search design, and the unknown-search design for protocol and implementation details. FTP architecture, validation results, known filename limitations, and remaining hardware acceptance checks are recorded in the FTP server notes.
A Nintendo Switch (CFW) sysmodule that allows users to remotely control their Switch over a TCP socket and read or write game memory. It can be used for bots, automation, and controlled memory research.
Security warning: the command socket on port 6000 is unauthenticated. The explicitly
enabled networkProfile command returns the current Wi-Fi passphrase, while other commands
return serial and account identifiers or change system state. Expose this port only on a
trusted isolated network and restrict it with the surrounding network firewall.
- Set controller state
- Simulate buttons press, hold, and release
- Simulate touch screen drawing
- Read/write x amount bytes of consecutive memory from RAM based on:
- Absolute memory address
- Address relative to main nso base
- Address relative to heap base
- Share Atmosphere dmnt's active debug handle so memory commands and searches can coexist with the cheat VM, with an explicit direct-debug fallback.
- Run asynchronous exact and typed memory searches with progress, cancellation, and paged results.
- Capture current screen and return as JPG
The custom build starts an anonymous FTP server on port 6001 by default. Its root is the SD
card root; it does not expose BIS, save data, gamecard, or other system mounts.
The FTP core runs as one event-driven worker thread and accepts up to four simultaneous client sessions. Connections and transfers are polled and advanced in turns; they do not receive one thread each and multiple large transfers do not run in true CPU-parallel fashion. Concurrent transfers also share Wi-Fi and SD-card bandwidth.
curl ftp://switch:6001/
printf 'ftpStatus\r\n' | nc -w 3 switch 6000
printf 'ftpStop\r\n' | nc -w 3 switch 6000
printf 'ftpStart\r\n' | nc -w 3 switch 6000Anonymous mode permits uploads, renames, and deletion across the complete SD card. This is
intended for a trusted development network. For account access, copy
config/ftp.ini.template to
/config/sys-agent/ftp.ini on the SD card, set anonymous=0, provide both credentials, and
run ftpReload. Invalid credentials or ports leave FTP in an error state without stopping
the controller or memory service.
ASCII filenames, including spaces, are the supported stable baseline. On the tested Horizon
SD filesystem, Chinese and Japanese names return native FS 0x202, while some other non-ASCII
names can be opened but are not returned reliably by directory enumeration. The server does
not silently rewrite names; use an ASCII temporary or final filename when transferring such
files.
Do not run old sys-ftpd on port 6001. Sphaira normally uses port 5000, so both can coexist,
although two writers changing the same file is unsafe. For Atmosphere deployment, upload to a
temporary filename and rename it only after the transfer completes. During an active C-level
search, FTP modifications below /switch/sys-agent/search are rejected to protect the
transactional snapshot.
This project was created for the purpose of development for bot automation. The creators and maintainers of this project are not liable for any damages caused or bans received. Use at your own risk.
-
Download the ZIP from this fork's latest release.
-
Power off the Switch and back up the existing directory:
atmosphere/contents/43000000000000A6. -
Extract the ZIP into the root of the SD card. The final files must be:
atmosphere/contents/43000000000000A6/exefs.nsp atmosphere/contents/43000000000000A6/flags/boot2.flag -
Safely eject the SD card and fully restart the Switch. Restarting only the game is not sufficient when replacing a running sysmodule.
-
Verify the service over TCP, for example:
printf 'getVersion\r\n' | nc -w 3 switch 6000 printf 'memoryBackendProbe\r\n' | nc -w 3 switch 6000 printf 'searchCapabilities\r\n' | nc -w 3 switch 6000
When installed correctly, sys-agent will make the docked Joy-Con HOME button glow during
Switch startup. If this does not happen, check the directory layout and boot2.flag.
To upgrade, replace the complete 43000000000000A6 directory with the one from the new
release and fully restart the console. To roll back, restore the directory backed up before
installation and restart again. Do not mix exefs.nsp from one release with packaging files
from another release.
deploy_sysagent.py updates an existing sys-agent installation on a running Switch. It
builds the current tree with the pinned Docker image, then installs the new build over the
built-in FTP server and reboots into emuMMC — without removing the SD card. It requires that
sys-agent is already installed and running on the Switch, because it relies on the built-in
FTP server (port 6001) and the reboot command (port 6000). For a first-time installation
on a console without sys-agent, use the manual steps in Installation
instead.
python3 deploy_sysagent.py
python3 deploy_sysagent.py --no-build --dry-run # preview only, no Switch accessThe update uploads the new exefs.nsp as exefs.nsp.new, verifies the byte count, renames
it atomically over the running file, requests systemRebootEmuMMC to reboot directly into
the virtual system (pass --normal-reboot for a plain reboot), and waits until the console
answers a command round-trip before checking that the new build advertises
audio=volume,mute. --verify-only performs just that wait-and-check on a console that is
already rebooting. The script intentionally does not back up the Switch-side sys-agent; to
roll back, re-deploy an older build or edit the SD card manually.
This branch is built with the pinned official devkitPro image:
docker run --rm \
--platform linux/amd64 \
-v "$PWD:/work" \
-w /work \
devkitpro/devkita64:20260219 \
bash -lc 'source /opt/devkitpro/switchvars.sh && make clean && make && make test'Clone with --recurse-submodules, or run git submodule update --init --recursive before the
first build. The build uses the checked-out pinned FTP source and does not download dependencies.
The build produces sys-agent/sys-agent.nsp and refreshes the ignored installation tree
at sys-agent/43000000000000A6. The NSP is copied there as exefs.nsp.
Unknown-search snapshots are runtime-only temporary data under /switch/sys-agent/search on
the SD card. They are removed when the session closes or the sysmodule starts again. Do not
store personal files in that directory.
- Big thank you to jakibaki for a great sysmodule base to learn and work with, as well as being helpful on the Reswitched discord!
- Thanks to RTNX on discord for bringing to my attention a nasty little bug that would very randomly cause RAM poking to go bad and the switch (sometimes) crashing as a result.
- Thanks to Anubis for stress testing!
- Thanks to the Atmosphere project for documenting and providing the
dmnt:chtservice used by the unified process-memory backend.
