TCP Gecko Server Feature Requests

Discussion in 'Wii U - Hacking & Backup Loaders' started by BullyWiiPlaza, May 25, 2016.

  1. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    In this topic I want to collect features that would be great to have in the TCP Gecko server code.
    • Support compressed sending/receiving of bytes to save network transmission time using an open-source compression library like zlib or even lzma. Unfortunately, I'm getting Z_MEM_ERROR when calling deflateInit(). Alternatively, there is lzma:
    Code:
    LzmaCompress(unsigned char *dest, size_t *destLen,
                   const unsigned char *src, size_t srcLen,
                   unsigned char *outProps,
                   size_t *outPropsSize, /* *outPropsSize must be = 5 */
                   int level,            /* 0 <= level <= 9, default = 5 */
                   unsigned dictSize,    /* default = (1 << 24) */
                   int lc,               /* 0 <= lc <= 8, default = 3  */
                   int lp,               /* 0 <= lp <= 4, default = 0  */
                   int pb,               /* 0 <= pb <= 4, default = 2  */
                   int fb,               /* 5 <= fb <= 273, default = 32 */
                   int numThreads        /* 1 or 2, default = 2 */
                  );
    • Support dumping memory to the SD Card for performance reasons explained here
    • Support multiple clients to be connected to the server at once to avoid having to disconnect when switching clients
    • Support setting breakpoints to find out what reads from or writes to an address. Also execute breakpoints for assembly (Everything like on Wii). I heard that Chadderz got it to work so I'm positive this can be done already without an IOSU exploit release. Also Kinnay made breakpoint execute for Diibugger so it could be integrated into the TCP Gecko Installer
    • Support pausing and resuming the game to allow more fine-grained memory searches. Some cheat codes can hardly be made without
    • Merge kernel exploit and TCP Gecko installer
    • Implement a search function for known values that returns all addresses matching the condition (==, !=, >, <, >=, <=) similar to the search function already implemented:
      Code:
      case COMMAND_MEMORY_SEARCH: {
          // Receive the initial data
          ret = recvwait(bss, clientfd, buffer, 4 * 5);
          ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (memory search information)")
          int startingAddress = ((int *) buffer)[0];
          int length = ((int *) buffer)[1];
          int resultsLimit = ((int *) buffer)[2];
          int aligned = ((int *) buffer)[3];
          int searchBytesCount = ((int *) buffer)[4];
      
          // Receive the search bytes
          char searchBytes[searchBytesCount];
          ret = recvwait(bss, clientfd, searchBytes, searchBytesCount);
          ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (memory search bytes)")
      
          int iterationIncrement = aligned ? searchBytesCount : 1;
          int searchBytesOccurrences = 0;
      
          // Perform the bytes search and collect the results
          for (int currentAddress = startingAddress;
               currentAddress < startingAddress + length;
               currentAddress += iterationIncrement) {
              if (memcmp((void *) currentAddress, searchBytes, searchBytesCount) == 0) {
                  // Search bytes have been found
                  ((int *) buffer)[1 + searchBytesOccurrences] = currentAddress;
                  searchBytesOccurrences++;
      
                  if ((resultsLimit == searchBytesOccurrences)
                      || (searchBytesOccurrences == ((DATA_BUFFER_SIZE / 4) - 1))) {
                      // We bail out
                      break;
                  }
              }
          }
      
          ((int *) buffer)[0] = searchBytesOccurrences * 4;
          ret = sendwait(bss, clientfd, buffer, 4 + (searchBytesOccurrences * 4));
          ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (Sending search bytes occurrences)")
      
          break;
      }
    This will allow the initial searching time for known value searches to be optimized.
    • Support multi-threaded memory dumping (once again for performance reasons)
    • Add screenshot support
    • Allow replacing files on the file system
      Code:
      case COMMAND_REPLACE_FILE: {
          // TODO Write file
      
          // Receive the file path
          char file_path[FS_MAX_FULLPATH_SIZE] = {0};
          receiveString(bss, clientfd, file_path, FS_MAX_FULLPATH_SIZE);
      
          considerInitializingFileSystem();
      
          // Create an empty file for writing. Its contents will be erased
          int handle;
          int status = FSOpenFile(client, commandBlock, file_path, "w", &handle, FS_RET_ALL_ERROR);
      
          if (status == FS_STATUS_OK) {
              // Send the OK status
              ((int *) buffer)[0] = status;
              ret = sendwait(bss, clientfd, buffer, 4);
              ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (OK status)")
      
              // Set the file handle position to the beginning
              ret = FSSetPosFile(client, commandBlock, handle, 0, FS_RET_ALL_ERROR);
              ASSERT_FUNCTION_SUCCEEDED(ret, "FSSetPosFile")
      
              // Allocate the file bytes buffer
              unsigned int file_buffer_size = 0x2000;
              char *fileBuffer = (char *) OSAllocFromSystem(file_buffer_size, FS_IO_BUFFER_ALIGN);
              ASSERT_ALLOCATED(fileBuffer, "File buffer")
      
              // Send the maximum file buffer size
              ret = sendwait(bss, clientfd, &file_buffer_size, 4);
              ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (maximum file buffer size)")
      
              while (true) {
                  // Receive the data bytes length
                  unsigned int dataLength;
                  ret = recvwait(bss, clientfd, &dataLength, 4);
                  ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (File bytes length)")
                  ASSERT_MAXIMUM_HOLDS(file_buffer_size, dataLength, "File buffer overrun attempted")
      
                  if (dataLength > 0) {
                      // Receive the data
                      ret = recvwait(bss, clientfd, fileBuffer, dataLength);
                      ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (File buffer)")
      
                      // Write the data and advance file handle position
                      ret = FSWriteFile(client, commandBlock, fileBuffer, 1,
                                        dataLength, handle, 0, FS_RET_ALL_ERROR);
                      ASSERT_FUNCTION_SUCCEEDED(ret, "FSWriteFile")
                  } else {
                      // Done
                      break;
                  }
              }
      
              /*// Flush the file back
              ret = FSFlushFile(client, commandBlock, handle, FS_RET_ALL_ERROR);
              CHECK_FUNCTION_FAILED(ret, "FSFlushFile")*/
      
              // Close the file
              ret = FSCloseFile(client, commandBlock, handle, FS_RET_ALL_ERROR);
              ASSERT_FUNCTION_SUCCEEDED(ret, "FSCloseFile")
      
              // Free the file buffer
              OSFreeToSystem(fileBuffer);
          } else {
              // Send the status
              ((int *) buffer)[0] = status;
              ret = sendwait(bss, clientfd, buffer, 4);
              ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (status)")
          }
      
          break;
      }
    • Allow adding files to the file system
      Cafiine source.
    The TCP Gecko Installer source code is here.

    Please post your suggestions below if you have any that haven't been mentioned yet. :)

    @Maschell
    @gudenaurock
    @NWPlayer123
    @Marionumber1
    @Onion_Knight
    @wj44
    @shinyquagsire23
    @Hykem
    @MrRean
     
    Last edited by BullyWiiPlaza, Feb 11, 2017
  2. gudenau

    gudenau Never a unique idea

    Member
    3,257
    1,225
    Jul 7, 2010
    United States
    /dev/random
    A dedicated hardware device for conecting a PC directly, would not impact the network and could have less overhead if done well, more throughput.
     
    BullyWiiPlaza likes this.
  3. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    We don't really need a USB Gecko'ish device since it will cost extra money for everyone. Performance will be good enough when optimized software-wise I believe. Also the Wii USB Gecko was still slow. Yes, the GameCube memory card slots weren't fast to begin with but still, which slot would you propose to provide more throughput? Most likely not possible or not worth it.
     
    Last edited by BullyWiiPlaza, May 25, 2016
  4. gudenau

    gudenau Never a unique idea

    Member
    3,257
    1,225
    Jul 7, 2010
    United States
    /dev/random
    Yeah, but for the few that would use it (like me) it could be useful. The fastest you can get with the networking goes though a few layers in software. USB, IP, TCP, Handler. A USB device could just be USB,Handler.

    Even optimizing the search tools to not transfer much data would not eleviate the utility of memory dumps.

    Probably a good idea to make two builds, one with tcp and the other with USB.
     
    BullyWiiPlaza likes this.
  5. Duckling

    Duckling Sorry for being dumb ;(

    Member
    470
    97
    Mar 17, 2016
    Laos
    A java tcpgecko so that it could run on both mac and windows
     
  6. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    I'm making that already with JGecko U (if anyone would help it might go much faster). Since this is not part of the server it's off-topic.
     
    Last edited by BullyWiiPlaza, May 25, 2016
    Duckling likes this.
  7. George35000vr

    George35000vr TROLLIE

    Member
    227
    22
    Jun 22, 2013
    Greece
    Crete
    Android app :P
     
  8. rbsk

    rbsk Advanced Member

    Newcomer
    61
    11
    May 10, 2016
    United States
    @BullyWiiPlaza Is it at all possible to get a feature for finding what 'write/reads to/from this address'?
    Like, a watch on a single address for either what is writing to this address or reading from this address or both as you go about and change things.
    That is my favorite thing about BitSlicer (OSXs equivalent to cheat engine). Or would this fall solely under the client piece and not the server?
     
    Last edited by rbsk, May 25, 2016
    BullyWiiPlaza likes this.
  9. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    Yeah, it's for the server. This is indeed something I forgot. It's called setting breakpoints.
     
    rbsk likes this.
  10. rbsk

    rbsk Advanced Member

    Newcomer
    61
    11
    May 10, 2016
    United States
    Oh, wow- that's what it is. Thank you.
    So, with that would you be able to do all the "step in/out/over" stuff?
     
  11. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    Yeah, exactly
     
    Phantom90 and rbsk like this.
  12. gudenau

    gudenau Never a unique idea

    Member
    3,257
    1,225
    Jul 7, 2010
    United States
    /dev/random
    I'll look into breakpoints, it'll be fun to do that I suppose.
     
    rbsk, BullyWiiPlaza and Thomas83Lin like this.
  13. gudenau

    gudenau Never a unique idea

    Member
    3,257
    1,225
    Jul 7, 2010
    United States
    /dev/random
    One idea is some sort of UDP broadcast based discovery system.
     
  14. RandomUser

    RandomUser What has gotten into you Rosie?

    Member
    582
    202
    May 9, 2010
    United States
    I don't know if it would be possible, perhaps a way to load cheats from SD card, like GeckoOS, also if possible being able to select which cheats you want enabled from said SD card. Actually may want to scratch that, to many potential for online abuse, as currently too much codes sent through the Network interface will interfere with online communication, thus making it a little less convenience to cheat online.
     
  15. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    The suggestions are for the codehandler server which has nothing to do with the SD Card. About your concern: It doesn't really matter. The network for sending codes or whatever doesn't get "less stable" during online play.
     
  16. RandomUser

    RandomUser What has gotten into you Rosie?

    Member
    582
    202
    May 9, 2010
    United States
    Oops, my brain is off today. I was and still am not thinking correctly. Sorry about that:wacko:.
     
  17. BullyWiiPlaza
    OP

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,727
    1,409
    Aug 2, 2014
    Germany
    So I was trying to implement a bytes search but it's not working right...
    Code:
    int compareMemory(unsigned char *buffer, void* address, int size) {
        void* current_address = address;
    
        int buffer_index = 0;
        for (; current_address < address + size; current_address++) {
            char memory_value = *(char *) current_address;
            char buffer_value = buffer[buffer_index];
    
            if (memory_value != buffer_value) {
                return false;
            }
    
            buffer_index++;
        }
    
        return true;
    }
    Code:
    case 0x73: { /* cmd_search_bytes */
                    data_size = 0x400;
                    ret = recvwait(bss, clientfd, buffer, data_size);
                    CHECK_ERROR(ret < 0);
    
                    int starting_address = ((int *) buffer)[0];
                    int end_address = ((int *) buffer)[1];
                    int value_bytes_length = ((int *) buffer)[2];
                    unsigned char* value_bytes = &buffer[3];
    
                    int found_address = 0;
                    for (int current_address = starting_address;
                         current_address < end_address;
                         current_address++) {
                        if (compareMemory(value_bytes, (void *) current_address, value_bytes_length)) {
                            found_address = current_address;
                            break;
                        }
                    }
    
                    ((int *) buffer)[0] = found_address;
                    ret = sendwait(bss, clientfd, buffer, 4);
                    CHECK_ERROR(ret < 0);
                    break;
                }
    Can someone please take a look and maybe tell me what went possibly wrong? The idea is to receive the address to start search from, the end address of the search interval, the amount of bytes to compare against and finally the actual bytes.

    On Linux, the following example code worked:
    Code:
    #include <malloc.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    int compareMemory(unsigned char *buffer, void *address, int size) {
        void *current_address = address;
    
        int buffer_index = 0;
        for (; current_address < address + size; current_address++) {
            char memory_value = *(char *) current_address;
            char buffer_value = buffer[buffer_index];
    
            if (memory_value != buffer_value) {
                return false;
            }
    
            buffer_index++;
        }
    
        return true;
    }
    
    int main() {
        unsigned char buffer[7];
        buffer[0] = 0;
        buffer[1] = 0;
        buffer[2] = 0;
        buffer[3] = 1;
        buffer[4] = 2;
        buffer[5] = 3;
        buffer[6] = 4;
    
        size_t size = 4 * sizeof(char);
        char *allocated = (char *) malloc(size);
        allocated[0] = 1;
        allocated[1] = 2;
        allocated[2] = 3;
        allocated[3] = 4;
    
        printf("The same: %i", compareMemory(&buffer[3], allocated, 4));
    
        return EXIT_SUCCESS;
    }
    Thanks!
     
    Last edited by BullyWiiPlaza, Oct 28, 2016