Tutorial  Updated

sys-netcheat 101: From the basics to relative addresses, trainers and Android usage

logo.png


IntroductionPart 1: Requirements & installationPart 2: Basic usagePart 3: Relative addressesPart 4: Scripting & TrainersPart 5: (Android) Termux scripts & WidgetsPart 6: FAQ

  1. Hey, welcome to my tutorial! :D

    If you've never heard about it, sys-netcheat is an open-source system module that allows you to cheat in Nintendo Switch games. For this reason it's commonly referred to as a free alternative to SX OS' cheat functionality.
    Despite this, not many people seem to use it to its full capabilities (or even at all) and I believe one of the reasons is because there aren't many guides out there except for the basic one included in the ReadMe.

    ...And this is why I'm writing my own one here. This guide is meant to be as comprehensive and up-to-date as possible, explaining both simple tasks (such as the setup process and using the tool's basic memory editing functions) and advanced ones that I haven't seen mentioned online yet (creating scripts and trainers based around it or using it on the go from your Android device, for example). Thus, it was created using a mix of the module's official documentation, community resources and personal research.

    I've also taken extra steps to make the guide understandable to both beginners and experts alike. Most people who just want to have a small help to get through a certain game will want to read its first two or three parts while power users may be interested in its second half - which is going to be a bit more difficult, but will teach you how to make use of this tool to its full potential.

    Before getting started, however, here's an important advice: make sure to backup its save file if you care about it!
    It doesn't matter which platform, tools or whatever - if you edit the game's memory in the wrong way you might end up corrupting your save data permanently. This can be avoided by simply creating a backup of your save beforehand just in case. It takes only a few seconds but it can save hundreds of headache-inducing hours later. Don't say I didn't warn you!

    Finally, do NOT use this homebrew to cheat in online matches. Not only you're ruining the game for everyone else but you're also putting a big red flag on your account if it hasn't been banned already. You have been warned.

    Hopefully my work will draw more people's attention to this otherwise underappreciated homebrew and, of course, I also hope you'll find this guide useful! ^_^

  2. So, you're ready to start? Great! In order to follow this guide you're going to need the following:

    • A Nintendo Switch with either Atmosphère v0.8.2 (or higher) or Kosmos v11.7 (or higher). This guide gives for granted that the CFW has been set up and works correctly.
    • sys-netcheat (only if you have Atmosphère, Kosmos includes it by default)
    • A computer with either Windows/macOS/Linux or an Android phone
    • If you have Atmosphère, you need a way to access your Switch's microSD from your PC (card reader/rajikosto's UMS tool/nxmtp/etc...)
    • netcat (all platforms) or SysNetCheatGUI (Windows only - but it reportedly runs well on other OSes using Wine), which you can get from here:
      • Windows - netcat / SysNetCheatGUI. Extract the ZIP of whichever you decide to choose to a folder.
      • macOS - Good news, macOS includes netcat by default!
      • Linux - Some distros inlcude netcat by default (eg. Ubuntu / Debian). If yours doesn't then either install it using your package manager or compile it from source.
      • Android - First download Termux, then open it and run "pkg install netcat" (without quotes, when asked for confirmation reply Y)
    • A working internet connection (Protip: your phone's Wi-Fi hotspot works here too!) - Use 90DNS if you don't want to get banned
    • Patience

    At the time of writing, sys-netcheat's latest version DOES NOT work under ReiNX: it depends on some Atmosphère components that haven't been ported over yet. If you copy over the KIP it will accept connections just fine, however trying to change or freeze a value will do nothing.


    All good? Alrighty, we'll start by installing & enabling the module then! Aside from a small difference (making sure that an option has been turned on) it's no different than the others, so it'll be a breeze if you already know how to install KIPs.

    -If you're running Kosmos you can skip ahead to point #4-

    1. Plug your microSD into your computer
    2. This next step will vary if you're booting Atmosphère using fusee-primary or by loading the required KIPs separately via Hekate:
    Copy sys-netcheat.kip to microSD:\atmosphere\kips, then open microSD:\atmosphere\BCT.ini with a text editor and check that debugmode is set to 1 (if not, set it to 1).

    That was easy!
    You only need to do this if you're using Hekate's KIP loading functions to boot Atmosphère instead of chainloading its own payloads. If you're chainloading fusee-primary through it, you'll need to follow the instructions above!

    If you're unsure, open microSD:\bootloader\hekate_ipl.ini with a text editor and look for a value called "payload". If it points to a file called "fusee-primary.bin" you will need to follow the instructions for fusee-primary above instead!

    Copy sys-netcheat.kip anywhere on your microSD (although it's better to put it together with your other KIPs). Open microSD:\bootloader\hekate_ipl.ini with a text editor. Locate your CFW's boot entry (it will be between square brackets) and add the following lines right below it:
    Code:
    kip1=path to sys-netcheat.kip
    debugmode=1
    If you did everything correctly, it will look something like this:
    Code:
    [CFW]
    kip1=modules/sys-netcheat.kip
    debugmode=1
    kip1=modules/loader.kip
    kip1=modules/pm.kip
    kip1=modules/sm.kip
    kip1=modules/fs_mitm.kip
    secmon=modules/required/exosphere.bin
    atmosphere=1
    Done!
    1. Plug the microSD back into your Switch if you've removed it before.
    2. Boot your Switch's CFW via your preferred method. If you're using Kosmos, be sure to go to "More configs" and then choose either "CFW + sys-netcheat" or "Stock + sys-netcheat" once you're into Hekate!
    3. Wait until the Switch is fully booted up. Success! Click on the next tab above.

    If the Switch hangs at boot you either have conflicting KIPs (for example I've noticed sys-netcheat and sys-ftpd don't go well together) or you have made a mistake while following the installation process. Disable any other KIPs you've got, double check everything and try again.


  3. Now that sys-netcheat has been set up and loaded, it's time to learn how to use it!
    This part will be what most people will care about as it'll teach you how to search and edit values in a game's memory. Keep in mind to keep your game open while following this guide, otherwise the memory addresses will change and you'll have to start all over again!

    Do not worry if some parts are lenghty, a good bunch of them is taken up by images and examples for your own convenience!

    Connecting

    Make sure your Switch and your computer/Android device are both on to the same network!

    You'll need your console's IP address in order to connect. If you don't know it, open the Homebrew Menu and press Y to bring up the NetLoader. You'll find the IP in the window that pops up there.

    Open up a command line/terminal window (cmd.exe on Windows,Terminal on macOS,whichever you ve got installed using on Linux,Termux on Android). If you're on Windows, you should navigate to the folder where you've extracted netcat (for example "cd C:\Users\myusername\Desktop\netcat", without quotes).
    Once you've done that, type the following and press enter (remember to replace switch_ip):

    Code:
    nc switch_ip 5555

    If everything goes fine you'll see a welcome message:
    welcome.png

    The connection was succesful!

    You'll find that the GUI is pretty much self-explanatory in a lot of occasions and one this is no exception. Write your console's IP in the "Switch IP Address" field, then press "Connect".
    If no error occurs you'll see the various components of the GUI become active and editable like so:
    welcome-gui.png


    Done!

    If you're unable to connect double check that you've done everything in Part 1 correctly, otherwise it's time to open a game and get to the good stuff!

    Searching for a value

    This is the most important part of the guide: you're going to learn how to find a value's memory address (aka, where the value is located in the game's memory).

    As already mentioned before the tool will only work once a game is loaded, so it's time to open whatever game you want if you haven't done so already. I'm going to use Kirby Star Allies for reference.
    Once ingame, bring whatever part you need help with on screen. For example, if I want to increase the numbers of lives I have, I'll have to get inside a level so the life counter is displayed.
    (This is a precautionary measure to ensure that whatever value we're going to edit is loaded in the game's memory)

    lives.jpg

    Once you're there, it's time to finally start our search! If you're using netcat we're going to be useing the "ssearch" command, which has the following syntax:
    Code:
    ssearch u8/u16/u32/u64 value         | Starts a search with 'value' as the starting-value

    Now, you may be thinking: "Okay, I kind of get, it but what's all that u8/u16/etc. about?". That represents the data type of our value.
    The data type specifies what kind of value we're going to look for and how big it can be. There are a lot of them, however sys-netcheat supports four out of the box. In all of our cases, the "u" stands for unsigned integer and the number next to it represents the maximum number of bits that can be used by the value.
    Confused? Here's a list of the various value ranges supported by each data type:
    Code:
    u8: from 0 to 255
    u16: from 0 to 65535
    u32: from 0 to 4294967295
    u64: from 0 to 18446744073709551615
    Keep that list in mind as choosing the correct data type is important. For example, trying to search for a value that exceeds the maximum for the one you chose will make the search function report back incorrect results.

    Now you know about the various data types, however you may wonder how to choose the right one. Aside from checking the various value ranges above (for example, if I have 300 lives I can safely assume the value isn't an u8), it's mostly trial and error. The most common data types in Switch games seem to be u32 and u64 so it's a good idea to start from those, then try the others if the search won't find the right address.

    Finally, a few last remarks about the "value" parameter. First off, it's already been stated before but it should still be stressed out that the number you're looking for must be an integer: it should not contain a decimal point nor a sign. Second, unlike other memory editing software which use hexadecimal values, the value here should be decimal (if you don't know what that means, don't worry - it's actually a good thing if you're a beginner as you won't have to fiddle around with a calculator as much :P)
    You should really keep both of those in mind: sys-netcheat will treat the value as 0 if you input an invalid one, and it'll do so without returning any errors!

    So, now that we're done with all of that, it's time for a quick recap! I'll list a few correct and incorrect examples below so you can check if you've got everything I've explained so far:
    ssearch u32 1105
    ^ CORRECT!

    ssearch u64 3204099
    ^ CORRECT!

    ssearch u8 1105
    ^ INCORRECT! (Value exceeds range of u8)

    ssearch u16 3.50
    ^ INCORRECT! (Value includes a decimal point)

    ssearch u32 -10
    ^ INCORRECT! (Value includes a sign)

    ssearch u16 10FF
    ^ INCORRECT! (Value is hexadecimal)

    ssearch u64 Hello
    ^ INCORRECT (Value is not a number)

    Now, back to my game. I want to edit how many lives I have and the counter says I currently have 140. So, in order to search for the value, I'll use the following command:
    Code:
    > ssearch u32 140

    If I were to use the GUI instead, I'd put 140 in the "Value" field, choose u32 in Value Size and then click on "Search":
    search-gui.png

    The game will freeze for a bit (it will stay frozen until the search is over, have patience!) and a list of addresses will start showing up onscreen...
    Code:
    -There were around 200 lines above this one-
    Got a hit at 3b117ac008!
    Got a hit at 3b117ae900!
    Got a hit at 3b117af67c!
    Got a hit at 3b117bcbdc!
    Got a hit at 3b117beed4!
    Got a hit at 3b117bfa78!
    Got a hit at 3b117c46b4!
    Got a hit at 3b117c630c!
    >

    ...that's too many. A few hundreds too many be exact. Luckily, there's another command that allows you to continue our search and get more accurate results:
    Code:
    csearch value                        | Searches the hits of the last search for the new value

    This one is much easier to understand: you can use it to make the program go through the search results again and check if any of them now contain the newly specified value. If you know the value you're looking for has changed ingame, you can use it to shrink down the list and pinpoint the right address!
    (You won't have to worry about data types this time as csearch will just reuse whichever you've specified before)

    To give you an idea of a real use scenario, let's go back to Kirby. I've already started the search before when I had 140 lives so I'll now purposely lose one to decrease the counter...

    dead.jpg

    ...which is already kind of an achievement of its own in this game.​

    Now I have 139 lives, so I know the value has changed. I'll wait until I respawn and then I'll use the following command to continue the search:
    Code:
    > csearch 139

    Which returns the following addresses...

    Code:
    Got a hit at 3aa1a02e04!
    Got a hit at 3ac397c420!
    Got a hit at 3ac397c480!
    Got a hit at 3ac4ae3678!
    Got a hit at 3ad6e87aa0!
    >
    They went from hundreds of addresses to only five. That's muuuuch better. We can proceed to the next step!

    Changing a value stored in memory

    Now that you have a small list of addresses you can work with, it's time to start changing values around until you find the right one. Of course, there's a command for that:
    Code:
    poke address u8/u16/u32/u64 value    | Sets the memory at address to value

    As you can see, it's pretty simple: you grab one of the addresses from the result, specify what data type it contains (the same you've used for ssearch) and the new value you want to set it to.
    So, if I want to change back the lives to 600 in my game, I'll have to send it like this...
    Code:
    > poke 3ac4ae3678 u32 999
    ...and repeat it for every address in the list until I find the right one.

    In the GUI, you can simply double click on one of the address returned from the search. A popup will appear which asks you to input the new value:
    sdfdsf.png
    (Additionally, you can also click on the big + button to enter an address manually)

    life.gif

    And just like that, I now have a ludicrous amount of lives!​

    But what if I could have... literally infinite lives?

    Freezing values

    sys-netcheat has one additional function: freezing. When used, the tool will check if a value changes at your specified memory address and, if it does, it'll automatically revert it back to whatever value you want.
    This is useful in two different scenarios: the first one is if you want infinite lives/items/coins/etc. and the second is to help with some games which will actively try to deter you from cheating by changing the value back when they detect you may be doing something fishy.
    This command's syntax is basically the same as poke:
    Code:
    afreeze address u8/u16/u32/u64 value | Freezes the memory at address to value
    Just as before, get one of the addresses from the results, specify the same data type as the one you've used to search and set the value to whatever you want. Once you send the command, you can double check if the address has been frozen by using:
    Code:
    lfreeze                              | Lists all frozen values
    ...Which does exactly what it says and requires no arguments. Finally, if you want to unfreeze a previously frozen address, you can use:
    Code:
    dfreeze index                        | Unfreezes the memory at index
    The "index" parameter here is the number of the address as reported by lfreeze.

    It's time to get back to Kirby once more. I'll use this command to essentially get infinite lives:
    Code:
    > afreeze 3ac4ae3678 u32 999
    The counter will still show 999 lives, however it won't decrease anymore!
    Once I want to turn Kirby back to a mere mortal, I'll first use lfreeze and then dfreeze like so:
    Code:
    > lfreeze
    0) 3ac4ae3678 (u32) = 999
    > dfreeze 0

    Freezing addresses from the GUI is also very simple: once you have an address on the table (by either selecting one from the search results or inserting one manually), you can use the little checkbox on the leftmost row to freeze/unfreeze the address:
    ghfhgf.png

    Now, some of you who already tried sys-netcheat could think "Well, so far this is a bit more detailed and up to date rather than the guide in the ReadMe but so far I didn't learn much more than what I already knew!"
    If that applies to you, don't you worry: we were just getting started! :P

    If you ever get stuck, check the last part of this guide (the FAQ)!

  4. So, if you've been paying attention you'll know by now that the addresses you've found will no longer work if you close the game. This means whenever you want to use a cheat you'll have to search for your specific value every time... right?

    Well, yes and no. You see, the problem here is caused by the game's base address changing every time you open it. This isn't a problem for more advanced memory editors which will automatically give you relative addresses (for example, Cheat Engine on Windows does that), however sys-netcheat only supports absolute addresses, meaning that it doesn't take into account the process' base one at all.

    And here is where things get interesting: most of the time what actually changes is just the base address, not the relative ones of a specific value (unless the program itself is made to do so). This also applies to games running on the Switch so, if we can find a way to make our addresses relative, we can effectively just make a single initial search and then work by ourselves from there!

    Now, there is no easy way to get the process' base address using sys-netcheat but this doesn't mean we're out of luck. In fact, we can use a dead simple yet effective trick: we're going to search for a value that never changes in our game's memory and make out addresses relative to that one instead.

    This is usually as easy as looking for an u64 with value 0 and picking the first result. However, be extra sure that whatever you've picked will actually stay the same all the time! In order to do so just play the game for a while - test different levels, areas, battles, etc and make constant searches. If your address pops up everytime, you've got yourself a good candidate!

    Once you've got it, all you have to do is to subtract the address you've just got to the ones you've previously found - just keep in mind that the addresses are shown as hexadecimal so remember set your calculator to HEX :P

    Then, once you open your game once more, it's time to do the opposite: search for that same value again, get the new address and add the result of the aforementioned subtraction to it. Yes, it's that simple.

    Here's the mandatory Kirby example:
    I closed the game then reopened it so I got new addresses. I've searched for the lives' memory addresses again, which this time is:
    Code:
    2c694e3678

    Now I'll search for an address that never changes its value so I can make the above address relative:
    Code:
    > ssearch u64 0
    > Got a hit at 2bf1e00018!
    Got a hit at 2bf1e00038!
    Got a hit at 2bf1e00040!
    Got a hit at 2bf1e00048!
    ...
    I'll play the game for a bit and perform the same search again. Sure enough, the first hit always pops up: it means there's a good chance it indeed never changes!

    It's time to bring up the calculator (most support hex notation including Windows' own, but if for some strange reason yours doesn't then use this one). Now, all I have to do is to subtract the base address to the life counter's:
    Code:
    2c694e3678 - 2bf1e00018 = 776E3660

    It's time to close and re-open the game to check if the trick worked. When I'm in-game I'll perform the same search and pick the first result again:
    Code:
    > ssearch u64 0
    > Got a hit at 6ae3a00018!
    Got a hit at 6ae3a00038!
    Got a hit at 6ae3a00040!
    Got a hit at 6ae3a00048!
    Got a hit at 6ae3a00058!
    ...

    Now, let's add the value we've found to that address...
    Code:
    6ae3a00018 + 776E3660 = 6b5b0e3678

    That's it! (It does kinda look like the old one, right? :P)
    From here, it's time to test it using poke or freeze. If it does work (and mine did), you've got yourself a way to make all your addresses relative, thus making them persist reboots, crashes and whatnot!

    Keep in mind that the offsets may change between different game languages, versions, revisions and the like! If a new version of the game gets released, for example, you may have to perform searches again to find the value and recalculate the relative offsets.
    (The above is true for basically all platforms ever released, but it's always good to remind it)

    That's it, really - a simple trick that solves an immensely annoying problem. It'll also be absolutely crucial for what we're going to do next.

  5. And now we've reached what I think is the best part. Here we're going to mix pretty much everything I've told you so far so be sure to have had a good amount of practice before reading. A good knowledge of a scripting language is also recommended (I'm going to use Bash and Batch scripts here as they're some of the most common, but you can easily adapt this to whatever language you want).

    Netcat is known as "the swiss army knife of TCP/IP connections" for a reason. What we're using it for here is to act as a way to interface us with sys-netcheat, however it can do much, much more. While a lot of the additional functions aren't compatible or necessary for our goals, one thing that's going to be extremely useful to us is that it's been made with scripting in mind and you bet we're going to take advantage of that here.

    One thing worth mentioning is that while the following instructions will be good for Windows, macOS and Linux, they will need to be changed a bit to work on Android as Termux uses a slightly different version of netcat. This will be covered in the next part.

    First off, if you've been playing with netcat a bit, you've probably noticed that the are a few switches to execute a script or command through it (such as -c, -e, --lua-exec). Those cannot be used in our case as sys-netcheat doesn't actually provide a remote shell. However, netcat also accepts inputs via stdin and this will indeed work here. So, we can just echo our command and pipe it to netcat, for example:
    Code:
    echo "help" | nc switch_ip 5555
    Will show the help screen as soon as it connects to our Switch! Still, netcat will wait for another command instead of quitting as soon as it's done printing stuff onscreen. This can be avoided by using the -w switch, which acts as a timeout if the connection stays idle for the specified number of seconds. Add a little stdout redirection to a file and we've got this:
    Code:
    echo "help" | nc -w 3 switch_ip 5555 > out.txt
    In the above example netcat will connect to sys-netcheat, send the "help" command, wait for 3 seconds until the connection times out and write the result to a file called out.txt. This little command is already useful per se: you could make shortcuts to perform searches, change specific values (in this case writing to a file is not necessary) or list frozen addresses with a single click.

    Still, why stop there? With a few additions we can make a simple script that allows us to use relative addresses with ease:
    Code:
    #!/bin/bash
    IP='192.168.1.200'
    RELADDR='776E3660'
    BASTXT='base.txt'
    
    HEX='0x'
    if [ ! -f $BASTXT ]; then
       OUTFILE='search.txt'
       SEARCH='ssearch u64 0'
       echo $SEARCH | nc -w 4 $IP 5555 > $OUTFILE
       LCNT=$(wc -l < $OUTFILE)
       if (( $LCNT >= 3 )); then
           BAS=$(sed -n 3p $OUTFILE | cut -c 16- | cut -d "!" -f1)
           echo -n $HEX$BAS > $BASTXT
       else
           echo "[ERROR] - Could not get search results!"
       fi
       rm $OUTFILE
    fi
    BAS=$(cat $BASTXT)
    NEWDEC=$(($BAS+$HEX$RELADDR))
    NEWADDR=$(echo -n 16o${NEWDEC}p | dc )
    echo "poke $NEWADDR u32 100" | nc -w 1 $IP 5555 > /dev/null
    NOTE: This script uses GNU bc to get around some limitations of Batch, which you can download from here. Put netcat (nc), bc and the script itself in the same directory.
    Code:
    @echo off
    set IP="192.168.1.200"
    set RELADDR=776E3660
    set BASTXT=base.txt
    
    if exist %BASTXT% goto send
    
    set OUTFILE="search.txt"
    set SEARCH=ssearch u64 0
    
    echo %SEARCH% | nc.exe -w 4 %IP% 5555 > %OUTFILE%
    set "BAS="
    for /F "skip=2 delims=>!" %%I in (search.txt) do if not defined BAS set "BAS=%%I"
    set BAS=%BAS: Got a hit at =%
    if "%BAS%" == " Got a hit at =" (goto baserror)
    set BAS=%BAS:a=A%
    set BAS=%BAS:b=B%
    set BAS=%BAS:c=C%
    set BAS=%BAS:d=D%
    set BAS=%BAS:e=E%
    set BAS=%BAS:f=F%
    echo %BAS% > %BASTXT%
    del %OUTFILE%
    goto :send
    
    :send
    set /P BAS= < base.txt
    echo obase=16;ibase=16;%BAS%+%RELADDR% | bc.exe -l > temp.txt
    set /P NEWADDR= < temp.txt
    del temp.txt
    echo poke %NEWADDR% u32 100 | nc.exe -w 1 %IP% 5555 > nul
    goto end
    
    :baserror
    echo [ERROR] - Could not get search results!
    pause
    
    :end
    Using the scripts above is simple: you just need to edit the IP and RELADDR variables, putting your Switch's IP and relative address there respectively. You can also edit the BASTXT (name of the text file containing the base address), OUTFILE (name of the temporary text file storing the search results) and SEARCH (parameters for the initial search, this usually doesn't have to be changed as previously said) variables if you want to have a little bit more customization.

    How the scripts work is simple: first, they'll look for a file containing the base address. If it's not found, they'll search for it in the game's memory using some predefined search parameters (default: ssearch u64 0, then get the first address from the list). On the other hand, if the file is found then the base address is loaded from it and a relative address will be calculated using the value stored in RELADDR. Finally, a command is executed to write a predefined value located at the previously calculated address (default: poke with datatype u32 and value 100, if you want to edit the command go to line 23 [Bash] or 30 [Batch]).

    Those scripts can already prove useful by themselves as they make working with relative addresses a fairly straightforward procedure, however they have a much, much bigger potential. You know what happens when we get a bunch of relative addresses, the scripts above, a simple menu and mix it all together?

    We get ourselves our very own basic game trainer!

    Code:
    #!/bin/bash
    BASTXT='base.txt'
    
    reladdr () {
    HEX='0x'
    if [ ! -f $BASTXT ]; then
       OUTFILE='search.txt'
       SEARCH='ssearch u64 0'
       echo "Finding base address - this must be done only once each time you open the game/trainer, please wait..."
       echo $SEARCH | nc -w 4 $IP 5555 > $OUTFILE
       LCNT=$(wc -l < $OUTFILE)
       if (( $LCNT >= 3 )); then
           BAS=$(sed -n 3p $OUTFILE | cut -c 16- | cut -d "!" -f1)
           echo -n $HEX$BAS > $BASTXT
       else
           echo "[ERROR] - Could not get search results!"
       fi
       rm $OUTFILE
    fi
    BAS=$(cat $BASTXT)
    NEWDEC=$(($BAS+$HEX$2))
    NEWADDR=$(echo -n 16o${NEWDEC}p | dc )
    echo "Sending command..."
    echo "$1 $NEWADDR $3" | nc -w 1 $IP 5555 > /dev/null
    echo "Done!"
    }
    
    PS3='Select: '
    CHEATS=("Set lives to 999 (Green Gardens)" "Set lives to 999 (World Map - Dream Land)" "Infinite lives (Green Gardens)" "Always have 99 stars (Green Gardens)" "Set stars to 99 (World Map - Dream Land)" "Clear base address (choose this first if you closed your game)" "Quit")
    if [ -f $BASTXT ]; then
       rm $BASTXT
    fi
    echo "- Kirby Star Allies v1.0.0 (ENG) +5 Trainer -"
    echo "Part of the sys-netcheat 101 guide by RattletraPM"
    echo
    echo -n "Please input your Switch's IP address: "
    read IP
    if [ -z "$IP" ]; then
       echo "You need to input your Switch's IP address. Quitting..."
       exit 1
    fi
    echo
    select CHOICE in "${CHEATS[@]}"
    do
        case $CHOICE in
            "Set lives to 999 (Green Gardens)")
                reladdr 'poke' '776E3660' 'u32 999'
                ;;
            "Set lives to 999 (World Map - Dream Land)")
                reladdr 'poke' '614B7DB0' 'u32 999'
                ;;
            "Infinite lives (Green Gardens)")
                reladdr 'afreeze' '776E3660' 'u32 999'
                ;;
       "Always have 99 stars (Green Gardens)")
                reladdr 'afreeze' '776E3664' 'u32 99'
                ;;
       "Set stars to 99 (World Map - Dream Land)")
                reladdr 'poke' '614B7DB8' 'u32 99'
                ;;
       "Clear base address (choose this first if you closed your game)")
                rm $BASTXT
                ;;
            "Quit")
                break
                ;;
            *) echo "Invalid selection!";;
        esac
    done
    NOTE: Again, this script uses GNU bc to get around some limitations of Batch, which you can download from here. Put netcat (nc), bc and the script itself in the same directory.

    Code:
    @echo off
    set IP=""
    set CMD=""
    set ARGS=""
    set RELADDR=""
    set BASTXT=base.txt
    if exist %BASTXT% del %BASTXT%
    echo - Kirby Star Allies v1.0.0 (ENG) +5 Trainer -
    echo Part of the sys-netcheat 101 guide by RattletraPM
    echo.
    set /p IP="Please input your Switch's IP address: "
    if %IP% == "" goto iperror
    echo.
    echo 1) Set lives to 999 (Green Gardens)
    echo 2) Set lives to 999 (World Map - Dream Land)
    echo 3) Infinite lives (Green Gardens)
    echo 4) Always have 99 stars (Green Gardens)
    echo 5) Set stars to 99 (World Map - Dream Land)
    echo 6) Clear base address (choose this first if you closed your game)
    echo 7) Quit
    goto choice
    
    :choice
    set /P choice=Select:
    goto %choice%
    
    :1
    set CMD=poke
    set RELADDR=776E3660
    set ARGS=u32 999
    goto check
    
    :2
    set CMD=poke
    set RELADDR=614B7DB0
    set ARGS=u32 999
    goto check
    
    :3
    set CMD=afreeze
    set RELADDR=776E3660
    set ARGS=u32 999
    goto check
    
    :4
    set CMD=afreeze
    set RELADDR=776E3664
    set ARGS=u32 99
    goto check
    
    :5
    set CMD=poke
    set RELADDR=614B7DB8
    set ARGS=u32 99
    goto check
    
    :6
    if exist %BASTXT% del %BASTXT%
    goto choice
    
    :7
    goto end
    
    :check
    if exist %BASTXT% goto send
    
    set OUTFILE="search.txt"
    set SEARCH=ssearch u64 0
    
    echo Finding base address - this must be done only once each time you open the game/trainer, please wait...
    echo %SEARCH% | nc.exe -w 4 %IP% 5555 > %OUTFILE%
    set "BAS="
    for /F "skip=2 delims=>!" %%I in (search.txt) do if not defined BAS set "BAS=%%I"
    set BAS=%BAS: Got a hit at =%
    if "%BAS%" == " Got a hit at =" (goto baserror)
    set BAS=%BAS:a=A%
    set BAS=%BAS:b=B%
    set BAS=%BAS:c=C%
    set BAS=%BAS:d=D%
    set BAS=%BAS:e=E%
    set BAS=%BAS:f=F%
    echo %BAS% > %BASTXT%
    del %OUTFILE%
    goto :send
    
    :send
    set /P BAS= < base.txt
    echo obase=16;ibase=16;%BAS%+%RELADDR% | bc.exe -l > temp.txt
    set /P NEWADDR= < temp.txt
    del temp.txt
    echo Sending command...
    echo %CMD% %NEWADDR% %ARGS% | nc.exe -w 1 %IP% 5555 > nul
    echo Done!
    goto choice
    
    :baserror
    echo [ERROR] - Could not get search results!
    
    :iperror
    echo You need to input your Switch's IP address. Quitting...
    goto end
    
    :end

    And presto, here's they are! I've uploaded everything to a ZIP for your own convenience, which you can download from here.

    Before calling it a day, however, keep in mind when making a trainer to always specify for which game version, language, etc. it's meant for. As said before, different game versions/revisions/languages/etc. may break your stuff so always take your time to test things out and let the user know what is compatible and what isn't.

    Oh, and one last note too: all the code you see here is released under the WTFPL. You're free to modify, improve, break, share and generally do whatever you want with it. Go nuts.

  6. If you've been paying attention in the previous part (hopefully) you've read that the scripts won't work out of the box in Termux. What gives? It has a Bash shell and netcat so they should just fine!
    Well, spoiler alert, not quite. It's true, the shell is indeed Bash but as it turns out, Termux has been lying to you about netcat all along! Dun-dun-dunnnnn~!

    Here's what I mean: the netcat package doesn't actually provide one of the many netcat variations out there: it installs Ncat instead, which is a different tool compatible with the former with the same command name. However some of the switches are different, so we'll need to take that into account.

    What we need to do is very simple: netcat's -w switch corresponds to Ncat's -i switch. So we need to replace every occurrence of this:
    Code:
    nc -w
    With this:
    Code:
    nc -i

    If you do so, the scripts will run just fine! If you don't know how to run them in Termux I advise you to copy them to your internal storage, follow this guide to allow access your phone's storage and then run the following commands (be mindful to replace fname with your script's filename):
    Code:
    cp ~/storage/shared/fname .
    chmod +x fname
    After that, you can just run it as any other shell script from your home directory (aka, like so: ./fname)

    However, there's something even better you can do on Android. If you don't fancy the idea of using a terminal emulator on the go to access your cheats, I feel you, it is a bit impractical afterall. Luckily Termux gives us an alternative, Termux:Widget!

    Thanks to it, you'll have a quick way to run your scripts from your home menu. You can get it from Google Play but it costst around 2 EUR there, however they're free on F-Droid (no, that's not piracy - both listings are official and reportedly the Google Play one is not free as it's a way to support the developer)

    Protip: You can download Termux:Widget's APK from the link above without installing F-Droid's app, just keep in mind that in order to work both Termux and Widget must be installed from the same source (installing one from Google Play and the other from F-Droid won't work!)

    Once that's said and done, a folder called .shortcuts should have been created in your home dir (check with ls -a, if there is none then create it). All you need to do is to copy your scripts in there (remember to mark them as executable!), then put the widgets on your home screen.

    There are two available: one lists all the scripts in the aforementioned folder and the other is a quick launch button for a specific scripts. Choose whichever combination you like!

    photo5989959492529402514.jpg

    This, combined with Rekado and a mobile hotspot can really turn your phone into the ultimate RCM injector setup :P

    • Q: sys-netcheat won't let me connect after I put the Switch to sleep/I connect a lot of times!
    • A: This is sadly a known issue and there's no solution at the moment. A workaround is to use Atmosphère's reboot to payload to reboot your Switch but, of course, it's a bit awkward. Still, it works for the time, until the dev finds a fix at least.

    • Q: You've mentioned unsigned integers but how do I search for other data types? (eg. strings, signed integers, floats,...)
    • A: It's possible to find those using sys-netcheat but it's a bit more complicated than it needs to be. For example, I've succesfully replaced strings both in homebrew games and Pokèmon LGPE, however you need to take into account several things in order to do so (string encoding, endianess, zero-termination and also the length will probably exceed whatever data type you chose). If you want to search for strings then just keep in mind that most official Switch games will use wide chars to provide Unicode support. Signed integers are technically more feasible (use two's complement) but don't even bother with floats and doubles, sys-netcheat is just too barebones for that.

    • Q: A cheat I've made works in some levels/screens/occasion but doesn't in others!
    • A: Different games have different quirks. For example, you may have noticed the cheats I've made for the lives in Kirby are different for a single level and the world map. It's just due to how the game is made - for example in Sonic Mania Plus this doesn't happen but the life counter is tied to whatever save slot you're using. Sometimes you may even have to change different addresses.

    • Q: I can't find a value!
    • A: Are you sure you're looking for the right one and it's an integer? If so, try again - patience and perseverance are key here!
 
Last edited by RattletraPM,

ericiscool

New Member
Newbie
Joined
Feb 28, 2019
Messages
3
Trophies
0
Age
39
XP
44
Country
United States
No matter what I do I can't get this to connect to my switch . Tried netcat and the gui. Everything works fine with lan-play.exe. I even added the .exe in windows firewall. Not sure what the problem could be. I'm using latest kosmos. I followed the install instructions exactly and am loading from hekate more configs/cfw + sys-netcheat.

So I think I found the answer. sys-netcheat appears to be incompatible with the ip setting requirements of lan-play.exe (lan-play dot com) . This is intentional I'm sure. And no I'm not trying to cheat against randoms, but did want to make some trainers to try out with a friend. Once I set ip settings in the switch to automatic (90 dns still manual) everything worked fine. Tested with nc, sysnetcheatGUI, and HAnX.
 

RattletraPM

Well-Known Member
OP
Member
Joined
Jan 18, 2017
Messages
897
Trophies
1
XP
8,341
Country
Italy
So I think I found the answer. sys-netcheat appears to be incompatible with the ip setting requirements of lan-play.exe (lan-play dot com) . This is intentional I'm sure. And no I'm not trying to cheat against randoms, but did want to make some trainers to try out with a friend. Once I set ip settings in the switch to automatic (90 dns still manual) everything worked fine. Tested with nc, sysnetcheatGUI, and HAnX.
I don't know if it's intentional, for example sys-netcheat also conflicts with sys-ftpd so it may just have problems with any other KIP that uses the network stack, but in the end I just recommend to use it by itself.
 

MrWhosHacking

Well-Known Member
Member
Joined
May 3, 2018
Messages
293
Trophies
0
Age
34
XP
505
Country
United States
View attachment 157811

IntroductionPart 1: Requirements & installationPart 2: Basic usagePart 3: Relative addressesPart 4: Scripting & TrainersPart 5: (Android) Termux scripts & WidgetsPart 6: FAQ

  1. Hey, welcome to my tutorial! :D

    If you've never heard about it, sys-netcheat is an open-source system module that allows you to cheat in Nintendo Switch games. For this reason it's commonly referred to as a free alternative to SX OS' cheat functionality.
    Despite this, not many people seem to use it to its full capabilities (or even at all) and I believe one of the reasons is because there aren't many guides out there except for the basic one included in the ReadMe.

    ...And this is why I'm writing my own one here. This guide is meant to be as comprehensive and up-to-date as possible, explaining both simple tasks (such as the setup process and using the tool's basic memory editing functions) and advanced ones that I haven't seen mentioned online yet (creating scripts and trainers based around it or using it on the go from your Android device, for example). Thus, it was created using a mix of the module's official documentation, community resources and personal research.

    I've also taken extra steps to make the guide understandable to both beginners and experts alike. Most people who just want to have a small help to get through a certain game will want to read its first two or three parts while power users may be interested in its second half - which is going to be a bit more difficult, but will teach you how to make use of this tool to its full potential.

    Before getting started, however, here's an important advice: make sure to backup its save file if you care about it!
    It doesn't matter which platform, tools or whatever - if you edit the game's memory in the wrong way you might end up corrupting your save data permanently. This can be avoided by simply creating a backup of your save beforehand just in case. It takes only a few seconds but it can save hundreds of headache-inducing hours later. Don't say I didn't warn you!

    Finally, do NOT use this homebrew to cheat in online matches. Not only you're ruining the game for everyone else but you're also putting a big red flag on your account if it hasn't been banned already. You have been warned.

    Hopefully my work will draw more people's attention to this otherwise underappreciated homebrew and, of course, I also hope you'll find this guide useful! ^_^

  2. So, you're ready to start? Great! In order to follow this guide you're going to need the following:

    • A Nintendo Switch with either Atmosphère v0.8.2 (or higher) or Kosmos v11.7 (or higher). This guide gives for granted that the CFW has been set up and works correctly.
    • sys-netcheat (only if you have Atmosphère, Kosmos includes it by default)
    • A computer with either Windows/macOS/Linux or an Android phone
    • If you have Atmosphère, you need a way to access your Switch's microSD from your PC (card reader/rajikosto's UMS tool/nxmtp/etc...)
    • netcat (all platforms) or SysNetCheatGUI (Windows only - but it reportedly runs well on other OSes using Wine), which you can get from here:
      • Windows - netcat / SysNetCheatGUI. Extract the ZIP of whichever you decide to choose to a folder.
      • macOS - Good news, macOS includes netcat by default!
      • Linux - Some distros inlcude netcat by default (eg. Ubuntu / Debian). If yours doesn't then either install it using your package manager or compile it from source.
      • Android - First download Termux, then open it and run "pkg install netcat" (without quotes, when asked for confirmation reply Y)
    • A working internet connection (Protip: your phone's Wi-Fi hotspot works here too!) - Use 90DNS if you don't want to get banned
    • Patience

    At the time of writing, sys-netcheat's latest version DOES NOT work under ReiNX: it depends on some Atmosphère components that haven't been ported over yet. If you copy over the KIP it will accept connections just fine, however trying to change or freeze a value will do nothing.


    All good? Alrighty, we'll start by installing & enabling the module then! Aside from a small difference (making sure that an option has been turned on) it's no different than the others, so it'll be a breeze if you already know how to install KIPs.

    -If you're running Kosmos you can skip ahead to point #4-

    1. Plug your microSD into your computer
    2. This next step will vary if you're booting Atmosphère using fusee-primary or by loading the required KIPs separately via Hekate:
    Copy sys-netcheat.kip to microSD:\atmosphere\kips, then open microSD:\atmosphere\BCT.ini with a text editor and check that debugmode is set to 1 (if not, set it to 1).

    That was easy!
    You only need to do this if you're using Hekate's KIP loading functions to boot Atmosphère instead of chainloading its own payloads. If you're chainloading fusee-primary through it, you'll need to follow the instructions above!

    If you're unsure, open microSD:\bootloader\hekate_ipl.ini with a text editor and look for a value called "payload". If it points to a file called "fusee-primary.bin" you will need to follow the instructions for fusee-primary above instead!

    Copy sys-netcheat.kip anywhere on your microSD (although it's better to put it together with your other KIPs). Open microSD:\bootloader\hekate_ipl.ini with a text editor. Locate your CFW's boot entry (it will be between square brackets) and add the following lines right below it:
    Code:
    kip1=path to sys-netcheat.kip
    debugmode=1
    If you did everything correctly, it will look something like this:
    Code:
    [CFW]
    kip1=modules/sys-netcheat.kip
    debugmode=1
    kip1=modules/loader.kip
    kip1=modules/pm.kip
    kip1=modules/sm.kip
    kip1=modules/fs_mitm.kip
    secmon=modules/required/exosphere.bin
    atmosphere=1
    Done!
    1. Plug the microSD back into your Switch if you've removed it before.
    2. Boot your Switch's CFW via your preferred method. If you're using Kosmos, be sure to go to "More configs" and then choose either "CFW + sys-netcheat" or "Stock + sys-netcheat" once you're into Hekate!
    3. Wait until the Switch is fully booted up. Success! Click on the next tab above.

    If the Switch hangs at boot you either have conflicting KIPs (for example I've noticed sys-netcheat and sys-ftpd don't go well together) or you have made a mistake while following the installation process. Disable any other KIPs you've got, double check everything and try again.


  3. Now that sys-netcheat has been set up and loaded, it's time to learn how to use it!
    This part will be what most people will care about as it'll teach you how to search and edit values in a game's memory. Keep in mind to keep your game open while following this guide, otherwise the memory addresses will change and you'll have to start all over again!

    Do not worry if some parts are lenghty, a good bunch of them is taken up by images and examples for your own convenience!

    Connecting

    Make sure your Switch and your computer/Android device are both on to the same network!

    You'll need your console's IP address in order to connect. If you don't know it, open the Homebrew Menu and press Y to bring up the NetLoader. You'll find the IP in the window that pops up there.

    Open up a command line/terminal window (cmd.exe on Windows,Terminal on macOS,whichever you ve got installed using on Linux,Termux on Android). If you're on Windows, you should navigate to the folder where you've extracted netcat (for example "cd C:\Users\myusername\Desktop\netcat", without quotes).
    Once you've done that, type the following and press enter (remember to replace switch_ip):

    Code:
    nc switch_ip 5555

    If everything goes fine you'll see a welcome message:
    welcome.png

    The connection was succesful!

    You'll find that the GUI is pretty much self-explanatory in a lot of occasions and one this is no exception. Write your console's IP in the "Switch IP Address" field, then press "Connect".
    If no error occurs you'll see the various components of the GUI become active and editable like so:
    welcome-gui.png


    Done!

    If you're unable to connect double check that you've done everything in Part 1 correctly, otherwise it's time to open a game and get to the good stuff!

    Searching for a value

    This is the most important part of the guide: you're going to learn how to find a value's memory address (aka, where the value is located in the game's memory).

    As already mentioned before the tool will only work once a game is loaded, so it's time to open whatever game you want if you haven't done so already. I'm going to use Kirby Star Allies for reference.
    Once ingame, bring whatever part you need help with on screen. For example, if I want to increase the numbers of lives I have, I'll have to get inside a level so the life counter is displayed.
    (This is a precautionary measure to ensure that whatever value we're going to edit is loaded in the game's memory)

    lives.jpg

    Once you're there, it's time to finally start our search! If you're using netcat we're going to be useing the "ssearch" command, which has the following syntax:
    Code:
    ssearch u8/u16/u32/u64 value         | Starts a search with 'value' as the starting-value

    Now, you may be thinking: "Okay, I kind of get, it but what's all that u8/u16/etc. about?". That represents the data type of our value.
    The data type specifies what kind of value we're going to look for and how big it can be. There are a lot of them, however sys-netcheat supports four out of the box. In all of our cases, the "u" stands for unsigned integer and the number next to it represents the maximum number of bits that can be used by the value.
    Confused? Here's a list of the various value ranges supported by each data type:
    Code:
    u8: from 0 to 255
    u16: from 0 to 65535
    u32: from 0 to 4294967295
    u64: from 0 to 18446744073709551615
    Keep that list in mind as choosing the correct data type is important. For example, trying to search for a value that exceeds the maximum for the one you chose will make the search function report back incorrect results.

    Now you know about the various data types, however you may wonder how to choose the right one. Aside from checking the various value ranges above (for example, if I have 300 lives I can safely assume the value isn't an u8), it's mostly trial and error. The most common data types in Switch games seem to be u32 and u64 so it's a good idea to start from those, then try the others if the search won't find the right address.

    Finally, a few last remarks about the "value" parameter. First off, it's already been stated before but it should still be stressed out that the number you're looking for must be an integer: it should not contain a decimal point nor a sign. Second, unlike other memory editing software which use hexadecimal values, the value here should be decimal (if you don't know what that means, don't worry - it's actually a good thing if you're a beginner as you won't have to fiddle around with a calculator as much :P)
    You should really keep both of those in mind: sys-netcheat will treat the value as 0 if you input an invalid one, and it'll do so without returning any errors!

    So, now that we're done with all of that, it's time for a quick recap! I'll list a few correct and incorrect examples below so you can check if you've got everything I've explained so far:
    ssearch u32 1105
    ^ CORRECT!

    ssearch u64 3204099
    ^ CORRECT!

    ssearch u8 1105
    ^ INCORRECT! (Value exceeds range of u8)

    ssearch u16 3.50
    ^ INCORRECT! (Value includes a decimal point)

    ssearch u32 -10
    ^ INCORRECT! (Value includes a sign)

    ssearch u16 10FF
    ^ INCORRECT! (Value is hexadecimal)

    ssearch u64 Hello
    ^ INCORRECT (Value is not a number)

    Now, back to my game. I want to edit how many lives I have and the counter says I currently have 140. So, in order to search for the value, I'll use the following command:
    Code:
    > ssearch u32 140

    If I were to use the GUI instead, I'd put 140 in the "Value" field, choose u32 in Value Size and then click on "Search":
    search-gui.png

    The game will freeze for a bit (it will stay frozen until the search is over, have patience!) and a list of addresses will start showing up onscreen...
    Code:
    -There were around 200 lines above this one-
    Got a hit at 3b117ac008!
    Got a hit at 3b117ae900!
    Got a hit at 3b117af67c!
    Got a hit at 3b117bcbdc!
    Got a hit at 3b117beed4!
    Got a hit at 3b117bfa78!
    Got a hit at 3b117c46b4!
    Got a hit at 3b117c630c!
    >

    ...that's too many. A few hundreds too many be exact. Luckily, there's another command that allows you to continue our search and get more accurate results:
    Code:
    csearch value                        | Searches the hits of the last search for the new value

    This one is much easier to understand: you can use it to make the program go through the search results again and check if any of them now contain the newly specified value. If you know the value you're looking for has changed ingame, you can use it to shrink down the list and pinpoint the right address!
    (You won't have to worry about data types this time as csearch will just reuse whichever you've specified before)

    To give you an idea of a real use scenario, let's go back to Kirby. I've already started the search before when I had 140 lives so I'll now purposely lose one to decrease the counter...

    dead.jpg

    ...which is already kind of an achievement of its own in this game.​

    Now I have 139 lives, so I know the value has changed. I'll wait until I respawn and then I'll use the following command to continue the search:
    Code:
    > csearch 139

    Which returns the following addresses...

    Code:
    Got a hit at 3aa1a02e04!
    Got a hit at 3ac397c420!
    Got a hit at 3ac397c480!
    Got a hit at 3ac4ae3678!
    Got a hit at 3ad6e87aa0!
    >
    They went from hundreds of addresses to only five. That's muuuuch better. We can proceed to the next step!

    Changing a value stored in memory

    Now that you have a small list of addresses you can work with, it's time to start changing values around until you find the right one. Of course, there's a command for that:
    Code:
    poke address u8/u16/u32/u64 value    | Sets the memory at address to value

    As you can see, it's pretty simple: you grab one of the addresses from the result, specify what data type it contains (the same you've used for ssearch) and the new value you want to set it to.
    So, if I want to change back the lives to 600 in my game, I'll have to send it like this...
    Code:
    > poke 3ac4ae3678 u32 999
    ...and repeat it for every address in the list until I find the right one.

    In the GUI, you can simply double click on one of the address returned from the search. A popup will appear which asks you to input the new value:
    sdfdsf.png
    (Additionally, you can also click on the big + button to enter an address manually)

    life.gif

    And just like that, I now have a ludicrous amount of lives!​

    But what if I could have... literally infinite lives?

    Freezing values

    sys-netcheat has one additional function: freezing. When used, the tool will check if a value changes at your specified memory address and, if it does, it'll automatically revert it back to whatever value you want.
    This is useful in two different scenarios: the first one is if you want infinite lives/items/coins/etc. and the second is to help with some games which will actively try to deter you from cheating by changing the value back when they detect you may be doing something fishy.
    This command's syntax is basically the same as poke:
    Code:
    afreeze address u8/u16/u32/u64 value | Freezes the memory at address to value
    Just as before, get one of the addresses from the results, specify the same data type as the one you've used to search and set the value to whatever you want. Once you send the command, you can double check if the address has been frozen by using:
    Code:
    lfreeze                              | Lists all frozen values
    ...Which does exactly what it says and requires no arguments. Finally, if you want to unfreeze a previously frozen address, you can use:
    Code:
    dfreeze index                        | Unfreezes the memory at index
    The "index" parameter here is the number of the address as reported by lfreeze.

    It's time to get back to Kirby once more. I'll use this command to essentially get infinite lives:
    Code:
    > afreeze 3ac4ae3678 u32 999
    The counter will still show 999 lives, however it won't decrease anymore!
    Once I want to turn Kirby back to a mere mortal, I'll first use lfreeze and then dfreeze like so:
    Code:
    > lfreeze
    0) 3ac4ae3678 (u32) = 999
    > dfreeze 0

    Freezing addresses from the GUI is also very simple: once you have an address on the table (by either selecting one from the search results or inserting one manually), you can use the little checkbox on the leftmost row to freeze/unfreeze the address:
    ghfhgf.png

    Now, some of you who already tried sys-netcheat could think "Well, so far this is a bit more detailed and up to date rather than the guide in the ReadMe but so far I didn't learn much more than what I already knew!"
    If that applies to you, don't you worry: we were just getting started! :P

    If you ever get stuck, check the last part of this guide (the FAQ)!

  4. So, if you've been paying attention you'll know by now that the addresses you've found will no longer work if you close the game. This means whenever you want to use a cheat you'll have to search for your specific value every time... right?

    Well, yes and no. You see, the problem here is caused by the game's base address changing every time you open it. This isn't a problem for more advanced memory editors which will automatically give you relative addresses (for example, Cheat Engine on Windows does that), however sys-netcheat only supports absolute addresses, meaning that it doesn't take into account the process' base one at all.

    And here is where things get interesting: most of the time what actually changes is just the base address, not the relative ones of a specific value (unless the program itself is made to do so). This also applies to games running on the Switch so, if we can find a way to make our addresses relative, we can effectively just make a single initial search and then work by ourselves from there!

    Now, there is no easy way to get the process' base address using sys-netcheat but this doesn't mean we're out of luck. In fact, we can use a dead simple yet effective trick: we're going to search for a value that never changes in our game's memory and make out addresses relative to that one instead.

    This is usually as easy as looking for an u64 with value 0 and picking the first result. However, be extra sure that whatever you've picked will actually stay the same all the time! In order to do so just play the game for a while - test different levels, areas, battles, etc and make constant searches. If your address pops up everytime, you've got yourself a good candidate!

    Once you've got it, all you have to do is to subtract the address you've just got to the ones you've previously found - just keep in mind that the addresses are shown as hexadecimal so remember set your calculator to HEX :P

    Then, once you open your game once more, it's time to do the opposite: search for that same value again, get the new address and add the result of the aforementioned subtraction to it. Yes, it's that simple.

    Here's the mandatory Kirby example:
    I closed the game then reopened it so I got new addresses. I've searched for the lives' memory addresses again, which this time is:
    Code:
    2c694e3678

    Now I'll search for an address that never changes its value so I can make the above address relative:
    Code:
    > ssearch u64 0
    > Got a hit at 2bf1e00018!
    Got a hit at 2bf1e00038!
    Got a hit at 2bf1e00040!
    Got a hit at 2bf1e00048!
    ...
    I'll play the game for a bit and perform the same search again. Sure enough, the first hit always pops up: it means there's a good chance it indeed never changes!

    It's time to bring up the calculator (most support hex notation including Windows' own, but if for some strange reason yours doesn't then use this one). Now, all I have to do is to subtract the base address to the life counter's:
    Code:
    2c694e3678 - 2bf1e00018 = 776E3660

    It's time to close and re-open the game to check if the trick worked. When I'm in-game I'll perform the same search and pick the first result again:
    Code:
    > ssearch u64 0
    > Got a hit at 6ae3a00018!
    Got a hit at 6ae3a00038!
    Got a hit at 6ae3a00040!
    Got a hit at 6ae3a00048!
    Got a hit at 6ae3a00058!
    ...

    Now, let's add the value we've found to that address...
    Code:
    6ae3a00018 + 776E3660 = 6b5b0e3678

    That's it! (It does kinda look like the old one, right? :P)
    From here, it's time to test it using poke or freeze. If it does work (and mine did), you've got yourself a way to make all your addresses relative, thus making them persist reboots, crashes and whatnot!

    Keep in mind that the offsets may change between different game languages, versions, revisions and the like! If a new version of the game gets released, for example, you may have to perform searches again to find the value and recalculate the relative offsets.
    (The above is true for basically all platforms ever released, but it's always good to remind it)

    That's it, really - a simple trick that solves an immensely annoying problem. It'll also be absolutely crucial for what we're going to do next.

  5. And now we've reached what I think is the best part. Here we're going to mix pretty much everything I've told you so far so be sure to have had a good amount of practice before reading. A good knowledge of a scripting language is also recommended (I'm going to use Bash and Batch scripts here as they're some of the most common, but you can easily adapt this to whatever language you want).

    Netcat is known as "the swiss army knife of TCP/IP connections" for a reason. What we're using it for here is to act as a way to interface us with sys-netcheat, however it can do much, much more. While a lot of the additional functions aren't compatible or necessary for our goals, one thing that's going to be extremely useful to us is that it's been made with scripting in mind and you bet we're going to take advantage of that here.

    One thing worth mentioning is that while the following instructions will be good for Windows, macOS and Linux, they will need to be changed a bit to work on Android as Termux uses a slightly different version of netcat. This will be covered in the next part.

    First off, if you've been playing with netcat a bit, you've probably noticed that the are a few switches to execute a script or command through it (such as -c, -e, --lua-exec). Those cannot be used in our case as sys-netcheat doesn't actually provide a remote shell. However, netcat also accepts inputs via stdin and this will indeed work here. So, we can just echo our command and pipe it to netcat, for example:
    Code:
    echo "help" | nc switch_ip 5555
    Will show the help screen as soon as it connects to our Switch! Still, netcat will wait for another command instead of quitting as soon as it's done printing stuff onscreen. This can be avoided by using the -w switch, which acts as a timeout if the connection stays idle for the specified number of seconds. Add a little stdout redirection to a file and we've got this:
    Code:
    echo "help" | nc -w 3 switch_ip 5555 > out.txt
    In the above example netcat will connect to sys-netcheat, send the "help" command, wait for 3 seconds until the connection times out and write the result to a file called out.txt. This little command is already useful per se: you could make shortcuts to perform searches, change specific values (in this case writing to a file is not necessary) or list frozen addresses with a single click.

    Still, why stop there? With a few additions we can make a simple script that allows us to use relative addresses with ease:
    Code:
    #!/bin/bash
    IP='192.168.1.200'
    RELADDR='776E3660'
    BASTXT='base.txt'
    
    HEX='0x'
    if [ ! -f $BASTXT ]; then
       OUTFILE='search.txt'
       SEARCH='ssearch u64 0'
       echo $SEARCH | nc -w 4 $IP 5555 > $OUTFILE
       LCNT=$(wc -l < $OUTFILE)
       if (( $LCNT >= 3 )); then
           BAS=$(sed -n 3p $OUTFILE | cut -c 16- | cut -d "!" -f1)
           echo -n $HEX$BAS > $BASTXT
       else
           echo "[ERROR] - Could not get search results!"
       fi
       rm $OUTFILE
    fi
    BAS=$(cat $BASTXT)
    NEWDEC=$(($BAS+$HEX$RELADDR))
    NEWADDR=$(echo -n 16o${NEWDEC}p | dc )
    echo "poke $NEWADDR u32 100" | nc -w 1 $IP 5555 > /dev/null
    NOTE: This script uses GNU bc to get around some limitations of Batch, which you can download from here. Put netcat (nc), bc and the script itself in the same directory.
    Code:
    @echo off
    set IP="192.168.1.200"
    set RELADDR=776E3660
    set BASTXT=base.txt
    
    if exist %BASTXT% goto send
    
    set OUTFILE="search.txt"
    set SEARCH=ssearch u64 0
    
    echo %SEARCH% | nc.exe -w 4 %IP% 5555 > %OUTFILE%
    set "BAS="
    for /F "skip=2 delims=>!" %%I in (search.txt) do if not defined BAS set "BAS=%%I"
    set BAS=%BAS: Got a hit at =%
    if "%BAS%" == " Got a hit at =" (goto baserror)
    set BAS=%BAS:a=A%
    set BAS=%BAS:b=B%
    set BAS=%BAS:c=C%
    set BAS=%BAS:d=D%
    set BAS=%BAS:e=E%
    set BAS=%BAS:f=F%
    echo %BAS% > %BASTXT%
    del %OUTFILE%
    goto :send
    
    :send
    set /P BAS= < base.txt
    echo obase=16;ibase=16;%BAS%+%RELADDR% | bc.exe -l > temp.txt
    set /P NEWADDR= < temp.txt
    del temp.txt
    echo poke %NEWADDR% u32 100 | nc.exe -w 1 %IP% 5555 > nul
    goto end
    
    :baserror
    echo [ERROR] - Could not get search results!
    pause
    
    :end
    Using the scripts above is simple: you just need to edit the IP and RELADDR variables, putting your Switch's IP and relative address there respectively. You can also edit the BASTXT (name of the text file containing the base address), OUTFILE (name of the temporary text file storing the search results) and SEARCH (parameters for the initial search, this usually doesn't have to be changed as previously said) variables if you want to have a little bit more customization.

    How the scripts work is simple: first, they'll look for a file containing the base address. If it's not found, they'll search for it in the game's memory using some predefined search parameters (default: ssearch u64 0, then get the first address from the list). On the other hand, if the file is found then the base address is loaded from it and a relative address will be calculated using the value stored in RELADDR. Finally, a command is executed to write a predefined value located at the previously calculated address (default: poke with datatype u32 and value 100, if you want to edit the command go to line 23 [Bash] or 30 [Batch]).

    Those scripts can already prove useful by themselves as they make working with relative addresses a fairly straightforward procedure, however they have a much, much bigger potential. You know what happens when we get a bunch of relative addresses, the scripts above, a simple menu and mix it all together?

    We get ourselves our very own basic game trainer!

    Code:
    #!/bin/bash
    BASTXT='base.txt'
    
    reladdr () {
    HEX='0x'
    if [ ! -f $BASTXT ]; then
       OUTFILE='search.txt'
       SEARCH='ssearch u64 0'
       echo "Finding base address - this must be done only once each time you open the game/trainer, please wait..."
       echo $SEARCH | nc -w 4 $IP 5555 > $OUTFILE
       LCNT=$(wc -l < $OUTFILE)
       if (( $LCNT >= 3 )); then
           BAS=$(sed -n 3p $OUTFILE | cut -c 16- | cut -d "!" -f1)
           echo -n $HEX$BAS > $BASTXT
       else
           echo "[ERROR] - Could not get search results!"
       fi
       rm $OUTFILE
    fi
    BAS=$(cat $BASTXT)
    NEWDEC=$(($BAS+$HEX$2))
    NEWADDR=$(echo -n 16o${NEWDEC}p | dc )
    echo "Sending command..."
    echo "$1 $NEWADDR $3" | nc -w 1 $IP 5555 > /dev/null
    echo "Done!"
    }
    
    PS3='Select: '
    CHEATS=("Set lives to 999 (Green Gardens)" "Set lives to 999 (World Map - Dream Land)" "Infinite lives (Green Gardens)" "Always have 99 stars (Green Gardens)" "Set stars to 99 (World Map - Dream Land)" "Clear base address (choose this first if you closed your game)" "Quit")
    if [ -f $BASTXT ]; then
       rm $BASTXT
    fi
    echo "- Kirby Star Allies v1.0.0 (ENG) +5 Trainer -"
    echo "Part of the sys-netcheat 101 guide by RattletraPM"
    echo
    echo -n "Please input your Switch's IP address: "
    read IP
    if [ -z "$IP" ]; then
       echo "You need to input your Switch's IP address. Quitting..."
       exit 1
    fi
    echo
    select CHOICE in "${CHEATS[@]}"
    do
        case $CHOICE in
            "Set lives to 999 (Green Gardens)")
                reladdr 'poke' '776E3660' 'u32 999'
                ;;
            "Set lives to 999 (World Map - Dream Land)")
                reladdr 'poke' '614B7DB0' 'u32 999'
                ;;
            "Infinite lives (Green Gardens)")
                reladdr 'afreeze' '776E3660' 'u32 999'
                ;;
       "Always have 99 stars (Green Gardens)")
                reladdr 'afreeze' '776E3664' 'u32 99'
                ;;
       "Set stars to 99 (World Map - Dream Land)")
                reladdr 'poke' '614B7DB8' 'u32 99'
                ;;
       "Clear base address (choose this first if you closed your game)")
                rm $BASTXT
                ;;
            "Quit")
                break
                ;;
            *) echo "Invalid selection!";;
        esac
    done
    NOTE: Again, this script uses GNU bc to get around some limitations of Batch, which you can download from here. Put netcat (nc), bc and the script itself in the same directory.

    Code:
    @echo off
    set IP=""
    set CMD=""
    set ARGS=""
    set RELADDR=""
    set BASTXT=base.txt
    if exist %BASTXT% del %BASTXT%
    echo - Kirby Star Allies v1.0.0 (ENG) +5 Trainer -
    echo Part of the sys-netcheat 101 guide by RattletraPM
    echo.
    set /p IP="Please input your Switch's IP address: "
    if %IP% == "" goto iperror
    echo.
    echo 1) Set lives to 999 (Green Gardens)
    echo 2) Set lives to 999 (World Map - Dream Land)
    echo 3) Infinite lives (Green Gardens)
    echo 4) Always have 99 stars (Green Gardens)
    echo 5) Set stars to 99 (World Map - Dream Land)
    echo 6) Clear base address (choose this first if you closed your game)
    echo 7) Quit
    goto choice
    
    :choice
    set /P choice=Select:
    goto %choice%
    
    :1
    set CMD=poke
    set RELADDR=776E3660
    set ARGS=u32 999
    goto check
    
    :2
    set CMD=poke
    set RELADDR=614B7DB0
    set ARGS=u32 999
    goto check
    
    :3
    set CMD=afreeze
    set RELADDR=776E3660
    set ARGS=u32 999
    goto check
    
    :4
    set CMD=afreeze
    set RELADDR=776E3664
    set ARGS=u32 99
    goto check
    
    :5
    set CMD=poke
    set RELADDR=614B7DB8
    set ARGS=u32 99
    goto check
    
    :6
    if exist %BASTXT% del %BASTXT%
    goto choice
    
    :7
    goto end
    
    :check
    if exist %BASTXT% goto send
    
    set OUTFILE="search.txt"
    set SEARCH=ssearch u64 0
    
    echo Finding base address - this must be done only once each time you open the game/trainer, please wait...
    echo %SEARCH% | nc.exe -w 4 %IP% 5555 > %OUTFILE%
    set "BAS="
    for /F "skip=2 delims=>!" %%I in (search.txt) do if not defined BAS set "BAS=%%I"
    set BAS=%BAS: Got a hit at =%
    if "%BAS%" == " Got a hit at =" (goto baserror)
    set BAS=%BAS:a=A%
    set BAS=%BAS:b=B%
    set BAS=%BAS:c=C%
    set BAS=%BAS:d=D%
    set BAS=%BAS:e=E%
    set BAS=%BAS:f=F%
    echo %BAS% > %BASTXT%
    del %OUTFILE%
    goto :send
    
    :send
    set /P BAS= < base.txt
    echo obase=16;ibase=16;%BAS%+%RELADDR% | bc.exe -l > temp.txt
    set /P NEWADDR= < temp.txt
    del temp.txt
    echo Sending command...
    echo %CMD% %NEWADDR% %ARGS% | nc.exe -w 1 %IP% 5555 > nul
    echo Done!
    goto choice
    
    :baserror
    echo [ERROR] - Could not get search results!
    
    :iperror
    echo You need to input your Switch's IP address. Quitting...
    goto end
    
    :end

    And presto, here's they are! I've uploaded everything to a ZIP for your own convenience, which you can download from here.

    Before calling it a day, however, keep in mind when making a trainer to always specify for which game version, language, etc. it's meant for. As said before, different game versions/revisions/languages/etc. may break your stuff so always take your time to test things out and let the user know what is compatible and what isn't.

    Oh, and one last note too: all the code you see here is released under the WTFPL. You're free to modify, improve, break, share and generally do whatever you want with it. Go nuts.

  6. If you've been paying attention in the previous part (hopefully) you've read that the scripts won't work out of the box in Termux. What gives? It has a Bash shell and netcat so they should just fine!
    Well, spoiler alert, not quite. It's true, the shell is indeed Bash but as it turns out, Termux has been lying to you about netcat all along! Dun-dun-dunnnnn~!

    Here's what I mean: the netcat package doesn't actually provide one of the many netcat variations out there: it installs Ncat instead, which is a different tool compatible with the former with the same command name. However some of the switches are different, so we'll need to take that into account.

    What we need to do is very simple: netcat's -w switch corresponds to Ncat's -i switch. So we need to replace every occurrence of this:
    Code:
    nc -w
    With this:
    Code:
    nc -i

    If you do so, the scripts will run just fine! If you don't know how to run them in Termux I advise you to copy them to your internal storage, follow this guide to allow access your phone's storage and then run the following commands (be mindful to replace fname with your script's filename):
    Code:
    cp ~/storage/shared/fname .
    chmod +x fname
    After that, you can just run it as any other shell script from your home directory (aka, like so: ./fname)

    However, there's something even better you can do on Android. If you don't fancy the idea of using a terminal emulator on the go to access your cheats, I feel you, it is a bit impractical afterall. Luckily Termux gives us an alternative, Termux:Widget!

    Thanks to it, you'll have a quick way to run your scripts from your home menu. You can get it from Google Play but it costst around 2 EUR there, however they're free on F-Droid (no, that's not piracy - both listings are official and reportedly the Google Play one is not free as it's a way to support the developer)

    Protip: You can download Termux:Widget's APK from the link above without installing F-Droid's app, just keep in mind that in order to work both Termux and Widget must be installed from the same source (installing one from Google Play and the other from F-Droid won't work!)

    Once that's said and done, a folder called .shortcuts should have been created in your home dir (check with ls -a, if there is none then create it). All you need to do is to copy your scripts in there (remember to mark them as executable!), then put the widgets on your home screen.

    There are two available: one lists all the scripts in the aforementioned folder and the other is a quick launch button for a specific scripts. Choose whichever combination you like!

    photo5989959492529402514.jpg

    This, combined with Rekado and a mobile hotspot can really turn your phone into the ultimate RCM injector setup :P

    • Q: sys-netcheat won't let me connect after I put the Switch to sleep/I connect a lot of times!
    • A: This is sadly a known issue and there's no solution at the moment. A workaround is to use Atmosphère's reboot to payload to reboot your Switch but, of course, it's a bit awkward. Still, it works for the time, until the dev finds a fix at least.

    • Q: You've mentioned unsigned integers but how do I search for other data types? (eg. strings, signed integers, floats,...)
    • A: It's possible to find those using sys-netcheat but it's a bit more complicated than it needs to be. For example, I've succesfully replaced strings both in homebrew games and Pokèmon LGPE, however you need to take into account several things in order to do so (string encoding, endianess, zero-termination and also the length will probably exceed whatever data type you chose). If you want to search for strings then just keep in mind that most official Switch games will use wide chars to provide Unicode support. Signed integers are technically more feasible (use two's complement) but don't even bother with floats and doubles, sys-netcheat is just too barebones for that.

    • Q: A cheat I've made works in some levels/screens/occasion but doesn't in others!
    • A: Different games have different quirks. For example, you may have noticed the cheats I've made for the lives in Kirby are different for a single level and the world map. It's just due to how the game is made - for example in Sonic Mania Plus this doesn't happen but the life counter is tied to whatever save slot you're using. Sometimes you may even have to change different addresses.

    • Q: I can't find a value!
    • A: Are you sure you're looking for the right one and it's an integer? If so, try again - patience and perseverance are key here!
no port yet for reinx
 

cucholix

00000780 00000438
Member
Joined
Jan 17, 2017
Messages
3,246
Trophies
1
Age
44
XP
6,271
Country
Chile
Is there any compatibility issues with other system modules (NX-Shell, emuiibo, maylady, freebird)? I read that they were fixed but worth asking just in case.
 
Last edited by cucholix,

Phenj

Well-Known Member
Member
Joined
May 22, 2018
Messages
493
Trophies
0
XP
1,895
Country
Italy
Is it possible to use this with a perma offline console? Maybe via USB connection. I'm talking about netloader - sysgui communication
 

Sptn777

New Member
Newbie
Joined
Jan 28, 2020
Messages
2
Trophies
0
Age
33
XP
38
Country
Mexico
Can anyone help me please, I use atmosphere but I won’t connect at all, debug mode it’s set to 1 and I have on modules and, atmosphere/kips modules But I won’t connect

i tray to use it with hekate but when I choose cfw+sys-net....it says wrong ini cfg or missing files failed to launch can any one upload their files just to put them on the SD
 

adrianrosariopr

New Member
Newbie
Joined
Aug 6, 2020
Messages
4
Trophies
0
Age
35
Location
Columbia, MO
XP
40
Country
United States
hello guys!
can anyone know how to cheat infinite health in the zelda botw?
Here is what I am currently using and it worse pretty good.

Code:
[Infinite Health]
580f0000 02ca1a78
580f1000 00000080
780f0000 00000848
610f0000 00000000 00000078

[Max Hearts]
580f0000 02c9fd70
580f1000 00000038
780f0000 000002a8
640f0000 00000000 42f00000
 

Master Dimentio

The Pleaser Of Crowds
Member
Joined
Feb 17, 2016
Messages
696
Trophies
0
Age
34
Location
Making my perfect world.
Website
www.youtube.com
XP
852
Country
United States
Sorry for reviving a dead thread, but I am trying to use this sys-netcheatGUI and I am unsure the proper way to set up the SD card if you are using Fusee. I've managed to get the program to actually connect with my switch's IP address, but if I try to search a value for the game itself, it doesn't ever get any hits no matter how long I sit and wait. It will say searching but I've sat there for like 10 minutes and it's done nothing. What do I need to do to fix this?
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: @SylverReZ, Indeed lol