diff --git a/src/dynamic_libs/fs_functions.h b/src/dynamic_libs/fs_functions.h index 6d67123..3b77111 100644 --- a/src/dynamic_libs/fs_functions.h +++ b/src/dynamic_libs/fs_functions.h @@ -28,7 +28,7 @@ extern "C" { #endif -#include "common/fs_defs.h" +#include "../common/fs_defs.h" void InitFSFunctionPointers(void); diff --git a/src/entry.c b/src/entry.c index 69a48f8..ca51c83 100644 --- a/src/entry.c +++ b/src/entry.c @@ -16,7 +16,7 @@ int __entry_menu(int argc, char **argv) { InitSocketFunctionPointers(); InitGX2FunctionPointers(); - start_pygecko(); + startTCPGecko(); return EXIT_RELAUNCH_ON_LOAD; } diff --git a/src/fs/fs_utils.c b/src/fs/fs_utils.c index 1f4d57b..ef8885e 100644 --- a/src/fs/fs_utils.c +++ b/src/fs/fs_utils.c @@ -4,7 +4,7 @@ #include #include #include "common/fs_defs.h" -#include "dynamic_libs/fs_functions.h" +#include "../dynamic_libs/fs_functions.h" int MountFS(void *pClient, void *pCmd, char **mount_path) diff --git a/src/fs/sd_fat_devoptab.c b/src/fs/sd_fat_devoptab.c index f5b278b..c458ad2 100644 --- a/src/fs/sd_fat_devoptab.c +++ b/src/fs/sd_fat_devoptab.c @@ -29,8 +29,8 @@ #include #include #include -#include "dynamic_libs/fs_functions.h" -#include "dynamic_libs/os_functions.h" +#include "../dynamic_libs/fs_functions.h" +#include "../dynamic_libs/os_functions.h" #include "fs_utils.h" #define FS_ALIGNMENT 0x40 diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index aaca44f..474238f 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -1,8 +1,8 @@ -#include "common/os_defs.h" -#include "common/kernel_defs.h" -#include "common/common.h" -#include "dynamic_libs/os_functions.h" -#include "utils/utils.h" +#include "../common/os_defs.h" +#include "../common/kernel_defs.h" +#include "../common/common.h" +#include "../dynamic_libs/os_functions.h" +#include "../utils/utils.h" #include "syscalls.h" extern void my_PrepareTitle_hook(void); diff --git a/src/main.c b/src/main.c index 2feaa2c..3f56f92 100644 --- a/src/main.c +++ b/src/main.c @@ -15,12 +15,11 @@ #include "fs/sd_fat_devoptab.h" #include "kernel/kernel_functions.h" #include "system/memory.h" -#include "utils/logger.h" #include "utils/utils.h" #include "common/common.h" #include "main.h" -int CCHandler; +int codeHandlerInstalled; void startMiiMaker() { char buf_vol_odd[20]; @@ -45,12 +44,6 @@ int Menu_Main(void) { InitVPadFunctionPointers(); InitSysFunctionPointers(); - const char ip_address[100] = "192.168.178.49"; - log_init(ip_address); - log_deinit(); - log_init(ip_address); - log_printf("Started %s\n", cosAppXmlInfoStruct.rpx_name); - if (strcasecmp("men.rpx", cosAppXmlInfoStruct.rpx_name) == 0) { return EXIT_RELAUNCH_ON_LOAD; } else if (strlen(cosAppXmlInfoStruct.rpx_name) > 0 && @@ -194,7 +187,7 @@ int Menu_Main(void) { m_DCInvalidateRange((u32) physicalCodeHandlerAddress, codeHandlerSize); unmount_sd_fat("sd"); - CCHandler = 1; + codeHandlerInstalled = 1; launchMethod = 2; break; @@ -212,8 +205,6 @@ int Menu_Main(void) { MEM1_free(screenBuffer); screenBuffer = NULL; - log_deinit(); - memoryRelease(); if (launchMethod == 0) { diff --git a/src/main.h b/src/main.h index 1b444ac..f74b6bd 100644 --- a/src/main.h +++ b/src/main.h @@ -12,7 +12,7 @@ extern "C" { //! C wrapper for our C++ functions int Menu_Main(void); -extern int CCHandler; +extern int codeHandlerInstalled; #ifdef __cplusplus } diff --git a/src/patcher/fs_logger.c b/src/patcher/fs_logger.c index 514f299..163ddf5 100644 --- a/src/patcher/fs_logger.c +++ b/src/patcher/fs_logger.c @@ -1,7 +1,7 @@ #include #include "common/common.h" -#include "dynamic_libs/os_functions.h" -#include "dynamic_libs/socket_functions.h" +#include "../dynamic_libs/os_functions.h" +#include "../dynamic_libs/socket_functions.h" #include "function_hooks.h" #include "fs_logger.h" #include "utils/utils.h" diff --git a/src/pygecko.c b/src/pygecko.c index f3ae424..3b8c4cc 100644 --- a/src/pygecko.c +++ b/src/pygecko.c @@ -14,6 +14,7 @@ #include "dynamic_libs/fs_functions.h" #include "common/fs_defs.h" #include "system/exception_handler.h" +#include "utils/logger.h" void *client; void *commandBlock; @@ -53,6 +54,9 @@ struct pygecko_bss_t { #define COMMAND_MEMORY_SEARCH 0x73 // #define COMMAND_SYSTEM_CALL 0x80 #define COMMAND_EXECUTE_ASSEMBLY 0x81 +#define COMMAND_PAUSE_CONSOLE 0x82 +#define COMMAND_RESUME_CONSOLE 0x83 +#define COMMAND_IS_CONSOLE_PAUSED 0x84 #define COMMAND_SERVER_VERSION 0x99 #define COMMAND_OS_VERSION 0x9A #define COMMAND_RUN_KERNEL_COPY_SERVICE 0xCD @@ -152,7 +156,8 @@ unsigned char *memcpy_buffer[DATA_BUFFER_SIZE]; void pygecko_memcpy(unsigned char *destinationBuffer, unsigned char *sourceBuffer, unsigned int length) { memcpy(memcpy_buffer, sourceBuffer, length); - SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &memcpy_buffer, length); + SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &memcpy_buffer, + length); DCFlushRange(destinationBuffer, (u32) length); } @@ -199,6 +204,48 @@ void startKernelCopyService() { OSResumeThread(thread); } +int (*AVMGetDRCScanMode)(int); + +unsigned long getConsoleStatePatchAddress() { + if (AVMGetDRCScanMode) { + log_print("Already acquired!\n"); + } else { + // Acquire the RPL and function + log_print("Acquiring...\n"); + unsigned int avm_handle; + OSDynLoad_Acquire("avm.rpl", (u32 * ) & avm_handle); + ASSERT_ALLOCATED(avm_handle, "avm.rpl") + OSDynLoad_FindExport((u32) avm_handle, 0, "AVMGetDRCScanMode", &AVMGetDRCScanMode); + ASSERT_ALLOCATED(AVMGetDRCScanMode, "AVMGetDRCScanMode") + log_print("Acquired!\n"); + } + + return (unsigned long) (AVMGetDRCScanMode + 0x44); +} + +typedef enum { + PAUSED = 0x38000001, RUNNING = 0x38000000 +} ConsoleState; + +void writeConsoleState(ConsoleState state) { + // Get the value to write + int patchValue = state; + log_printf("Patch value: %x\n", patchValue); + + // Write the value + unsigned int patchAddress = getConsoleStatePatchAddress(); + log_printf("Patch address: %x\n", patchAddress); + pygecko_memcpy((unsigned char *) patchAddress, (unsigned char *) &patchValue, 4); +} + +bool isConsolePaused() { + unsigned int patchAddress = getConsoleStatePatchAddress(); + log_printf("Patch address: %x\n", patchAddress); + int value = *(unsigned int *) patchAddress; + + return value == PAUSED; +} + /*Validates the address range (last address inclusive) but is SLOW on bigger ranges */ static int validateAddressRange(int starting_address, int ending_address) { return __OSValidateAddressSpaceRange(1, (void *) starting_address, ending_address - starting_address + 1); @@ -252,7 +299,7 @@ static int sendwait(struct pygecko_bss_t *bss, int sock, const void *buffer, int return ret; } -static int sendbyte(struct pygecko_bss_t *bss, int sock, unsigned char byte) { +static int sendByte(struct pygecko_bss_t *bss, int sock, unsigned char byte) { unsigned char buffer[1]; buffer[0] = byte; @@ -405,7 +452,7 @@ int kernelMemoryCompare(const void *sourceBuffer, return kern_read(sourceBuffer) - kern_read(destinationBuffer); } -static int rungecko(struct pygecko_bss_t *bss, int clientfd) { +static int listenForCommands(struct pygecko_bss_t *bss, int clientfd) { int ret; // Hold the command and the data @@ -480,7 +527,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { if (rangeIterationIndex == length) { // No need to send all zero bytes for performance - ret = sendbyte(bss, clientfd, ONLY_ZEROS_READ); + ret = sendByte(bss, clientfd, ONLY_ZEROS_READ); CHECK_ERROR(ret < 0) } else { // TODO Compression of ptr, sending of status, compressed size and data, length: 1 + 4 + len(data) @@ -527,7 +574,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { if (rangeIterationIndex == length) { // No need to send all zero bytes for performance - ret = sendbyte(bss, clientfd, ONLY_ZEROS_READ); + ret = sendByte(bss, clientfd, ONLY_ZEROS_READ); CHECK_ERROR(ret < 0) } else { // TODO Compression of ptr, sending of status, compressed size and data, length: 1 + 4 + len(data) @@ -564,7 +611,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { int isAddressRangeValid = validateAddressRange(startingAddress, endingAddress); - sendbyte(bss, clientfd, (unsigned char) isAddressRangeValid); + sendByte(bss, clientfd, (unsigned char) isAddressRangeValid); break; } /*case COMMAND_DISASSEMBLE_RANGE: { @@ -1126,7 +1173,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { break; } case COMMAND_SERVER_STATUS: { - ret = sendbyte(bss, clientfd, 1); + ret = sendByte(bss, clientfd, 1); CHECK_ERROR(ret < 0) break; } @@ -1259,6 +1306,24 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { break; } + case COMMAND_PAUSE_CONSOLE: { + writeConsoleState(PAUSED); + + break; + } + case COMMAND_RESUME_CONSOLE: { + writeConsoleState(RUNNING); + + break; + } + case COMMAND_IS_CONSOLE_PAUSED: { + bool paused = isConsolePaused(); + log_printf("Paused: %d\n", paused); + ret = sendByte(bss, clientfd, (unsigned char) paused); + ASSERT_FUNCTION_SUCCEEDED(ret, "sendByte (sending paused console status)") + + break; + } case COMMAND_SERVER_VERSION: { char versionBuffer[50]; strcpy(versionBuffer, SERVER_VERSION); @@ -1299,7 +1364,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) { return 0; } -static int start(int argc, void *argv) { +static int runTCPGeckoServer(int argc, void *argv) { int sockfd = -1, clientfd = -1, ret = 0, len; struct sockaddr_in addr; struct pygecko_bss_t *bss = argv; @@ -1307,7 +1372,10 @@ static int start(int argc, void *argv) { setup_os_exceptions(); socket_lib_init(); - while (1) { + log_init("192.168.2.103"); + log_print("TCP Gecko Installer\n"); + + while (true) { addr.sin_family = AF_INET; addr.sin_port = 7331; addr.sin_addr.s_addr = 0; @@ -1321,11 +1389,11 @@ static int start(int argc, void *argv) { ret = listen(sockfd, 20); CHECK_ERROR(ret < 0) - while (1) { + while (true) { len = 16; clientfd = accept(sockfd, (void *) &addr, &len); CHECK_ERROR(clientfd == -1) - ret = rungecko(bss, clientfd); + ret = listenForCommands(bss, clientfd); CHECK_ERROR(ret < 0) socketclose(clientfd); clientfd = -1; @@ -1345,7 +1413,8 @@ static int start(int argc, void *argv) { return 0; } -static int CCThread(int argc, void *argv) { +static int startTCPGeckoThread(int argc, void *argv) { + // Run the TCP Gecko Installer server struct pygecko_bss_t *bss; bss = memalign(0x40, sizeof(struct pygecko_bss_t)); @@ -1353,25 +1422,28 @@ static int CCThread(int argc, void *argv) { return 0; memset(bss, 0, sizeof(struct pygecko_bss_t)); - if (OSCreateThread(&bss->thread, start, 1, bss, (u32) bss->stack + sizeof(bss->stack), sizeof(bss->stack), 0, + if (OSCreateThread(&bss->thread, runTCPGeckoServer, 1, bss, (u32) bss->stack + sizeof(bss->stack), + sizeof(bss->stack), 0, 0xc) == 1) { OSResumeThread(&bss->thread); } else { free(bss); } - if (CCHandler == 1) { - void (*entrypoint)() = (void *) CODE_HANDLER_INSTALL_ADDRESS; + // Execute the code handler if it is installed + if (codeHandlerInstalled) { + void (*codeHandlerFunction)() = (void (*)()) CODE_HANDLER_INSTALL_ADDRESS; - while (1) { + while (true) { usleep(9000); - entrypoint(); + codeHandlerFunction(); } } + return 0; } -void start_pygecko() { +void startTCPGecko() { // Force the debugger to be initialized by default // writeInt((unsigned int) (OSIsDebuggerInitialized + 0x1C), 0x38000001); // li r3, 1 @@ -1381,7 +1453,7 @@ void start_pygecko() { void *thread = memalign(0x40, 0x1000); ASSERT_ALLOCATED(thread, "TCP Gecko thread") - int status = OSCreateThread(thread, CCThread, 1, + int status = OSCreateThread(thread, startTCPGeckoThread, 1, NULL, (u32) stack + sizeof(stack), sizeof(stack), 0, OS_THREAD_ATTR_AFFINITY_CORE1 | OS_THREAD_ATTR_PINNED_AFFINITY | OS_THREAD_ATTR_DETACH); diff --git a/src/pygecko.h b/src/pygecko.h index b4e6c55..1945fdd 100644 --- a/src/pygecko.h +++ b/src/pygecko.h @@ -10,7 +10,7 @@ extern "C" { #endif //! C wrapper for our C++ functions -void start_pygecko(void); +void startTCPGecko(void); #ifdef __cplusplus } diff --git a/src/system/exception_handler.c b/src/system/exception_handler.c index 7dbd6d6..d5b63b2 100644 --- a/src/system/exception_handler.c +++ b/src/system/exception_handler.c @@ -1,6 +1,6 @@ #include -#include "dynamic_libs/os_functions.h" -#include "utils/logger.h" +#include "../dynamic_libs/os_functions.h" +#include "../utils/logger.h" #include "exception_handler.h" #define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4 diff --git a/src/system/memory.c b/src/system/memory.c index e560cc7..52dc327 100644 --- a/src/system/memory.c +++ b/src/system/memory.c @@ -16,8 +16,8 @@ ****************************************************************************/ #include #include -#include "dynamic_libs/os_functions.h" -#include "common/common.h" +#include "../dynamic_libs/os_functions.h" +#include "../common/common.h" #include "memory.h" #define MEMORY_ARENA_1 0 diff --git a/src/utils/logger.c b/src/utils/logger.c index 49ab1ef..b962cd4 100644 --- a/src/utils/logger.c +++ b/src/utils/logger.c @@ -2,18 +2,15 @@ #include #include #include -#include -#include "common/common.h" -#include "dynamic_libs/os_functions.h" -#include "dynamic_libs/socket_functions.h" +#include "../dynamic_libs/os_functions.h" +#include "../dynamic_libs/socket_functions.h" #include "logger.h" -static int log_socket = 0; +#ifdef DEBUG_LOGGER +static int log_socket = -1; static volatile int log_lock = 0; - -void log_init(const char * ipString) -{ +void log_init(const char *ipString) { log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (log_socket < 0) return; @@ -24,65 +21,60 @@ void log_init(const char * ipString) connect_addr.sin_port = 4405; inet_aton(ipString, &connect_addr.sin_addr); - if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) - { - socketclose(log_socket); - log_socket = -1; + if (connect(log_socket, (struct sockaddr *) &connect_addr, sizeof(connect_addr)) < 0) { + socketclose(log_socket); + log_socket = -1; } } -void log_deinit(void) -{ - if(log_socket > 0) - { - socketclose(log_socket); - log_socket = -1; - } +void log_deinit(void) { + if (log_socket >= 0) { + socketclose(log_socket); + log_socket = -1; + } } -void log_print(const char *str) -{ - // socket is always 0 initially as it is in the BSS - if(log_socket <= 0) { - return; - } +void log_print(const char *str) { + // socket is always 0 initially as it is in the BSS + if (log_socket < 0) { + return; + } - while(log_lock) - usleep(1000); - log_lock = 1; + while (log_lock) + usleep(1000); + log_lock = 1; - int len = strlen(str); - int ret; - while (len > 0) { - int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet - ret = send(log_socket, str, block, 0); - if(ret < 0) - break; + int len = strlen(str); + int ret; + while (len > 0) { + int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet + ret = send(log_socket, str, block, 0); + if (ret < 0) + break; - len -= ret; - str += ret; - } + len -= ret; + str += ret; + } - log_lock = 0; + log_lock = 0; } -void log_printf(const char *format, ...) -{ - if(log_socket <= 0) { - return; - } +void log_printf(const char *format, ...) { + if (log_socket < 0) { + return; + } - char * tmp = NULL; + char *tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) - { - log_print(tmp); + if ((vasprintf(&tmp, format, va) >= 0) && tmp) { + log_print(tmp); } va_end(va); - if(tmp) + if (tmp) free(tmp); } +#endif \ No newline at end of file diff --git a/src/utils/logger.h b/src/utils/logger.h index 32fab70..dd7cc71 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -5,85 +5,22 @@ extern "C" { #endif -/* Communication bytes with the server */ -// Com -#define BYTE_NORMAL 0xff -#define BYTE_SPECIAL 0xfe -#define BYTE_OK 0xfd -#define BYTE_PING 0xfc -#define BYTE_LOG_STR 0xfb -#define BYTE_DISCONNECT 0xfa - -// SD -#define BYTE_MOUNT_SD 0xe0 -#define BYTE_MOUNT_SD_OK 0xe1 -#define BYTE_MOUNT_SD_BAD 0xe2 - -// Replacement -#define BYTE_STAT 0x00 -#define BYTE_STAT_ASYNC 0x01 -#define BYTE_OPEN_FILE 0x02 -#define BYTE_OPEN_FILE_ASYNC 0x03 -#define BYTE_OPEN_DIR 0x04 -#define BYTE_OPEN_DIR_ASYNC 0x05 -#define BYTE_CHANGE_DIR 0x06 -#define BYTE_CHANGE_DIR_ASYNC 0x07 -#define BYTE_MAKE_DIR 0x08 -#define BYTE_MAKE_DIR_ASYNC 0x09 -#define BYTE_RENAME 0x0A -#define BYTE_RENAME_ASYNC 0x0B -#define BYTE_REMOVE 0x0C -#define BYTE_REMOVE_ASYNC 0x0D - -// Log -#define BYTE_CLOSE_FILE 0x40 -#define BYTE_CLOSE_FILE_ASYNC 0x41 -#define BYTE_CLOSE_DIR 0x42 -#define BYTE_CLOSE_DIR_ASYNC 0x43 -#define BYTE_FLUSH_FILE 0x44 -#define BYTE_GET_ERROR_CODE_FOR_VIEWER 0x45 -#define BYTE_GET_LAST_ERROR 0x46 -#define BYTE_GET_MOUNT_SOURCE 0x47 -#define BYTE_GET_MOUNT_SOURCE_NEXT 0x48 -#define BYTE_GET_POS_FILE 0x49 -#define BYTE_SET_POS_FILE 0x4A -#define BYTE_GET_STAT_FILE 0x4B -#define BYTE_EOF 0x4C -#define BYTE_READ_FILE 0x4D -#define BYTE_READ_FILE_ASYNC 0x4E -#define BYTE_READ_FILE_WITH_POS 0x4F -#define BYTE_READ_DIR 0x50 -#define BYTE_READ_DIR_ASYNC 0x51 -#define BYTE_GET_CWD 0x52 -#define BYTE_SET_STATE_CHG_NOTIF 0x53 -#define BYTE_TRUNCATE_FILE 0x54 -#define BYTE_WRITE_FILE 0x55 -#define BYTE_WRITE_FILE_WITH_POS 0x56 - -#define BYTE_SAVE_INIT 0x57 -#define BYTE_SAVE_SHUTDOWN 0x58 -#define BYTE_SAVE_INIT_SAVE_DIR 0x59 -#define BYTE_SAVE_FLUSH_QUOTA 0x5A -#define BYTE_SAVE_OPEN_DIR 0x5B -#define BYTE_SAVE_REMOVE 0x5C - -#define BYTE_CREATE_THREAD 0x60 - -#define LOADIINE_LOGGER_IP "192.168.178.3" - -int logger_connect(int *socket); -void logger_disconnect(int socket); -void log_string(int sock, const char* str, char byte); -void log_byte(int sock, char byte); +#define DEBUG_LOGGER 1 +#ifdef DEBUG_LOGGER void log_init(const char * ip); void log_deinit(void); void log_print(const char *str); void log_printf(const char *format, ...); +#else +#define log_init(x) +#define log_deinit() +#define log_print(x) +#define log_printf(x, ...) +#endif #ifdef __cplusplus } #endif #endif - diff --git a/src/utils/net.c b/src/utils/net.c index 800fdc6..a1b259e 100644 --- a/src/utils/net.c +++ b/src/utils/net.c @@ -1,8 +1,8 @@ #include #include -#include "common/common.h" -#include "dynamic_libs/os_functions.h" -#include "dynamic_libs/socket_functions.h" +#include "../common/common.h" +#include "../dynamic_libs/os_functions.h" +#include "../dynamic_libs/socket_functions.h" #include "net.h" static volatile int iLock = 0; diff --git a/tcpgecko.elf b/tcpgecko.elf index 2c4040a..45f2f99 100644 Binary files a/tcpgecko.elf and b/tcpgecko.elf differ