ROM Hack Unlocking online functionality using gateshark2ntr

  • Thread starter Thread starter Mr_Waffles
  • Start date Start date
  • Views Views 1,833
  • Replies Replies 16

Mr_Waffles

Intellectual saviour of the masses
Member
Joined
Feb 6, 2017
Messages
510
Reaction score
132
Trophies
1
Location
East Northamptonshire
XP
1,165
Country
United Kingdom
I was wandering if anyone could point me in the right direction yo get the main.o file to unlock online for use with Ntr plugins. And don't day use Google as I have and I get nothing.
 
I wouldn't expect to get any help here, most of us strongly oppose cheating online. So, "use Google" is likely as much assistance as you'll get.

Sorry (not really).
 
I'd also like to know, well, create my own cheats that is, or even just understand how it's done XD
 
Aaaaand as if summoned by a forbidden ritual, @DarkFlare69 appears suddenly.

DarkFlare69 is probably the most morally ambiguous member here (no offence intended) with the knowledge you seek. If he won't help you, no one will (although it might cost you).
That's a nice way to put it lol

Care to teach me
It would take too long to teach you every step, especially if you have no prior programming knowledge. I could give you a few examples and show how a gateway code works. From that point you can use both of these skills to convert most codes. I'll type up a little when I go on my PC
 
  • Like
Reactions: Bluespheal
First, you should keep this tab open as a reference: http://doc.kodewerx.org/hacking_nds.html
It contains all of the codetypes that Gateway codes use. The first character in each line (in one of the standard codetypes) is the codetype, and the following 7 characters is the offset to add onto the previously computed offset (such as a pointer or a "set offset" codetype). The 8 characters seperated by a space is the value (in the standard codetypes, not including D6000000 and stuff)

Let's look at some examples:
Code:
Perfect Timer
6065C528 00000000 // 6 codetype means if not equal to. So what it's doing is it's checking if the address 0x65C528 is not equal to 0. If it is not equal, continue executing the code. If it is equal, skip that block of code and then reset the execution status to true.
B065C528 00000000 // B codetype means pointer. So it's reading the value at the address 0x65C528 and then setting that value as the offset. The 00000000 means nothing; any pointer code will always have this.
00000080 00000000 // add 0x80 to the previously computed pointer and then write 32 bits containing 0x00000000 to that address.
D2000000 00000000 // Terminator

Converted code:
Code:
u32 offset = 0; // Create "offset". For your purposes, you only need this once in the cheats.c file, not for every code

void    PerfectTimer(void) // Code name. Make sure to not have any spaces
{
    if (READU32(0x065C528) != 0x00000000) // Check if value at 0x65C528 is not equal (!=) to 0x00000000
    {
        offset = READU32(0x065C528); // Set "offset" equal to the value at 0x65C528
        WRITEU32(0x80 + offset, 0x00000000); // Add 0x80 onto the integer in "offset" and write 32 bits of 0x00000000 to it
    }
}
Optimized code:
Code:
void    PerfectTimer(void)
{
    if (READU32(0x65C528) != 0)
    {
        offset = READU32(0x65C528);
        WRITEU32(0x80 + offset, 0);
    }
}
Another example:
Code:
D3000000 30000000 // set offset to 0x30000000
21234568 000000FF // write 8 bits to 0x1234568 + offset, containing 0xFF
D2000000 00000000 // terminator
Converted code:
Code:
void    code(void)
{
    offset = 0x30000000; // set offset to 0x30000000
    WRITEU8(offset + 0x1234568, 0xFF);
}
I'm kind of lacking on the examples, but I don't want to take too long to explain all of this. If you have a question about how to convert a specific codetype not shown above, then I can tell you for that. However, you can use common sense to figure out some of the similar codetypes. For example, != means not equal, so replace that with == to get equal. Replace WRITEU32 or WRITEU8 with WRITEU16 to write 16 bits.

Once you're done, download this: https://github.com/RyDog199/blankCheatMenu

Throw the codes into Sources/cheats.h and copy the names of the codes into Sources/cheats.h with a semicolon after the final character in each line. In Sources/create_menu.c you can use this format:
Code:
new_entry("Visible Name", InternalName);
 
Last edited by DarkFlare69,
  • Like
Reactions: Bluespheal
Code:
u32 offset = 0; // Create "offset". For your purposes, you only need this once in the cheats.c file, not for every code

