How to find pointers on NTR Debugger memory dumps? (NTR CFW)

Discussion in '3DS - ROM Hacking, Translations and Utilities' started by omegapirate, Feb 23, 2016.

  1. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    So on the last couple of weeks I've been working on several cheat methods (RAM hacking, ROM hacking and Save Data Editing) but one thing I can't figure out are pointers!

    Sure dumping a few times the RAM and finding then changing a static value is extremely easy to do, but finding the address that writes on that dynamic address is the real challenge.

    Now, obviously pointers are extremely easy to find when running (or reading memory live) a game on an emulator like Citra, but the problem is that not all games are supported on this moment. I have found several pointers on FE:A with Citra and Cheat Engine and it was extremely easy!

    The question is, how can I find pointers while dumping memory with ntr debugger?

    Is there any way I can read live the ram memory of the 3ds? If so, that would be extremely helpful on finding pointers.

    Another thing I've found is that it seems that Gateway can help in finding pointers with some PC software and dumping ram, but it seems that it uses very different memory regions than that of ntr debugger. (Physical or virtual memory, perhaps?!)

    I've been searching around and really haven't found any way to find pointers with memory dumps so I'm wondering what people here say/know about it. :)
     


  2. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Well I bought a gateway card as it seems its a lot easier to find pointers that way.

    Once I get it and find some pointers, I'll update.
     
  3. DesuIsSparta

    DesuIsSparta GBAtemp Advanced Fan

    Member
    542
    174
    Oct 13, 2015
    United States
    Weaboo land
    Unfortunately, the closest thing you can do at the moment is hook into the NTR TCP protocol yourself and handle the returned bytes that way..

    The 3DS is extremely slow, and since NTR sends the read RAM in it's own packet via TCP on LAN, it is incredibly slow. It can take 4 full minutes to receive. You can program it so you can read the bytes while they're being returned but it's a mess unless you're experienced with that... i'm not.

    Cell9 is not releasing the source for NTR, so we won't really ever be able to contribute and see if optimization is an option. Also, he only logs in the forum once in a while and his native language is Chinese so conversations are possible but short.

    The fastest way at the moment seems to be with Gateway... I wish I had a Gateway. There's no other way I can think of to access the RAM instantly, since it can only be done from the console itself.
     
    Last edited by DesuIsSparta, Feb 26, 2016
  4. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Yea I read in many forums Gateway is the way to go when reading RAM live. I think if they could do it, I can code an app that works in a similar way than gateway on that regard and associate it with ntr or create another solution altogether.

    Either way, when the gateway card arrives ill try to find a few pointers and update this thread.
     
  5. DesuIsSparta

    DesuIsSparta GBAtemp Advanced Fan

    Member
    542
    174
    Oct 13, 2015
    United States
    Weaboo land
    Honestly the only thing I can think of, is engineering a device similar to gateway which functions solely as a RAM box, and has a fast enough (50mb/s) transfer speeds. Perhaps USB 3.0 is the way to go there.. Costs a bunch of money and won't really be worth it in the end.. but I can't think of a solution that doesn't involve modding the device.
     
  6. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    That's interesting. I wonder how hard it would be to code one.
     
  7. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    I just got my gateway card. I will be playing with it and I-ll report back with finding pointers
     
    DesuIsSparta likes this.
  8. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Ok so I've been playing with the gateway card and I've been dumping ram to find pointers.

    IT'S A SUCCESS! I could certainly find pointers for some values!

    Now the biggest problem I have is that to create a ntr plugin I >NEED< to read that pointer address to get the value address for me to write whatever value I want.

    For example, a pointer is 0x145EAEB0 which value is 80455c15 (or 0x155c4580). Then at 0x155c4580 I find my 4byte value, the one the game uses. (i.e. 6101 or 353 in decimal).

    Now, the code I believe it should work on a ntr plugin is:

    Code:
    int valueG = READU32(0x145EAEB0);
    WRITEU16(valueG, 0x0000FFFF);
    But the only problem I have is actually reading the pointer address which contains the dynamic address.

    Does anyone know how I can do that?

    It's really easy to do it with NTR Debugger [ read(0x145EAEB0, 0x4, pid=0x29) ] but I would totally prefer to make it work in one single cheat.plg file without me reading the pointer manually from NTR Debugger.

    Any help? Or anyone that can help on this? Or does anyone know someone that can help with this?

    I'm sure if I can figure this out, finding cheats with GW and then translating to NTR would help in creating a lot more cheats!

    PS: Once I find a way to read an address within the plg file, I will make a tutorial on how to do everything and how to find the pointers! ;)
     
    Last edited by omegapirate, Mar 9, 2016
  9. MichiS97

    MichiS97 "Leftist snowflake milennial"

    Member
    GBAtemp Patron
    MichiS97 is a Patron of GBAtemp and is helping us stay independent!

    Our Patreon
    1,324
    744
    Jun 14, 2011
    Gambia, The
    Bavaria
    return (*(vu8*)(0x00776312));

    I'm using this to read a single byte, change vu8 to vu16 to read two bytes :)
    How exactly can you convert Gateway codes to NTR though?
     
    omegapirate likes this.
  10. ShiroKyouma

    ShiroKyouma Advanced Member

    Newcomer
    86
    17
    Dec 29, 2015
    Waiting for the tutorial. :D
     
  11. Tomato Hentai

    Tomato Hentai baja boner blast

    Member
    3,751
    6,113
    Oct 30, 2014
    Canada
    actually north korea. please send help
    I know this sounds strange, but I wonder if it'd be possible to solder wires to the board in a way that would let people dump the RAM like that.
    That's very likely a 'no' but, eh. Never hurts to ask.
     
  12. Nanquitas

    Nanquitas GBAtemp Addict

    Member
    2,081
    1,710
    Sep 29, 2015
    France
    South of France :)
    Hello !

    Your code should work but replace int with unsigned int. ;)
    Code:
    unsigned int pointer = READU32(0x145EAEB0);
    WRITEU16(pointer, 0xFFFF);
     
    Tomato Hentai likes this.
  13. DesuIsSparta

    DesuIsSparta GBAtemp Advanced Fan

    Member
    542
    174
    Oct 13, 2015
    United States
    Weaboo land
    Well of course you can create your own hardware to dump the system's RAM but then you're still stuck with the same problem NTR offers you: How do you interact with said RAM?

    It's absolutely 100% possible to write Gateway's method of memory hacking without a Gateway. Unfortunately, I don't have the programming knowledge nor enough information on firmwares to create my own CFW designed to do so. If I were able to, I'd write NTR a different way. NTR isn't written poorly but the developer does not share the source code (i've already asked), nor are there many updates for it.. so it's lacking pretty hard in some places.

    For the time being, the best we have is Gateway and NTR. Perhaps I'll look into creating a CFW sometime in the future, but at the time I just can't do it..
     
    Tomato Hentai likes this.
  14. Nanquitas

    Nanquitas GBAtemp Addict

    Member
    2,081
    1,710
    Sep 29, 2015
    France
    South of France :)
    Why don't just make a plugin to read / write the memory ?
     
  15. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Absolutely wonderful people!

    I will test with the few codes people posted here and I will get back :)

    Hopefully I get back with good news! haha
     
  16. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    That's what I'm trying to do xD

    It seems I cant use READU32 as it's not defined. I tried to define it but there are always errors to compile :/

    So I've been playing with that line but I can't seems to make it work for some reason.

    I tried:

    Code:
    int valueG = *(vu32*)(0x145EAEB0);
    WRITEU16(valueG, 0x0000FFFF);
    
    Any help? xD
     
  17. Nanquitas

    Nanquitas GBAtemp Addict

    Member
    2,081
    1,710
    Sep 29, 2015
    France
    South of France :)
    Yeah, i meant in a more globally way, not a specific game's plugin. ;)

    Here's my macros definition:
    Code:
    #ifndef READU8
    #    define READU8(addr)             *(volatile unsigned char*)(addr)
    #endif
    #ifndef READU16
    #    define READU16(addr)             *(volatile unsigned short*)(addr)
    #endif
    #ifndef READU32
    #    define READU32(addr)             *(volatile unsigned int*)(addr)
    #endif
    Why do you think it's not working ? How do you use it ?
     
    omegapirate likes this.
  18. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Well I tried defining it that way and it could compile xD

    Problem still persists when trying to use it as:

    Code:
    unsigned int valueG = READU32(0x145EAEB0);
    WRITEU32(valueG, 0x0000FFFF);
    
    Even tried with writeu16 but it doesn't seem to work either.

    What I'm going to try is with the valueG variable as signed and without signed/unsigned.

    Also 2 things i believe are happening:

    1. the valueG is not represented as hex when trying to write the 0xFFFF so it could be a problem.
    2. the valueG is encoded in little/big endian and I need to translate it before using it on the writeu32 line
    3. i know i said 2 things, but still, it could be that valueG is not represented as hex when trying to write 0xFFFF and/or is also coded in little/big endian.

    Can anyone confirm whether or not that should work? xD

    Im a coder but C in general i dont remember a thing!
     
  19. Nanquitas

    Nanquitas GBAtemp Addict

    Member
    2,081
    1,710
    Sep 29, 2015
    France
    South of France :)
    1. Doesn't matter, the compiler doesn't make difference between 0x1 or 1, it's just more convenient for you to write a big number.
    2. Nope, i use this way in my FF plugin to read dynamic address.
    3. CF 1.

    Now:
    - If you try to freeze the value you have to loop it, especially if the game rewrite the real number right after the modification;
    - Are you sure you triggering the code ?
    - Maybe the address is not the good one ? :/

    If you link the code i can try to help, but the code you wrote ahead is working. ;)
     
    omegapirate likes this.
  20. omegapirate
    OP

    omegapirate Member

    Newcomer
    42
    2
    May 25, 2012
    Mexico
    Ok so unfortunately I can't link to the code as it's one I created from dumping ram with gateway xD

    But here's the code:

    ::Generated Code(Goomba atk)
    6145EAEB0 00000000
    B145EAEB0 00000000
    00000000 00000000
    D2000000 00000000

    So basically the thing is that pointer 0x145EAEB0 (a static pointer) contains the address of DMA where the atk of the goomba is.

    How can I know this code should work?

    Well, using the 2 dumped rams with gateway, I both went to the static pointer 0x145EAEB0 and both had a dynamic address. Then I went to those dynamic addresses and I could find the attack of the goomba.

    I firstly used gateway cheat finder to get the attack of the goomba and then I changed it to 0xFFFF and the attack obviously increased. Obviously as it's dynamic, after the fight, the address was different but the pointer (0x145EAEB0) is static and that's what I need for me to find and change the dynamic address.

    The code above of 4 lines basically locates the static pointer, gets the value of the static pointer which is the dynamic address and then we can write on the dynamic address.

    I'm trying to do the same process but with NTR so that's why converting codes from gateway to NTR is quite a job sometimes xD