diff --git a/Makefile b/Makefile index f572f5b..51f7691 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lz -liosuhax -lgd +LIBS := -lm -lfat -lz -liosuhax -lgd #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/src/common/common.h b/src/common/common.h index 9d0dae4..b095ad4 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -1,11 +1,11 @@ -#ifndef COMMON_H -#define COMMON_H +#pragma once #ifdef __cplusplus extern "C" { #endif #include "os_defs.h" +#include "fs_defs.h" #define CODE_HANDLER_INSTALL_ADDRESS 0x010F4000 @@ -58,17 +58,15 @@ extern "C" { #define RESTORE_INSTR_ADDR ((restore_instructions_t*)(MEM_BASE + 0x1600)) typedef struct _restore_instructions_t { - unsigned int magic; - unsigned int instr_count; - struct { - unsigned int addr; - unsigned int instr; - } data[0]; + unsigned int magic; + unsigned int instr_count; + struct { + unsigned int addr; + unsigned int instr; + } data[0]; } restore_instructions_t; #ifdef __cplusplus } #endif -#endif /* COMMON_H */ - diff --git a/src/dynamic_libs/fs_functions.h b/src/dynamic_libs/fs_functions.h index 3b77111..21c1d47 100644 --- a/src/dynamic_libs/fs_functions.h +++ b/src/dynamic_libs/fs_functions.h @@ -50,8 +50,7 @@ extern int (*FSUnmount)(void *pClient, void *pCmd, const char *target, int errHa extern int (*FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); -extern int -(*FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); +extern int (*FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); extern int (*FSRemove)(void *pClient, void *pCmd, const char *path, int error); @@ -63,8 +62,7 @@ extern int (*FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void * extern int (*FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); -extern int -(*FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); +extern int (*FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); extern int (*FSRemove)(void *pClient, void *pCmd, const char *path, int error); @@ -76,9 +74,7 @@ extern int (*FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, int extern int (*FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); -extern int -(*FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, - void *asyncParams); +extern int (*FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); extern int (*FSRollbackQuota)(void *pClient, void *pCmd, const char *path, int error); @@ -104,11 +100,9 @@ extern int (*FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, int er extern int (*FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); -extern int (*FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, - const void *asyncParams); +extern int (*FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); -extern int -(*FSReadFile)(void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); +extern int (*FSReadFile)(void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); extern int (*FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling); @@ -120,9 +114,7 @@ extern int (*FSGetStatFile)(void *pClient, void *pCmd, int fd, void *buffer, int extern int (*FSSetPosFile)(void *pClient, void *pCmd, int fd, int pos, int error); -extern int -(*FSWriteFile)(void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, - int error); +extern int (*FSWriteFile)(void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); extern int (*FSBindMount)(void *pClient, void *pCmd, char *source, char *target, int error); diff --git a/src/dynamic_libs/socket_functions.h b/src/dynamic_libs/socket_functions.h index 03c9071..5252393 100644 --- a/src/dynamic_libs/socket_functions.h +++ b/src/dynamic_libs/socket_functions.h @@ -57,38 +57,49 @@ extern u32 hostIpAddress; struct in_addr { - unsigned int s_addr; + unsigned int s_addr; }; struct sockaddr_in { - short sin_family; - unsigned short sin_port; - struct in_addr sin_addr; - char sin_zero[8]; + short sin_family; + unsigned short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; }; -struct sockaddr -{ - unsigned short sa_family; - char sa_data[14]; +struct sockaddr { + unsigned short sa_family; + char sa_data[14]; }; void InitSocketFunctionPointers(void); extern int (*socket_lib_init)(void); + extern int (*socket_lib_finish)(void); + extern int (*socket)(int domain, int type, int protocol); + extern int (*socketclose)(int s); + extern int (*connect)(int s, void *addr, int addrlen); -extern int (*bind)(s32 s,struct sockaddr *name,s32 namelen); -extern int (*listen)(s32 s,u32 backlog); -extern int (*accept)(s32 s,struct sockaddr *addr,s32 *addrlen); + +extern int (*bind)(s32 s, struct sockaddr *name, s32 namelen); + +extern int (*listen)(s32 s, u32 backlog); + +extern int (*accept)(s32 s, struct sockaddr *addr, s32 *addrlen); + extern int (*send)(int s, const void *buffer, int size, int flags); + extern int (*recv)(int s, void *buffer, int size, int flags); + extern int (*sendto)(int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); + extern int (*setsockopt)(int s, int level, int optname, void *optval, int optlen); -extern char * (*inet_ntoa)(struct in_addr in); +extern char *(*inet_ntoa)(struct in_addr in); + extern int (*inet_aton)(const char *cp, struct in_addr *inp); #ifdef __cplusplus diff --git a/src/fs/CFile.cpp b/src/fs/CFile.cpp index 161b980..b369565 100644 --- a/src/fs/CFile.cpp +++ b/src/fs/CFile.cpp @@ -2,60 +2,54 @@ #include #include "CFile.hpp" -CFile::CFile() -{ +CFile::CFile() { iFd = -1; mem_file = NULL; filesize = 0; pos = 0; } -CFile::CFile(const std::string & filepath, eOpenTypes mode) -{ +CFile::CFile(const std::string &filepath, eOpenTypes mode) { iFd = -1; this->open(filepath, mode); } -CFile::CFile(const u8 * mem, int size) -{ +CFile::CFile(const u8 *mem, int size) { iFd = -1; this->open(mem, size); } -CFile::~CFile() -{ +CFile::~CFile() { this->close(); } -int CFile::open(const std::string & filepath, eOpenTypes mode) -{ +int CFile::open(const std::string &filepath, eOpenTypes mode) { this->close(); s32 openMode = 0; - switch(mode) - { - default: - case ReadOnly: - openMode = O_RDONLY; - break; - case WriteOnly: - openMode = O_WRONLY; - break; - case ReadWrite: - openMode = O_RDWR; - break; - case Append: - openMode = O_APPEND | O_WRONLY; - break; + switch (mode) { + default: + case ReadOnly: + openMode = O_RDONLY; + break; + case WriteOnly: + openMode = O_WRONLY; + break; + case ReadWrite: + openMode = O_RDWR; + break; + case Append: + openMode = O_APPEND | O_WRONLY; + break; } - //! Using fopen works only on the first launch as expected - //! on the second launch it causes issues because we don't overwrite - //! the .data sections which is needed for a normal application to re-init - //! this will be added with launching as RPX + //! Using fopen works only on the first launch as expected + //! on the second launch it causes issues because we don't overwrite + //! the .data sections which is needed for a normal application to re-init + //! this will be added with launching as RPX iFd = ::open(filepath.c_str(), openMode); - if(iFd < 0) + if (iFd < 0) return iFd; @@ -65,8 +59,7 @@ int CFile::open(const std::string & filepath, eOpenTypes mode) return 0; } -int CFile::open(const u8 * mem, int size) -{ +int CFile::open(const u8 *mem, int size) { this->close(); mem_file = mem; @@ -75,9 +68,8 @@ int CFile::open(const u8 * mem, int size) return 0; } -void CFile::close() -{ - if(iFd >= 0) +void CFile::close() { + if (iFd >= 0) ::close(iFd); iFd = -1; @@ -86,27 +78,24 @@ void CFile::close() pos = 0; } -int CFile::read(u8 * ptr, size_t size) -{ - if(iFd >= 0) - { - int ret = ::read(iFd, ptr,size); - if(ret > 0) +int CFile::read(u8 *ptr, size_t size) { + if (iFd >= 0) { + int ret = ::read(iFd, ptr, size); + if (ret > 0) pos += ret; return ret; } int readsize = size; - if(readsize > (s64) (filesize-pos)) - readsize = filesize-pos; + if (readsize > (s64)(filesize - pos)) + readsize = filesize - pos; - if(readsize <= 0) + if (readsize <= 0) return readsize; - if(mem_file != NULL) - { - memcpy(ptr, mem_file+pos, readsize); + if (mem_file != NULL) { + memcpy(ptr, mem_file + pos, readsize); pos += readsize; return readsize; } @@ -114,60 +103,47 @@ int CFile::read(u8 * ptr, size_t size) return -1; } -int CFile::write(const u8 * ptr, size_t size) -{ - if(iFd >= 0) - { - size_t done = 0; - while(done < size) - { - int ret = ::write(iFd, ptr, size - done); - if(ret <= 0) - return ret; +int CFile::write(const u8 *ptr, size_t size) { + if (iFd >= 0) { + size_t done = 0; + while (done < size) { + int ret = ::write(iFd, ptr, size - done); + if (ret <= 0) + return ret; - ptr += ret; - done += ret; - pos += ret; - } + ptr += ret; + done += ret; + pos += ret; + } return done; } return -1; } -int CFile::seek(long int offset, int origin) -{ +int CFile::seek(long int offset, int origin) { int ret = 0; s64 newPos = pos; - if(origin == SEEK_SET) - { + if (origin == SEEK_SET) { newPos = offset; - } - else if(origin == SEEK_CUR) - { + } else if (origin == SEEK_CUR) { newPos += offset; - } - else if(origin == SEEK_END) - { - newPos = filesize+offset; + } else if (origin == SEEK_END) { + newPos = filesize + offset; } - if(newPos < 0) - { + if (newPos < 0) { pos = 0; - } - else { - pos = newPos; + } else { + pos = newPos; } - if(iFd >= 0) + if (iFd >= 0) ret = ::lseek(iFd, pos, SEEK_SET); - if(mem_file != NULL) - { - if(pos > filesize) - { + if (mem_file != NULL) { + if (pos > filesize) { pos = filesize; } } @@ -175,23 +151,21 @@ int CFile::seek(long int offset, int origin) return ret; } -int CFile::fwrite(const char *format, ...) -{ - int result = -1; - char * tmp = NULL; +int CFile::fwrite(const char *format, ...) { + int result = -1; + char *tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) - { - result = this->write((u8 *)tmp, strlen(tmp)); + if ((vasprintf(&tmp, format, va) >= 0) && tmp) { + result = this->write((u8 *) tmp, strlen(tmp)); } va_end(va); - if(tmp) + if (tmp) free(tmp); - return result; + return result; } diff --git a/src/fs/CFile.hpp b/src/fs/CFile.hpp index 1580eb3..1374469 100644 --- a/src/fs/CFile.hpp +++ b/src/fs/CFile.hpp @@ -7,51 +7,60 @@ #include #include #include +#include "../common/fs_defs.h" -class CFile -{ - public: - enum eOpenTypes - { - ReadOnly, - WriteOnly, - ReadWrite, - Append - }; +class CFile { +public: + enum eOpenTypes { + ReadOnly, + WriteOnly, + ReadWrite, + Append + }; - CFile(); - CFile(const std::string & filepath, eOpenTypes mode); - CFile(const u8 * memory, int memsize); - virtual ~CFile(); + CFile(); - int open(const std::string & filepath, eOpenTypes mode); - int open(const u8 * memory, int memsize); + CFile(const std::string &filepath, eOpenTypes mode); - bool isOpen() const { - if(iFd >= 0) - return true; + CFile(const u8 *memory, int memsize); - if(mem_file) - return true; + virtual ~CFile(); - return false; - } + int open(const std::string &filepath, eOpenTypes mode); - void close(); + int open(const u8 *memory, int memsize); - int read(u8 * ptr, size_t size); - int write(const u8 * ptr, size_t size); - int fwrite(const char *format, ...); - int seek(long int offset, int origin); - u64 tell() { return pos; }; - u64 size() { return filesize; }; - void rewind() { this->seek(0, SEEK_SET); }; + bool isOpen() const { + if (iFd >= 0) + return true; - protected: - int iFd; - const u8 * mem_file; - u64 filesize; - u64 pos; + if (mem_file) + return true; + + return false; + } + + void close(); + + int read(u8 *ptr, size_t size); + + int write(const u8 *ptr, size_t size); + + int fwrite(const char *format, ...); + + int seek(long int offset, int origin); + + u64 tell() {return pos;}; + + u64 size() {return filesize;}; + + void rewind() {this->seek(0, SEEK_SET);}; + +protected: + int iFd; + const u8 *mem_file; + u64 filesize; + u64 pos; }; -#endif +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.cpp similarity index 94% rename from src/main.c rename to src/main.cpp index 028a7ce..fffaa64 100644 --- a/src/main.c +++ b/src/main.cpp @@ -18,6 +18,8 @@ #include "utils/logger.h" #include "utils/function_patcher.h" #include "patcher/function_patcher_gx2.h" +#include "patcher/function_patcher_coreinit.h" +#include "utils/sd_ip_reader.hpp" bool isCodeHandlerInstalled; @@ -30,6 +32,7 @@ typedef enum { void applyFunctionPatches() { patchIndividualMethodHooks(method_hooks_gx2, method_hooks_size_gx2, method_calls_gx2); + patchIndividualMethodHooks(method_hooks_coreinit, method_hooks_size_coreinit, method_calls_coreinit); } /* Entry point */ @@ -91,7 +94,7 @@ int Menu_Main(void) { int screenBuffer0Size = OSScreenGetBufferSizeEx(0); int screenBuffer1Size = OSScreenGetBufferSizeEx(1); - unsigned char *screenBuffer = MEM1_alloc(screenBuffer0Size + screenBuffer1Size, 0x40); + unsigned char *screenBuffer = (unsigned char *) MEM1_alloc(screenBuffer0Size + screenBuffer1Size, 0x40); OSScreenSetBufferEx(0, screenBuffer); OSScreenSetBufferEx(1, (screenBuffer + screenBuffer0Size)); @@ -147,7 +150,7 @@ int Menu_Main(void) { isCodeHandlerInstalled = true; launchMethod = TCP_GECKO; - log_init(COMPUTER_IP_ADDRESS); + initializeUDPLog(); log_print("Patching functions\n"); applyFunctionPatches(); diff --git a/src/patcher/function_patcher_coreinit.c b/src/patcher/function_patcher_coreinit.c new file mode 100644 index 0000000..9d2ec72 --- /dev/null +++ b/src/patcher/function_patcher_coreinit.c @@ -0,0 +1,47 @@ +#include "../utils/function_patcher.h" +#include "../utils/logger.h" + +declareFunctionHook(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling) { + log_printf("FSOpenFile(): %s", path); + return real_FSOpenFile(pClient, pCmd, path, mode, fd, errHandling); +} + +declareFunctionHook(int, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams) { + log_printf("FSOpenFileAsync(): %s", path); + return real_FSOpenFileAsync(pClient, pCmd, path, mode, handle, error, asyncParams); +} + +declareFunctionHook(int, FSOpenDir, void *pClient, void *pCmd, const char *path, int *dh, int errHandling) { + log_printf("FSOpenDir(): %s", path); + return real_FSOpenDir(pClient, pCmd, path, dh, errHandling); +} + +declareFunctionHook(int, FSOpenDirAsync, void *pClient, void *pCmd, const char *path, int *handle, int error, void *asyncParams) { + log_printf("FSOpenDirAsync(): %s", path); + return real_FSOpenDirAsync(pClient, pCmd, path, handle, error, asyncParams); +} + +declareFunctionHook(int, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling) { + log_printf("FSGetStat(): %s", path); + return real_FSGetStat(pClient, pCmd, path, stats, errHandling); +} + +declareFunctionHook(int, FSGetStatAsync, void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling, void *asyncParams) { + log_printf("FSGetStatAsync(): %s", path); + return real_FSGetStatAsync(pClient, pCmd, path, stats, errHandling, asyncParams); +} + +FunctionHook method_hooks_coreinit[] __attribute__((section(".data"))) = { + makeFunctionHook(FSOpenFile, LIB_CORE_INIT, STATIC_FUNCTION), + makeFunctionHook(FSOpenFileAsync, LIB_CORE_INIT, STATIC_FUNCTION), + + makeFunctionHook(FSOpenDir, LIB_CORE_INIT, STATIC_FUNCTION), + makeFunctionHook(FSOpenDirAsync, LIB_CORE_INIT, STATIC_FUNCTION), + + makeFunctionHook(FSGetStat, LIB_CORE_INIT, STATIC_FUNCTION), + makeFunctionHook(FSGetStatAsync, LIB_CORE_INIT, STATIC_FUNCTION), +}; + +u32 method_hooks_size_coreinit __attribute__((section(".data"))) = sizeof(method_hooks_coreinit) / sizeof(FunctionHook); + +volatile unsigned int method_calls_coreinit[sizeof(method_hooks_coreinit) / sizeof(FunctionHook) * FUNCTION_PATCHER_METHOD_STORE_SIZE] __attribute__((section(".data"))); \ No newline at end of file diff --git a/src/patcher/function_patcher_coreinit.h b/src/patcher/function_patcher_coreinit.h new file mode 100644 index 0000000..7298d6b --- /dev/null +++ b/src/patcher/function_patcher_coreinit.h @@ -0,0 +1,15 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../utils/function_patcher.h" + +extern FunctionHook method_hooks_coreinit[]; +extern u32 method_hooks_size_coreinit; +extern volatile unsigned int method_calls_coreinit[]; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/patcher/function_patcher_gx2.h b/src/patcher/function_patcher_gx2.h index 86f6893..b9791a3 100644 --- a/src/patcher/function_patcher_gx2.h +++ b/src/patcher/function_patcher_gx2.h @@ -15,7 +15,7 @@ * along with this program. If not, see . ****************************************************************************/ -#ifndef FUNCTION_PATCHER_EXAMPLE_GX2_FUNCTION_PATCHER_H +#pragma once #ifdef __cplusplus extern "C" { @@ -29,6 +29,4 @@ extern volatile unsigned int method_calls_gx2[]; #ifdef __cplusplus } -#endif - #endif \ No newline at end of file diff --git a/src/address.c b/src/system/address.cpp similarity index 90% rename from src/address.c rename to src/system/address.cpp index 2f8a7b9..5955973 100644 --- a/src/address.c +++ b/src/system/address.cpp @@ -1,5 +1,5 @@ #include "address.h" -#include "dynamic_libs/os_functions.h" +#include "../dynamic_libs/os_functions.h" int validateAddressRange(int starting_address, int ending_address) { return __OSValidateAddressSpaceRange(1, (void *) starting_address, ending_address - starting_address + 1); diff --git a/src/address.h b/src/system/address.h similarity index 100% rename from src/address.h rename to src/system/address.h diff --git a/src/disassembler.c b/src/system/disassembler.c similarity index 93% rename from src/disassembler.c rename to src/system/disassembler.c index a7725f1..1cdbcab 100644 --- a/src/disassembler.c +++ b/src/system/disassembler.c @@ -1,6 +1,6 @@ #include "disassembler.h" -#include "assertions.h" -#include "dynamic_libs/os_functions.h" +#include "../utils/assertions.h" +#include "../dynamic_libs/os_functions.h" #include #include #include diff --git a/src/disassembler.h b/src/system/disassembler.h similarity index 100% rename from src/disassembler.h rename to src/system/disassembler.h diff --git a/src/system/exception_handler.c b/src/system/exception_handler.c index d3998bd..fd262bc 100644 --- a/src/system/exception_handler.c +++ b/src/system/exception_handler.c @@ -140,5 +140,5 @@ unsigned char program_exception_cb(void *context) { void setup_os_exceptions() { OSSetExceptionCallback(OS_EXCEPTION_DSI, &dsi_exception_cb); OSSetExceptionCallback(OS_EXCEPTION_ISI, &isi_exception_cb); - // OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb); + OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb); } \ No newline at end of file diff --git a/src/system/hardware_breakpoints.h b/src/system/hardware_breakpoints.h index a61d550..e1cfbd7 100644 --- a/src/system/hardware_breakpoints.h +++ b/src/system/hardware_breakpoints.h @@ -58,7 +58,6 @@ static inline int getIABRMatch(void *interruptedContext) { unsigned char breakPointHandler(void *interruptedContext); void registerBreakPointHandler() { - log_init(COMPUTER_IP_ADDRESS); log_print("Registering breakpoint handler...\n"); // TODO Not working, never called? // OSSetExceptionCallback((u8) OS_EXCEPTION_DSI, &breakPointHandler); @@ -80,7 +79,6 @@ void forceDebuggerPresent() { }*/ static inline void setupBreakpointSupport() { - log_init(COMPUTER_IP_ADDRESS); /*log_print("Clear and enable...\n"); __OSClearAndEnableInterrupt(); log_print("Restore...\n"); @@ -95,7 +93,6 @@ static inline void setupBreakpointSupport() { void setDataBreakpoint(int address, bool read, bool write) { setupBreakpointSupport(); - log_init(COMPUTER_IP_ADDRESS); log_print("Setting DABR...\n"); OSSetDABR(1, address, read, write); log_print("DABR set\n"); @@ -125,8 +122,6 @@ void setInstructionBreakpoint(unsigned int address) { } unsigned char breakPointHandler(void *interruptedContext) { - log_init(COMPUTER_IP_ADDRESS); - // Check for data breakpoints int dataAddress = getDABRAddress(interruptedContext); if (OSIsAddressValid((const void *) dataAddress)) { diff --git a/src/kernel.h b/src/system/kernel.h similarity index 81% rename from src/kernel.h rename to src/system/kernel.h index ef8e112..e3e631b 100644 --- a/src/kernel.h +++ b/src/system/kernel.h @@ -1,10 +1,10 @@ #pragma once -#include "kernel/syscalls.h" -#include "assertions.h" -#include "dynamic_libs/os_functions.h" -#include "tcp_gecko.h" -#include "utils/logger.h" +#include "../kernel/syscalls.h" +#include "../utils/assertions.h" +#include "../dynamic_libs/os_functions.h" +#include "../tcp_gecko.h" +#include "../utils/logger.h" unsigned char *kernelCopyBuffer[sizeof(int)]; @@ -17,7 +17,8 @@ void kernelCopyData(unsigned char *destinationBuffer, unsigned char *sourceBuffe } memcpy(kernelCopyBufferOld, sourceBuffer, length); - SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &kernelCopyBufferOld, length); + SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &kernelCopyBufferOld, + length); DCFlushRange(destinationBuffer, (u32) length); } @@ -65,6 +66,8 @@ int kernelCopyService(int argc, void *argv) { *(((int *) KERNEL_COPY_SOURCE_ADDRESS) + 1) = 0; } } + + return 0; } void startKernelCopyService() { @@ -84,8 +87,8 @@ void startKernelCopyService() { #define MINIMUM_KERNEL_COMPARE_LENGTH 4 #define KERNEL_MEMORY_COMPARE_STEP_SIZE 1 -int kernelMemoryCompare(const void *sourceBuffer, - const void *destinationBuffer, +int kernelMemoryCompare(const char *sourceBuffer, + const char *destinationBuffer, int length) { if (length < MINIMUM_KERNEL_COMPARE_LENGTH) { ASSERT_MINIMUM_HOLDS(length, MINIMUM_KERNEL_COMPARE_LENGTH, "length"); @@ -110,4 +113,18 @@ int kernelMemoryCompare(const void *sourceBuffer, } return kern_read(sourceBuffer) - kern_read(destinationBuffer); +} + +void executeAssembly(unsigned char buffer[], unsigned int size) { + // Write the assembly to an executable code region + int destinationAddress = 0x10000000 - size; + kernelCopyData((unsigned char *) destinationAddress, buffer, size); + + // Execute the assembly from there + void (*function)() = (void (*)()) destinationAddress; + function(); + + // Clear the memory contents again + memset((void *) buffer, 0, size); + kernelCopyData((unsigned char *) destinationAddress, buffer, size); } \ No newline at end of file diff --git a/src/pause.h b/src/system/pause.h similarity index 85% rename from src/pause.h rename to src/system/pause.h index bc0e21b..476e5e0 100644 --- a/src/pause.h +++ b/src/system/pause.h @@ -1,9 +1,9 @@ #pragma once -#include "utils/logger.h" -#include "assertions.h" -#include "dynamic_libs/os_functions.h" -#include "common/fs_defs.h" +#include "../utils/logger.h" +#include "../utils/assertions.h" +#include "../dynamic_libs/os_functions.h" +#include "../common/fs_defs.h" #include "kernel.h" int (*AVMGetDRCScanMode)(int); @@ -22,7 +22,7 @@ unsigned long getConsoleStatePatchAddress() { log_print("Acquired!\n"); } - return (unsigned long) (AVMGetDRCScanMode + 0x44); + return (unsigned long) ((char *) AVMGetDRCScanMode + 0x44); } typedef enum { diff --git a/src/system/threads.c b/src/system/threads.cpp similarity index 96% rename from src/system/threads.c rename to src/system/threads.cpp index ad50584..e91bc43 100644 --- a/src/system/threads.c +++ b/src/system/threads.cpp @@ -2,11 +2,8 @@ #include "../utils/linked_list.h" #include "../dynamic_libs/os_functions.h" #include "../utils/logger.h" -#include "../main.h" struct node *getAllThreads() { - log_init(COMPUTER_IP_ADDRESS); - struct node *threads = NULL; int currentThreadAddress = OSGetCurrentThread(); log_printf("Thread address: %08x\n", currentThreadAddress); diff --git a/src/system/utilities.h b/src/system/utilities.h index df6f255..370dad4 100644 --- a/src/system/utilities.h +++ b/src/system/utilities.h @@ -3,7 +3,7 @@ #include "../dynamic_libs/os_functions.h" #include "../utils/logger.h" -#include "../kernel.h" +#include "kernel.h" #include "../common/kernel_types.h" void writeCode(u32 address, u32 instruction) { @@ -13,7 +13,7 @@ void writeCode(u32 address, u32 instruction) { ICInvalidateRange(pointer, 4); } -void patchFunction(void *function, char *patchBytes, unsigned int patchBytesSize, int functionOffset) { +void patchFunction(char *function, char *patchBytes, unsigned int patchBytesSize, int functionOffset) { log_print("Patching function...\n"); void *patchAddress = function + functionOffset; log_printf("Patch address: %p\n", patchAddress); diff --git a/src/tcp_gecko.c b/src/tcp_gecko.cpp similarity index 94% rename from src/tcp_gecko.c rename to src/tcp_gecko.cpp index 2280f32..2c196b6 100644 --- a/src/tcp_gecko.c +++ b/src/tcp_gecko.cpp @@ -13,12 +13,12 @@ #include "dynamic_libs/gx2_functions.h" #include "dynamic_libs/fs_functions.h" #include "utils/logger.h" -#include "system/memory.h" #include "system/hardware_breakpoints.h" #include "utils/linked_list.h" -#include "address.h" +#include "system/address.h" #include "system/stack.h" -#include "pause.h" +#include "system/pause.h" +#include "utils/sd_ip_reader.hpp" void *client; void *commandBlock; @@ -55,7 +55,7 @@ struct pygecko_bss_t { #define COMMAND_FOLLOW_POINTER 0x60 #define COMMAND_REMOTE_PROCEDURE_CALL 0x70 #define COMMAND_GET_SYMBOL 0x71 -#define COMMAND_MEMORY_SEARCH 0x72 +#define COMMAND_MEMORY_SEARCH_32 0x72 #define COMMAND_ADVANCED_MEMORY_SEARCH 0x73 #define COMMAND_EXECUTE_ASSEMBLY 0x81 #define COMMAND_PAUSE_CONSOLE 0x82 @@ -111,7 +111,7 @@ int flush // ########## Being socket_functions.h ############ -static int recvwait(struct pygecko_bss_t *bss, int sock, void *buffer, int len) { +static int recvwait(struct pygecko_bss_t *bss, int sock, unsigned char *buffer, int len) { int ret; while (len > 0) { ret = recv(sock, buffer, len, 0); @@ -145,7 +145,7 @@ static int checkbyte(int sock) { return buffer[0]; } -static int sendwait(struct pygecko_bss_t *bss, int sock, const void *buffer, int len) { +static int sendwait(struct pygecko_bss_t *bss, int sock, unsigned char *buffer, int len) { int ret; while (len > 0) { ret = send(sock, buffer, len, 0); @@ -168,10 +168,10 @@ static int sendByte(struct pygecko_bss_t *bss, int sock, unsigned char byte) { void receiveString(struct pygecko_bss_t *bss, int clientfd, - char *stringBuffer, + unsigned char *stringBuffer, int bufferSize) { // Receive the string length - char lengthBuffer[4] = {0}; + unsigned char lengthBuffer[4] = {0}; int ret = recvwait(bss, clientfd, lengthBuffer, 4); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (string length)") int stringLength = ((int *) lengthBuffer)[0]; @@ -228,7 +228,7 @@ void considerInitializingFileSystem() { void reportIllegalCommandByte(int commandByte) { char errorBuffer[ERROR_BUFFER_SIZE]; __os_snprintf(errorBuffer, ERROR_BUFFER_SIZE, - "Illegal command byte received: 0x%02x\nServer Version: %s\nIf you see this, you most likely have to update your TCP Gecko Installer.", + "Illegal command byte received: 0x%02x\nServer Version: %s\nIf you see this,\nplease report this bug.", commandByte, SERVER_VERSION); OSFatal(errorBuffer); } @@ -514,7 +514,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { && (currentAddress < endingAddress)) { int value = *(int *) currentAddress; ((int *) buffer)[currentIntegerIndex++] = value; - char *opCodeBuffer = malloc(bufferSize); + char *opCodeBuffer = (char *) malloc(bufferSize); bool status = DisassemblePPCOpcode((u32 *) currentAddress, opCodeBuffer, (u32) bufferSize, OSGetSymbolName, (u32) disassemblerOptions); @@ -536,7 +536,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } int bytesToSend = currentIntegerIndex * integerSize; - ret = sendwait(bss, clientfd, &bytesToSend, 4); + ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, 4); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Buffer size)") // VALUE(4)|STATUS(4)|LENGTH(4)|DISASSEMBLED(LENGTH) @@ -545,7 +545,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } int bytesToSend = 0; - ret = sendwait(bss, clientfd, &bytesToSend, 4); + ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, 4); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (No more bytes)") break; @@ -656,7 +656,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { u32 image_size = surface.image_size; // Send the image size so that the client knows how much to read - ret = sendwait(bss, clientfd, &image_size, 4); + ret = sendwait(bss, clientfd, (unsigned char *) &image_size, 4); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image size)") unsigned int imageBytesSent = 0; @@ -711,7 +711,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } case COMMAND_READ_FILE: { char file_path[FS_MAX_FULLPATH_SIZE] = {0}; - receiveString(bss, clientfd, file_path, FS_MAX_FULLPATH_SIZE); + receiveString(bss, clientfd, (unsigned char *) file_path, FS_MAX_FULLPATH_SIZE); considerInitializingFileSystem(); @@ -747,7 +747,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { ASSERT_FUNCTION_SUCCEEDED(bytesRead, "FSReadFile") // Send file bytes - ret = sendwait(bss, clientfd, fileBuffer, bytesRead); + ret = sendwait(bss, clientfd, (unsigned char *) fileBuffer, bytesRead); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (file buffer)") totalBytesRead += bytesRead; @@ -768,7 +768,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } case COMMAND_READ_DIRECTORY: { char directory_path[FS_MAX_FULLPATH_SIZE] = {0}; - receiveString(bss, clientfd, directory_path, FS_MAX_FULLPATH_SIZE); + receiveString(bss, clientfd, (unsigned char *) directory_path, FS_MAX_FULLPATH_SIZE); considerInitializingFileSystem(); @@ -793,7 +793,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (data coming)") // Send the struct - ret = sendwait(bss, clientfd, &entry, entrySize); + ret = sendwait(bss, clientfd, (unsigned char *) &entry, entrySize); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (directory entry)") } @@ -819,7 +819,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { // Receive the file path char file_path[FS_MAX_FULLPATH_SIZE] = {0}; - receiveString(bss, clientfd, file_path, FS_MAX_FULLPATH_SIZE); + receiveString(bss, clientfd, (unsigned char *) file_path, FS_MAX_FULLPATH_SIZE); considerInitializingFileSystem(); @@ -843,19 +843,19 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { ASSERT_ALLOCATED(fileBuffer, "File buffer") // Send the maximum file buffer size - ret = sendwait(bss, clientfd, &file_buffer_size, 4); + ret = sendwait(bss, clientfd, (unsigned char *) &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); + ret = recvwait(bss, clientfd, (unsigned char *) &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); + ret = recvwait(bss, clientfd, (unsigned char *) fileBuffer, dataLength); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (File buffer)") // Write the data (and advance file handle position implicitly) @@ -888,7 +888,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } case COMMAND_IOSU_HAX_READ_FILE: { - log_print("COMMAND_IOSUHAX_READ_FILE"); + /*log_print("COMMAND_IOSUHAX_READ_FILE"); // TODO Crashes console on this call int returnValue = IOSUHAX_Open(NULL); @@ -965,7 +965,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { returnValue = IOSUHAX_Close(); log_printf("IOSUHAX_Close: %i", returnValue); - IOSUHAX_OPEN_FAILED: + IOSUHAX_OPEN_FAILED:*/ break; } @@ -1039,7 +1039,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { ASSERT_FUNCTION_SUCCEEDED(ret, "nn_act_Finalize"); // Send it - ret = sendwait(bss, clientfd, &persistentIdentifier, 4); + ret = sendwait(bss, clientfd, (unsigned char *) &persistentIdentifier, 4); ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (persistent identifier)") break; @@ -1113,7 +1113,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { ret = recvwait(bss, clientfd, buffer, 4 + 8 * 4); CHECK_ERROR(ret < 0); - fun = ((void **) buffer)[0]; + fun = (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]; @@ -1139,15 +1139,15 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { CHECK_ERROR(ret < 0) /* Identify the RPL name and symbol name */ - char *rplname = (char *) &((int *) buffer)[2]; - char *symname = (char *) (&buffer[0] + ((int *) buffer)[1]); + char *rplName = (char *) &((int *) buffer)[2]; + char *symbolName = (char *) (&buffer[0] + ((int *) buffer)[1]); /* Get the symbol and store it in the buffer */ unsigned int module_handle, function_address; - OSDynLoad_Acquire(rplname, &module_handle); + OSDynLoad_Acquire(rplName, &module_handle); char data = (char) recvbyte(bss, clientfd); - OSDynLoad_FindExport(module_handle, data, symname, &function_address); + OSDynLoad_FindExport(module_handle, data, symbolName, &function_address); ((int *) buffer)[0] = (int) function_address; ret = sendwait(bss, clientfd, buffer, 4); @@ -1155,7 +1155,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } - case COMMAND_MEMORY_SEARCH: { + case COMMAND_MEMORY_SEARCH_32: { ret = recvwait(bss, clientfd, buffer, sizeof(int) * 3); CHECK_ERROR(ret < 0); int address = ((int *) buffer)[0]; @@ -1178,7 +1178,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { } case COMMAND_ADVANCED_MEMORY_SEARCH: { // Receive the initial data - ret = recvwait(bss, clientfd, buffer, 4 * 6); + ret = recvwait(bss, clientfd, buffer, 6 * sizeof(int)); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (memory search information)") int bufferIndex = 0; int startingAddress = ((int *) buffer)[bufferIndex++]; @@ -1190,7 +1190,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { // Receive the search bytes char searchBytes[searchBytesCount]; - ret = recvwait(bss, clientfd, searchBytes, searchBytesCount); + ret = recvwait(bss, clientfd, (unsigned char *) searchBytes, searchBytesCount); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (memory search bytes)") int iterationIncrement = aligned ? searchBytesCount : 1; @@ -1204,7 +1204,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { int comparisonResult; if (kernelRead) { - comparisonResult = kernelMemoryCompare((void *) currentAddress, searchBytes, searchBytesCount); + comparisonResult = kernelMemoryCompare((char *) currentAddress, searchBytes, searchBytesCount); } else { comparisonResult = memcmp((void *) currentAddress, searchBytes, searchBytesCount); } @@ -1228,20 +1228,8 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } case COMMAND_EXECUTE_ASSEMBLY: { - // Receive the assembly - receiveString(bss, clientfd, (char *) buffer, DATA_BUFFER_SIZE); - - // Write the assembly to an executable code region - int destinationAddress = 0x10000000 - DATA_BUFFER_SIZE; - kernelCopyData((unsigned char *) destinationAddress, buffer, DATA_BUFFER_SIZE); - - // Execute the assembly from there - void (*function)() = (void (*)()) destinationAddress; - function(); - - // Clear the memory contents again - memset((void *) buffer, 0, DATA_BUFFER_SIZE); - kernelCopyData((unsigned char *) destinationAddress, buffer, DATA_BUFFER_SIZE); + receiveString(bss, clientfd, (unsigned char *) buffer, DATA_BUFFER_SIZE); + executeAssembly(buffer, DATA_BUFFER_SIZE); break; } @@ -1408,8 +1396,7 @@ static int runTCPGeckoServer(int argc, void *argv) { setup_os_exceptions(); socket_lib_init(); - - log_init(COMPUTER_IP_ADDRESS); + initializeUDPLog(); while (true) { socketAddress.sin_family = AF_INET; @@ -1460,18 +1447,18 @@ static int runTCPGeckoServer(int argc, void *argv) { } static int startTCPGeckoThread(int argc, void *argv) { - log_init(COMPUTER_IP_ADDRESS); log_print("Starting TCP Gecko thread...\n"); // Run the TCP Gecko Installer server struct pygecko_bss_t *bss; - bss = memalign(0x40, sizeof(struct pygecko_bss_t)); + bss = (struct pygecko_bss_t *) memalign(0x40, sizeof(struct pygecko_bss_t)); if (bss == 0) return 0; memset(bss, 0, sizeof(struct pygecko_bss_t)); - if (OSCreateThread(&bss->thread, runTCPGeckoServer, 1, bss, (u32) bss->stack + sizeof(bss->stack), + if (OSCreateThread(&bss->thread, (s32 (*)(s32, void *)) runTCPGeckoServer, 1, bss, + (u32) bss->stack + sizeof(bss->stack), sizeof(bss->stack), 0, 0xc) == 1) { OSResumeThread(&bss->thread); @@ -1499,7 +1486,6 @@ static int startTCPGeckoThread(int argc, void *argv) { } void startTCPGecko() { - log_init(COMPUTER_IP_ADDRESS); log_print("Starting TCP Gecko...\n"); // Force the debugger to be initialized by default diff --git a/src/assertions.h b/src/utils/assertions.h similarity index 100% rename from src/assertions.h rename to src/utils/assertions.h diff --git a/src/utils/linked_list.c b/src/utils/linked_list.cpp similarity index 100% rename from src/utils/linked_list.c rename to src/utils/linked_list.cpp diff --git a/src/utils/sd_ip_reader.cpp b/src/utils/sd_ip_reader.cpp new file mode 100644 index 0000000..4be8b8d --- /dev/null +++ b/src/utils/sd_ip_reader.cpp @@ -0,0 +1,40 @@ +#include "sd_ip_reader.hpp" + +char ipFromSd[16]; +bool hasReadIP = false; + +void initializeUDPLog() { + if (!hasReadIP) { + log_printf("Reading ip from sd card\n"); + hasReadIP = true; + + std::string ipFilePath = std::string(SD_PATH) + WIIU_PATH + "/" + IP_TXT; + + CFile file(ipFilePath, CFile::ReadOnly); + if (!file.isOpen()) { + log_printf("File %s not found, using hard-coded\n", ipFilePath.c_str()); + log_init(COMPUTER_IP_ADDRESS); + return; + } + + std::string strBuffer; + strBuffer.resize(file.size()); + file.read((u8 *) &strBuffer[0], strBuffer.size()); + + if (strBuffer.length() >= sizeof(ipFromSd)) { + log_printf("Loading ip from sd failed. String was too long: %s\n", strBuffer.c_str()); + return; + } + + memcpy(ipFromSd, strBuffer.c_str(), strBuffer.length()); + ipFromSd[strBuffer.length()] = 0; + + log_printf("Successfully read ip from sd! ip is: %s\n", ipFromSd); + + log_init(ipFromSd); + } + + if (strlen(ipFromSd) > 0) { + log_init(ipFromSd); + } +} \ No newline at end of file diff --git a/src/utils/sd_ip_reader.hpp b/src/utils/sd_ip_reader.hpp new file mode 100644 index 0000000..1f97e38 --- /dev/null +++ b/src/utils/sd_ip_reader.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "logger.h" +#include "../common/common.h" +#include "../fs/CFile.hpp" + +#define IP_TXT "ip.txt" + +void initializeUDPLog(); \ No newline at end of file diff --git a/tcpgecko.elf b/tcpgecko.elf index 07946c6..02b68a0 100644 Binary files a/tcpgecko.elf and b/tcpgecko.elf differ