void    PerfectTimer(void) // Code name. Make sure to not have any spaces
{
    if (READU32(0x065C528) != 0x00000000) // Check if value at 0x65C528 is not equal (!=) to 0x00000000
    {
        offset = READU32(0x065C528); // Set "offset" equal to the value at 0x65C528
        WRITEU32(0x80 + offset, 0x00000000); // Add 0x80 onto the integer in "offset" and write 32 bits of 0x00000000 to it
    }
}

I noticed that you use READU32 and WRITEU32, it is okay to use C/C++ standard when dealing with pointers? For example (It has been a while since I dealt with pointers, so my example could be wrong):
Code:
u32 *offset = 0x065C528;

if (*offset != nullptr)
{
    *(*offset + 0x80) = 0x00000000;
}
 
That was super useful! I don't know how to program in C nor C++ (yet), but as you've said it seems to be a matter of going off one example and figuring out the rest, one question though, how do you get the offsets of the values you want?

for example, the address of the timer (065C528), is there a plugin or an option in luma that points toward one of these values or how exactly do you find what you want to edit or mess with?
 
I noticed that you use READU32 and WRITEU32, it is okay to use C/C++ standard when dealing with pointers? For example (It has been a while since I dealt with pointers, so my example could be wrong):
Code:
u32 *offset = 0x065C528;

if (*offset != nullptr)
{
    *(*offset + 0x80) = 0x00000000;
}
yeah, i did it with readu32 and writeu32 to make it simpler for people who dont know as much about c/c++

That was super useful! I don't know how to program in C nor C++ (yet), but as you've said it seems to be a matter of going off one example and figuring out the rest, one question though, how do you get the offsets of the values you want?

for example, the address of the timer (065C528), is there a plugin or an option in luma that points toward one of these values or how exactly do you find what you want to edit or mess with?
Yes, for simple things like this, going off of a few examples is all it takes to learn enough to do a few yourself.

You find addresses by searching for differences in the thing you want to modify in the RAM. For example, let's say we want to give ourselves 100 coins in a game. Search for your current number of coins and that will store all of the addresses that contain that value, which will likely be in the thousands. Gain or lose a few coins, search for that new number, and it'll refine the results. Eventually after enough searches, you should get a few addresses that store your coin amount. Write 0x64 (equal to 100 in decimal) to those address(es) and that's it.

For unknown searches, let's say you're looking for your coordinates in a game to make moonjump or something. Each axis is stored at it's own address, so you're only going to focus on one. Keep in mind which axis you're looking for, so choose X or Y or Z (only X/Y if it's a 2d game) and then do an unknown search. Only focus on that 1D axis. So move a little to one side (X: left is greater and right is less, Y: up is greater and down is less, Z: forward is greater, back is less) and then search for the corresponding condition in parentheses. So if you moved to the left on the X axis, your coordinates will be greater than before, so you'll search greater than. Continue moving and searching and eventually you'll find that axis. All 3 axes are always (from what I've seen) right next to each other. Now to make a moonjump you could do something like this

DD000000 00000800 // If Y is pressed
D6000000 12345678 // load value at 0x12345678. lets pretend this is your Y axis
D4000000 00050000 // add 0x50000 to that value
D9000000 12345678 // store it back
D2000000 00000000 // terminator
 
  • Like
Reactions: CuriousTommy
Oh, of course, that makes a lot of sense, a few more questions; this one is kinda more important and specific, how do you look into the RAM in real time? is there a plugin or a menu with this info?

and how would you go on altering things such as collision? I'd assume by checking certain actions that disable collision and comparing addresses (kinda how you get coordinates, but I assume collision is just a flag)
 
Oh, of course, that makes a lot of sense, a few more questions; this one is kinda more important and specific, how do you look into the RAM in real time? is there a plugin or a menu with this info?

and how would you go on altering things such as collision? I'd assume by checking certain actions that disable collision and comparing addresses (kinda how you get coordinates, but I assume collision is just a flag)
You can use Gateway or CTRPF to look at the RAM in realtime

yeah that sounds right. that's slightly more difficult but it's still doable. or you can try and search for hitbox. I did this for MK8 by using a big character, doing an unknown search, and then using a smaller one and doing less than. Repeat
 
  • Like
Reactions: Bluespheal

Site & Scene News

Popular threads in this forum