diff --git a/src/dynamic_libs/sys_functions.h b/src/dynamic_libs/sys_functions.h index 5bd2119..f687b55 100644 --- a/src/dynamic_libs/sys_functions.h +++ b/src/dynamic_libs/sys_functions.h @@ -30,14 +30,16 @@ extern "C" { void InitSysFunctionPointers(void); -extern void(*_SYSLaunchTitleByPathFromLauncher)(const char* path, int len, int zero); -extern int (* SYSRelaunchTitle)(int argc, char* argv); -extern int (* SYSLaunchMenu)(void); -extern int (* SYSCheckTitleExists)(u64 titleId); +extern void (*_SYSLaunchTitleByPathFromLauncher)(const char *path, int len, int zero); +extern int (*SYSRelaunchTitle)(int argc, char *argv); + +extern int (*SYSLaunchMenu)(void); + +extern int (*SYSCheckTitleExists)(u64 titleId); #ifdef __cplusplus } #endif -#endif // __SYS_FUNCTIONS_H_ +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b6c541a..03ad761 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,11 +20,9 @@ #include "patcher/function_patcher_gx2.h" #include "patcher/function_patcher_coreinit.h" #include "utils/sd_ip_reader.hpp" -#include "fs/sd_fat_devoptab.h" -bool isCodeHandlerInstalled; - -#define PRINT_TEXT2(x, y, ...) { snprintf(messageBuffer, 80, __VA_ARGS__); OSScreenPutFontEx(0, x, y, messageBuffer); OSScreenPutFontEx(1, x, y, messageBuffer); } +bool isCodeHandlerInstalled = false; +bool areSDCheatsEnabled = false; typedef enum { EXIT, @@ -36,16 +34,38 @@ void applyFunctionPatches() { patchIndividualMethodHooks(method_hooks_coreinit, method_hooks_size_coreinit, method_calls_coreinit); } -bool isSDAccessEnabled() { - int result = mount_sd_fat("sd"); +void installCodeHandler() { + unsigned int physicalCodeHandlerAddress = (unsigned int) OSEffectiveToPhysical( + (void *) CODE_HANDLER_INSTALL_ADDRESS); + SC0x25_KernelCopyData((u32) physicalCodeHandlerAddress, (unsigned int) codeHandler, codeHandlerLength); + DCFlushRange((const void *) CODE_HANDLER_INSTALL_ADDRESS, (u32) codeHandlerLength); + isCodeHandlerInstalled = true; +} - if (result < 0) { - return false; - } +unsigned char *screenBuffer; - unmount_sd_fat("sd"); +#define PRINT_TEXT(x, y, ...) { snprintf(messageBuffer, 80, __VA_ARGS__); OSScreenPutFontEx(0, x, y, messageBuffer); OSScreenPutFontEx(1, x, y, messageBuffer); } - return true; +void initializeScreen() { + // Init screen and screen buffers + OSScreenInit(); + unsigned int screenBuffer0Size = OSScreenGetBufferSizeEx(0); + unsigned int screenBuffer1Size = OSScreenGetBufferSizeEx(1); + + screenBuffer = (unsigned char *) MEM1_alloc(screenBuffer0Size + screenBuffer1Size, 0x40); + + OSScreenSetBufferEx(0, screenBuffer); + OSScreenSetBufferEx(1, (screenBuffer + screenBuffer0Size)); + + OSScreenEnableEx(0, 1); + OSScreenEnableEx(1, 1); +} + +void install() { + installCodeHandler(); + initializeUDPLog(); + log_print("Patching functions\n"); + applyFunctionPatches(); } /* Entry point */ @@ -99,49 +119,38 @@ int Menu_Main(void) { // PatchMethodHooks(); memoryInitialize(); - VPADInit(); - - // Init screen and screen buffers - OSScreenInit(); - int screenBuffer0Size = OSScreenGetBufferSizeEx(0); - int screenBuffer1Size = OSScreenGetBufferSizeEx(1); - - unsigned char *screenBuffer = (unsigned char *) MEM1_alloc(screenBuffer0Size + screenBuffer1Size, 0x40); - - OSScreenSetBufferEx(0, screenBuffer); - OSScreenSetBufferEx(1, (screenBuffer + screenBuffer0Size)); - - OSScreenEnableEx(0, 1); - OSScreenEnableEx(1, 1); + initializeScreen(); char messageBuffer[80]; int launchMethod; - int update_screen = 1; + int shouldUpdateScreen = 1; s32 vpadError = -1; VPADData vpad_data; while (true) { VPADRead(0, &vpad_data, 1, &vpadError); - if (update_screen) { + if (shouldUpdateScreen) { OSScreenClearBufferEx(0, 0); OSScreenClearBufferEx(1, 0); + InitSocketFunctionPointers(); + // Build the IP address message char ipAddressMessageBuffer[64]; - InitSocketFunctionPointers(); __os_snprintf(ipAddressMessageBuffer, 64, "Your Wii U's IP address: %i.%i.%i.%i", (hostIpAddress >> 24) & 0xFF, (hostIpAddress >> 16) & 0xFF, (hostIpAddress >> 8) & 0xFF, hostIpAddress & 0xFF); - PRINT_TEXT2(14, 1, "-- TCP Gecko Installer --") - PRINT_TEXT2(7, 2, ipAddressMessageBuffer) - PRINT_TEXT2(0, 5, "Press A to install TCP Gecko (with built-in code handler)...") + PRINT_TEXT(14, 1, "-- TCP Gecko Installer --") + PRINT_TEXT(7, 2, ipAddressMessageBuffer) + PRINT_TEXT(0, 5, "Press A to install TCP Gecko (with built-in code handler)...") + PRINT_TEXT(0, 6, "Press X to install TCP Gecko (with code handler and SD cheats)...") - PRINT_TEXT2(0, 8, "Note:") - PRINT_TEXT2(0, 9, "* You can enable loading SD cheats with Mocha SD access") - PRINT_TEXT2(0, 10, "* Generate and store GCTUs to your SD card with JGecko U") + PRINT_TEXT(0, 8, "Note:") + PRINT_TEXT(0, 9, "* You can enable loading SD cheats with Mocha SD access") + PRINT_TEXT(0, 10, "* Generate and store GCTUs to your SD card with JGecko U") // testMount(); /*if (isSDAccessEnabled()) { @@ -150,7 +159,7 @@ int Menu_Main(void) { PRINT_TEXT2(0, 8, "No SD card access: Please run Mocha SD Access by maschell for SD cheat support...") }*/ - PRINT_TEXT2(0, 17, "Press Home to exit...") + PRINT_TEXT(0, 17, "Press Home to exit...") OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(1); @@ -163,27 +172,22 @@ int Menu_Main(void) { launchMethod = EXIT; break; - } - - // A Button pressed - if (pressedButtons & VPAD_BUTTON_A) { - unsigned int physicalCodeHandlerAddress = (unsigned int) OSEffectiveToPhysical( - (void *) CODE_HANDLER_INSTALL_ADDRESS); - SC0x25_KernelCopyData((u32) physicalCodeHandlerAddress, (unsigned int) codeHandler, codeHandlerLength); - DCFlushRange((const void *) CODE_HANDLER_INSTALL_ADDRESS, (u32) codeHandlerLength); - - isCodeHandlerInstalled = true; + } else if (pressedButtons & VPAD_BUTTON_A) { + install(); launchMethod = TCP_GECKO; - initializeUDPLog(); - log_print("Patching functions\n"); - applyFunctionPatches(); + + break; + } else if (pressedButtons & VPAD_BUTTON_X) { + install(); + launchMethod = TCP_GECKO; + areSDCheatsEnabled = true; break; } - // Button pressed ? - update_screen = (pressedButtons & (VPAD_BUTTON_LEFT | VPAD_BUTTON_RIGHT | VPAD_BUTTON_UP | VPAD_BUTTON_DOWN)) - ? 1 : 0; + // Button pressed? + shouldUpdateScreen = (pressedButtons & + (VPAD_BUTTON_LEFT | VPAD_BUTTON_RIGHT | VPAD_BUTTON_UP | VPAD_BUTTON_DOWN)) ? 1 : 0; usleep(20 * 1000); } @@ -191,16 +195,17 @@ int Menu_Main(void) { asm volatile ("mr 2, %0" : : "r" (old_sdata2_start)); MEM1_free(screenBuffer); - screenBuffer = NULL; memoryRelease(); if (launchMethod == EXIT) { - // RestoreInstructions(); + // Exit the installer return EXIT_SUCCESS; } else { + // Launch system menu SYSLaunchMenu(); } + // For each title load, relaunch the TCP Gecko return EXIT_RELAUNCH_ON_LOAD; -} +} \ No newline at end of file diff --git a/src/main.h b/src/main.h index cc72010..ae91dd4 100644 --- a/src/main.h +++ b/src/main.h @@ -13,6 +13,7 @@ extern "C" { int Menu_Main(void); extern bool isCodeHandlerInstalled; +extern bool areSDCheatsEnabled; #ifdef __cplusplus } diff --git a/src/system/address.cpp b/src/system/address.cpp index 5955973..d562fbd 100644 --- a/src/system/address.cpp +++ b/src/system/address.cpp @@ -5,11 +5,11 @@ int validateAddressRange(int starting_address, int ending_address) { return __OSValidateAddressSpaceRange(1, (void *) starting_address, ending_address - starting_address + 1); } -bool isValidDataAddress(int address) { +/*bool isValidDataAddress(int address) { return OSIsAddressValid((const void *) address) && address >= 0x10000000 && address < 0x50000000; -} +}*/ int roundUpToAligned(int number) { return (number + 3) & ~0x03; diff --git a/src/system/memory.h b/src/system/memory.h index 59764d0..732292d 100644 --- a/src/system/memory.h +++ b/src/system/memory.h @@ -39,4 +39,4 @@ void MEMBucket_free(void *ptr); } #endif -#endif // __MEMORY_H_ +#endif diff --git a/src/tcp_gecko.cpp b/src/tcp_gecko.cpp index 64a0778..42b2f82 100644 --- a/src/tcp_gecko.cpp +++ b/src/tcp_gecko.cpp @@ -1,5 +1,5 @@ #include "tcp_gecko.h" -#include +// #include #include #include #include @@ -91,7 +91,7 @@ struct pygecko_bss_t { #define VERSION_HASH 0x7FB223 -ZEXTERN int ZEXPORT +/*ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); ZEXTERN int ZEXPORT @@ -103,7 +103,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush -)); +));*/ // ########## Being socket_functions.h ############ @@ -547,45 +547,45 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } - case COMMAND_READ_MEMORY_COMPRESSED: { - // Receive the starting address and length - ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2); - CHECK_ERROR(ret < 0) - int startingAddress = ((int *) buffer)[0]; - unsigned int inputLength = ((unsigned int *) buffer)[1]; + /*case COMMAND_READ_MEMORY_COMPRESSED: { + // Receive the starting address and length + ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2); + CHECK_ERROR(ret < 0) + int startingAddress = ((int *) buffer)[0]; + unsigned int inputLength = ((unsigned int *) buffer)[1]; - z_stream stream; - memset(&stream, 0, sizeof(stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; + z_stream stream; + memset(&stream, 0, sizeof(stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; - // Initialize the stream struct - ret = deflateInit(&stream, Z_BEST_COMPRESSION); - ASSERT_INTEGER(ret, Z_OK, "deflateInit") + // Initialize the stream struct + ret = deflateInit(&stream, Z_BEST_COMPRESSION); + ASSERT_INTEGER(ret, Z_OK, "deflateInit") - // Supply the data - stream.avail_in = inputLength; - stream.next_in = (Bytef *) startingAddress; - stream.avail_out = DATA_BUFFER_SIZE; - void *outputBuffer = (void *) (&buffer + 4); - stream.next_out = (Bytef *) outputBuffer; + // Supply the data + stream.avail_in = inputLength; + stream.next_in = (Bytef *) startingAddress; + stream.avail_out = DATA_BUFFER_SIZE; + void *outputBuffer = (void *) (&buffer + 4); + stream.next_out = (Bytef *) outputBuffer; - // Deflate - ret = deflate(&stream, Z_FINISH); - ASSERT_INTEGER(ret, Z_OK, "deflate"); + // Deflate + ret = deflate(&stream, Z_FINISH); + ASSERT_INTEGER(ret, Z_OK, "deflate"); - // Finish - ret = deflateEnd(&stream); - ASSERT_INTEGER(ret, Z_OK, "deflateEnd"); + // Finish + ret = deflateEnd(&stream); + ASSERT_INTEGER(ret, Z_OK, "deflateEnd"); - // Send the compressed buffer size and content - int deflatedSize = stream.total_out; - ((int *) buffer)[0] = deflatedSize; - ret = sendwait(bss, clientfd, buffer, 4 + deflatedSize); - ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Compressed data)") + // Send the compressed buffer size and content + int deflatedSize = stream.total_out; + ((int *) buffer)[0] = deflatedSize; + ret = sendwait(bss, clientfd, buffer, 4 + deflatedSize); + ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Compressed data)") - break; + break;*/ // https://www.gamedev.net/resources/_/technical/game-programming/in-memory-data-compression-and-decompression-r2279 /* @@ -620,7 +620,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { OSFreeToSystem(compressedBuffer); break;*/ - } + // } case COMMAND_KERNEL_WRITE: { ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2); CHECK_ERROR(ret < 0) @@ -1098,21 +1098,29 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } int destinationAddress = baseAddress; - // Apply pointer offsets - for (offsetIndex = 0; offsetIndex < offsetsCount; offsetIndex++) { - int pointerValue = *(int *) destinationAddress; - int offset = offsets[offsetIndex]; - destinationAddress = pointerValue + offset; - // Validate the pointer address - bool isValidDestinationAddress = isValidDataAddress(destinationAddress); +#define INVALID_ADDRESS -1 - // Bail out if invalid - if (!isValidDestinationAddress) { - destinationAddress = -1; + if ((bool) OSIsAddressValid((const void *) destinationAddress)) { + // Apply pointer offsets + for (offsetIndex = 0; offsetIndex < offsetsCount; offsetIndex++) { + int pointerValue = *(int *) destinationAddress; + int offset = offsets[offsetIndex]; + destinationAddress = pointerValue + offset; - break; + // Validate the pointer address + bool isValidDestinationAddress = (bool) OSIsAddressValid((const void *) destinationAddress); + + // Bail out if invalid + if (!isValidDestinationAddress) { + destinationAddress = INVALID_ADDRESS; + + break; + } } + } else if (offsetsCount > 0) { + // Following pointers failed + destinationAddress = INVALID_ADDRESS; } // Return the destination address @@ -1128,14 +1136,14 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } case COMMAND_REMOTE_PROCEDURE_CALL: { - long long (*fun)(int, int, int, int, int, int, int, int); + long long (*function)(int, int, int, int, int, int, int, int); int r3, r4, r5, r6, r7, r8, r9, r10; long long result; ret = recvwait(bss, clientfd, buffer, 4 + 8 * 4); CHECK_ERROR(ret < 0); - fun = (long long int (*)(int, int, int, int, int, int, int, int)) ((void **) buffer)[0]; + function = (long long int (*)(int, int, int, int, int, int, int, int)) ((void **) buffer)[0]; r3 = ((int *) buffer)[1]; r4 = ((int *) buffer)[2]; r5 = ((int *) buffer)[3]; @@ -1145,7 +1153,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { r9 = ((int *) buffer)[7]; r10 = ((int *) buffer)[8]; - result = fun(r3, r4, r5, r6, r7, r8, r9, r10); + result = function(r3, r4, r5, r6, r7, r8, r9, r10); ((long long *) buffer)[0] = result; ret = sendwait(bss, clientfd, buffer, 8); @@ -1381,7 +1389,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } case COMMAND_GET_ENTRY_POINT_ADDRESS: { - u32 *entryPointAddress = (u32 *) *((u32 *) OS_SPECIFICS->addr_OSTitle_main_entry); + u32 *entryPointAddress = (u32 * ) * ((u32 * )OS_SPECIFICS->addr_OSTitle_main_entry); ((u32 *) buffer)[0] = (u32) entryPointAddress; ret = sendwait(bss, clientfd, buffer, sizeof(int)); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Entry point address)"); @@ -1487,7 +1495,7 @@ static s32 startTCPGeckoThread(s32 argc, void *argv) { bss = (struct pygecko_bss_t *) memalign(0x40, sizeof(struct pygecko_bss_t)); if (bss == 0) - return 0; + return (s32) 0; memset(bss, 0, sizeof(struct pygecko_bss_t)); if (OSCreateThread(&bss->thread, (s32 (*)(s32, void *)) runTCPGeckoServer, 1, bss, @@ -1518,13 +1526,15 @@ static s32 startTCPGeckoThread(s32 argc, void *argv) { executeAssembly(); } - considerApplyingSDCheats(); + if (areSDCheatsEnabled) { + considerApplyingSDCheats(); + } } } else { log_print("Code handler not installed...\n"); } - return 0; + return (s32) 0; } void startTCPGecko() { @@ -1540,9 +1550,10 @@ void startTCPGecko() { ASSERT_ALLOCATED(thread, "TCP Gecko thread") int status = OSCreateThread(thread, startTCPGeckoThread, (s32) 1, - NULL, (s32) (stack + sizeof(stack)), + NULL, (s32)(stack + sizeof(stack)), sizeof(stack), 0, - (OS_THREAD_ATTR_AFFINITY_CORE1 | OS_THREAD_ATTR_PINNED_AFFINITY | OS_THREAD_ATTR_DETACH)); + (OS_THREAD_ATTR_AFFINITY_CORE1 | OS_THREAD_ATTR_PINNED_AFFINITY | + OS_THREAD_ATTR_DETACH)); ASSERT_INTEGER(status, 1, "Creating TCP Gecko thread") // OSSetThreadName(thread, "TCP Gecko"); OSResumeThread(thread); diff --git a/src/title.c b/src/title.c index f833de0..9800cbe 100644 --- a/src/title.c +++ b/src/title.c @@ -2,7 +2,7 @@ #include "title.h" bool isRunningTitleID(unsigned long long int japaneseTitleID) { - unsigned long long int currentTitleID = (unsigned long long int) OSGetTitleID(); + u64 currentTitleID = OSGetTitleID(); return currentTitleID == japaneseTitleID // JAP || currentTitleID == japaneseTitleID + 0x100 // USA || currentTitleID == japaneseTitleID + 0x200; // EUR @@ -12,6 +12,6 @@ bool isRunningAllowedTitleID() { return OSGetTitleID != 0 && !isRunningTitleID(TITLE_ID_MII_VERSE) && !isRunningTitleID(TITLE_ID_MII_MAKER) - && !isRunningTitleID(TITLE_ID_BAYONETTA_2) + // && !isRunningTitleID(TITLE_ID_BAYONETTA_2) && !isRunningTitleID(TITLE_ID_INTERNET_BROWSER); } \ No newline at end of file diff --git a/tcpgecko.elf b/tcpgecko.elf index f4d0d72..2274627 100644 Binary files a/tcpgecko.elf and b/tcpgecko.elf differ