Avoiding memory addresses shifts

Discussion in 'Wii U - Homebrew' started by BullyWiiPlaza, Dec 25, 2016.

  1. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    I've been working on the TCP Gecko Installer and noticed that declaring global variables shifts everything downwards so all cheat codes will break. How can this be prevented? It's really important otherwise everything was pretty much :nayps3:

    Code:
    #include <string.h>
    #include <stdio.h>
    #include <malloc.h>
    #include "common/common.h"
    #include "main.h"
    #include "dynamic_libs/socket_functions.h"
    #include "dynamic_libs/gx2_functions.h"
    #include "kernel/syscalls.h"
    #include "dynamic_libs/fs_functions.h"
    #include "common/fs_defs.h"
    
    // ###### CULPRITS (but I need them to be allocated by default to cut down on boilerplate code) #######
    void *client;
    void *commandBlock;
    
    struct pygecko_bss_t {
        int error, line;
        void *thread;
        unsigned char stack[0x6F00];
    };
    
    #define CHECK_ERROR(cond) if (cond) { bss->line = __LINE__; goto error; }
    #define errno (*__gh_errno_ptr())
    #define MSG_DONTWAIT 32
    #define EWOULDBLOCK 6
    #define FS_BUFFER_SIZE 0x1000
    #define DATA_BUFFER_SIZE 0x5000
    
    [...]
    Any trick I could use? Apparently, global variables are allocated on the heap but the heap is in the 4XXXXXXX Wii U memory area. Yet the 1XXXXXXX area is shifted :mellow:

    @Maschell
    @gudenaurock
    @QuarkTheAwesome
    @dimok
    @wj44
     
    Last edited by BullyWiiPlaza, Dec 26, 2016
    CosmoCortney likes this.


  2. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    761
    1,849
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    That's a weird one. What do you get out of &client? I'm assuming this is a HBL ELF; so it really shouldn't affect anything outside the 0x00800000 range.
    Have you tried setting the variables to be in .data?
     
  3. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    Yes, it's a homebrew launcher ELF. The client is for the file system. How would you set the variables in the .data section like you proposed? The memory shift is 0x2200 but client and commandBlock only take up 0x1700 + 0xA80 = 0x2180 space (once allocated) so it kinda matches up.
     
    Last edited by BullyWiiPlaza, Dec 26, 2016
  4. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    761
    1,849
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    Oh, do you malloc() them? That's probably not the best idea. libdimok's (that's what I'm calling it now) malloc falls through to MEMAllocFromDefaultHeapEx, which does exactly what it says on the tin. You're allocating space from the console's main heap which it uses for everything, including games.
    The Wii U's allocation functions also take an alignment variable (so you can say "give me an address that ends in 00 (nearest 0x100 bytes)" or whatever) which explains the small size discrepancy you've noticed.

    I'd solve this either by allocating from somewhere else (annoying and could break other stuff) or putting what you need in the .data section, effectively moving it to 0x00800000 (has a size limitation).

    Here's how you'd put the above in .data:
    Code:
    char client[FS_BUFFER_SIZE /*or whatever*/] __attribute__ ((section (".data")));
    
    You could then use it like so:
    Code:
    FunctionThatTakesClientAsVoidPointer((void*)client);
    
    Alternatively, this would keep client as a void*:
    Code:
    char client_r[FS_BUFFER_SIZE /*or whatever*/] __attribute__ ((section (".data")));
    void* client = (void*)client_r;
    
    The big difference is that your code above declares a void pointer (a memory address) that you later fill in with malloc(). Here, however, we set up a char array (char allows us to give a size in bytes) that's in the actual ELF. client (or client_r) is now a pointer to that array, so we can cast it as we like and off we go!

    I will note that in this case buffer overflows will be far more devastating than normal. Be careful with your sizing.
     
    CosmoCortney and BullyWiiPlaza like this.
  5. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    Yep, that works. The memory is no longer shifted. :D
    But calling a file system function (like read directory) crashes the console now. It basically gets stuck. Not sure why :/
    Code:
    char client[FS_CLIENT_SIZE] __attribute__ ((section (".data")));
    char commandBlock[FS_CMD_BLOCK_SIZE] __attribute__ ((section (".data")));
    Code:
    void initializeFileSystem()
    {
        // Initialize the file system
        int status = FSInit();
        CHECK_FUNCTION_FAILED(status, "FSInit")
    
        // Allocate the client
        // client = malloc(FS_CLIENT_SIZE);
        CHECK_ALLOCATED(client, "Client")
    
        // Register the client
        status = FSAddClientEx(client, 0, -1);
        CHECK_FUNCTION_FAILED(status, "FSAddClientEx")
    
        // Allocate the command block
        // commandBlock = malloc(FS_CMD_BLOCK_SIZE);
        CHECK_ALLOCATED(commandBlock, "Command block")
    
        FSInitCmdBlock(commandBlock);
    }
     
    Last edited by BullyWiiPlaza, Dec 27, 2016
  6. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    761
    1,849
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    Hm, not sure. I'd try an exception handler and asking someone who knows more about the FS functions.
     
  7. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    Uh, this is kinda annoying. If I do the following:
    Code:
    void* client __attribute__ ((section (".data")));
    void* commandBlock __attribute__ ((section (".data")));
    client = malloc(FS_CLIENT_SIZE);
    commandBlock = malloc(FS_CMD_BLOCK_SIZE);
    It is basically the same as the "original" declarations (FS functions work but the memory is shifted):
    Code:
    void* client;
    void* commandBlock;
    Allocating it via
    Code:
    void* client[FS_CLIENT_SIZE] __attribute__ ((section (".data")));
    void* commandBlock [FS_CMD_BLOCK_SIZE] __attribute__ ((section (".data")));
    and not using malloc() does not shift but crashes when an FS function is called.

    Code:
    void* client __attribute__ ((section (".data")));
    void* commandBlock __attribute__ ((section (".data")));
    client = (void *) OSAllocFromSystem(FS_CLIENT_SIZE, 4);
    commandBlock = (void *) OSAllocFromSystem(FS_CMD_BLOCK_SIZE, 4);
    FS functions work but shifts the memory.

    Using
    Code:
    static
    also changes nothing.

    Any other suggestions?
    I need both to work out at once :(
     
    Last edited by BullyWiiPlaza, Dec 26, 2016
  8. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    761
    1,849
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    I really do have no idea. I will note that using "void* x[num]" like above will give an array of void*s, each 4 bytes big (x becomes a pointer to the first one; a void**!). However; that shouldn't affect much around functionality.
    At this point all I can recommend is an exception handler. My favorite is obviously my one but you could get away with Dimok's too. It should really zero in on the exact problem and you can work backwards pretty easily from there.
     
    BullyWiiPlaza likes this.
  9. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    But how does it help? I don't think it will do anything useful if it dumps registers and such. I have to find a solution to this problem anyway but I'm running out of ideas D:
     
    Last edited by BullyWiiPlaza, Dec 27, 2016
  10. CosmoCortney

    CosmoCortney The Hacker Furry

    Member
    1,538
    1,462
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    I hope this can be solved. it's annoying making all cheats above 0x11000000 being pointer codes due to this issue
     
    BullyWiiPlaza and CuriousTommy like this.
  11. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    761
    1,849
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    If you can get an exception log; we can figure out why the FS functions don't like having stuff in .data.
     
    CosmoCortney likes this.
  12. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    So I would just do
    Code:
    installExceptionHandler()
    with your code from here and exceptions will be caught?

    Or this by dimok :D

    I'll go with dimok's since the code is already in the project but unused.

    ---

    Well, the game is put in a semi-frozen state (the music keeps repeating but the game still runs). Pressing home freezes it completely. Nothing is printed on-screen as exception. Also, JGecko U freezes and the server is stuck. Re-connecting is impossible obviously.

    Code:
    char client_r[FS_CLIENT_SIZE] __attribute__ ((section (".data")));
    void *client = (void *) client_r;
    
    char commandBlock_r[FS_CMD_BLOCK_SIZE] __attribute__ ((section (".data")));
    void *commandBlock = (void *) commandBlock_r;
    The memory is not shifted though but the FS functions are not functioning. Maybe you can take a look at the C code? Maybe there is something wrong with it though but it works fine when the global variables are allocated "normally" on the heap. How strange. We need some other genius to help out :nayps3:
     
    Last edited by BullyWiiPlaza, Dec 27, 2016
    CosmoCortney likes this.
  13. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    I fixed it now. It was easier than expected xD

    All I had to do was delay the allocation till the file system is actually needed and allocate just once. Basically like this:
    Code:
    // Still global variables
    void *client;
    void *commandBlock;
    Code:
    void considerInitializingFileSystem() {
        if (!client) {
            // Allocate everything and set up the memory...
        }
    }
    Code:
    case 0x52: { /* cmd_read_file */
        char file_path[FS_MAX_FULLPATH_SIZE] = {0};
        receiveString(bss, clientfd, file_path, FS_MAX_FULLPATH_SIZE);
    
        considerInitializingFileSystem(); // The trick to avoid the shift
    
        int handle;
        int status = FSOpenFile(client, commandBlock, file_path, "r", &handle, -1);
        // A lot more code...
    Done. Not shifted, good code style and file system functions working. This is a base to work with for further features :D :D :D
     
    Last edited by BullyWiiPlaza, Dec 29, 2016
  14. CosmoCortney

    CosmoCortney The Hacker Furry

    Member
    1,538
    1,462
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    you're my hero :D
     
    BullyWiiPlaza likes this.
  15. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    422
    71
    Dec 29, 2016
    Uncached MEM2 of the Wii :-)
    soooo... is this code gonna be used to update the codehandler or something? Will I have to download a new version of tcpgecko installer or jgecko u or something else to use codes without memory shifting and all that stuff?
    Anyway, awesome work Bully!
     
    Last edited by HackingNewbie, Dec 29, 2016
  16. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    Yes, to add file system support. It's already there in JGecko U. There might be more if I have good ideas and get it working since barely anyone else helps implementing something :P
     
  17. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    422
    71
    Dec 29, 2016
    Uncached MEM2 of the Wii :-)
    So I just have to download a new version of the codehandler (when it's made) and nothing else?
     
    Last edited by HackingNewbie, Dec 29, 2016
  18. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,663
    1,364
    Aug 2, 2014
    Germany
    No. TCP Gecko Installer but it's already made.
     
  19. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    422
    71
    Dec 29, 2016
    Uncached MEM2 of the Wii :-)
    K, so I'll download it from CosmoCourtney's wii u code thread and boom, no memory shifting?
     
  20. CosmoCortney

    CosmoCortney The Hacker Furry

    Member
    1,538
    1,462
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    The codehandler has no affect on memory shifting. The shifting is caused by TCPGecko.elf especially when it declares variables. Bully's TCPGecko improvement now fixes the memory shifting.
    So no need to re-download the codehandler unless it experiences a new update