Homebrew Avoiding memory addresses shifts

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
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,
  • Like
Reactions: CosmoCortney

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
Germany
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?
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,
Joined
Apr 19, 2015
Messages
1,023
Trophies
1
Location
Stuck in the PowerPC
Website
heyquark.com
XP
3,908
Country
Australia
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.
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.
 

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
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,

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
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,
Joined
Apr 19, 2015
Messages
1,023
Trophies
1
Location
Stuck in the PowerPC
Website
heyquark.com
XP
3,908
Country
Australia
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.
 
  • Like
Reactions: BullyWiiPlaza

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
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,
Joined
Apr 19, 2015
Messages
1,023
Trophies
1
Location
Stuck in the PowerPC
Website
heyquark.com
XP
3,908
Country
Australia
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:
If you can get an exception log; we can figure out why the FS functions don't like having stuff in .data.
 
  • Like
Reactions: CosmoCortney

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
Germany
If you can get an exception log; we can figure out why the FS functions don't like having stuff in .data.
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,
  • Like
Reactions: CosmoCortney

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,467
Country
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,

CosmoCortney

i snack raw pasta and chew lollipops
Member
Joined
Apr 18, 2013
Messages
1,768
Trophies
2
Location
on the cool side of the pillow
Website
follow-the-white-rabbit.wtf
XP
3,007
Country
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
you're my hero :D
 
  • Like
Reactions: BullyWiiPlaza

HackingNewbie

Well-Known Member
Member
Joined
Dec 29, 2016
Messages
536
Trophies
0
Location
Somewhere in 2008
XP
699
Country
United Kingdom
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,

CosmoCortney

i snack raw pasta and chew lollipops
Member
Joined
Apr 18, 2013
Messages
1,768
Trophies
2
Location
on the cool side of the pillow
Website
follow-the-white-rabbit.wtf
XP
3,007
Country
Germany
K, so I'll download it from CosmoCourtney's wii u code thread and boom, no memory shifting?
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
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    K3Nv2 @ K3Nv2: https://youtu.be/MddR6PTmGKg?si=mU2EO5hoE7XXSbSr