diff --git a/meta/meta.xml b/meta/meta.xml index ad8ce39..23a6b12 100644 --- a/meta/meta.xml +++ b/meta/meta.xml @@ -3,7 +3,7 @@ TCP Gecko BullyWiiPlaza, wj44, dimok, Chadderz, Marionumber1 - 2.4 + 2.5 WiiU RAM Hacking A memory editor that does magical things to your games. In order to develop and apply real-time cheats use JGecko U. diff --git a/src/system/raw_assembly_cheats.h b/src/system/raw_assembly_cheats.h new file mode 100644 index 0000000..b991df2 --- /dev/null +++ b/src/system/raw_assembly_cheats.h @@ -0,0 +1,40 @@ +#pragma once + +#include "kernel.h" + +#define ENDING_ADDRESS 0x10000000 +unsigned int assemblySize = 0; + +unsigned int getStartAddress() { + return ENDING_ADDRESS - assemblySize; +} + +void persistAssembly(unsigned char buffer[], unsigned int size) { + assemblySize = size; + + // Write the assembly to an executable code region + unsigned int startAddress = getStartAddress(); + kernelCopyData((unsigned char *) startAddress, buffer, assemblySize); +} + +void executeAssembly() { + int startAddress = getStartAddress(); + log_printf("[Execute assembly] Start address: %i\n", startAddress); + void (*function)() = (void (*)()) startAddress; + function(); + log_print("[Execute assembly] Executed!\n"); +} + +void clearAssembly() { + log_printf("[Clear assembly] Assembly size: %i\n", assemblySize); + unsigned char buffer[assemblySize]; + log_print("[Clear assembly] Buffer allocated\n"); + memset((void *) buffer, 0, assemblySize); + log_print("[Clear assembly] Memory set\n"); + int startAddress = getStartAddress(); + log_printf("[Clear assembly] Start address: %i\n", startAddress); + kernelCopyData((unsigned char *) startAddress, buffer, assemblySize); + log_print("[Clear assembly] Kernel copy done\n"); + assemblySize = 0; + log_print("[Clear assembly] Assembly size 0\n"); +} \ No newline at end of file diff --git a/src/tcp_gecko.cpp b/src/tcp_gecko.cpp index 301ddd3..21db4cd 100644 --- a/src/tcp_gecko.cpp +++ b/src/tcp_gecko.cpp @@ -20,6 +20,7 @@ #include "system/pause.h" #include "utils/sd_ip_reader.hpp" #include "patcher/function_patcher_gx2.h" +#include "system/raw_assembly_cheats.h" void *client; void *commandBlock; @@ -74,6 +75,8 @@ struct pygecko_bss_t { #define COMMAND_RUN_KERNEL_COPY_SERVICE 0xCD #define COMMAND_IOSU_HAX_READ_FILE 0xD0 #define COMMAND_GET_VERSION_HASH 0xE0 +#define COMMAND_PERSIST_ASSEMBLY 0xE1 +#define COMMAND_CLEAR_ASSEMBLY 0xE2 #define CHECK_ERROR(cond) if (cond) { bss->line = __LINE__; goto error; } #define errno (*__gh_errno_ptr()) @@ -84,7 +87,7 @@ struct pygecko_bss_t { #define ONLY_ZEROS_READ 0xB0 #define NON_ZEROS_READ 0xBD -#define VERSION_HASH 0xC9D0452 +#define VERSION_HASH 0x7FB223 ZEXTERN int ZEXPORT deflateEnd OF((z_streamp @@ -157,23 +160,25 @@ static int sendByte(struct pygecko_bss_t *bss, int sock, unsigned char byte) { return sendwait(bss, sock, buffer, 1); } -void receiveString(struct pygecko_bss_t *bss, - int clientfd, - unsigned char *stringBuffer, - int bufferSize) { +unsigned int receiveString(struct pygecko_bss_t *bss, + int clientfd, + unsigned char *stringBuffer, + unsigned int bufferSize) { // Receive the string length unsigned char lengthBuffer[4] = {0}; - int ret = recvwait(bss, clientfd, lengthBuffer, 4); + int ret = recvwait(bss, clientfd, lengthBuffer, sizeof(int)); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (string length)") - int stringLength = ((int *) lengthBuffer)[0]; + unsigned int stringLength = ((unsigned int *) lengthBuffer)[0]; - if (stringLength >= 0 && stringLength <= bufferSize) { + if (stringLength <= bufferSize) { // Receive the actual string ret = recvwait(bss, clientfd, stringBuffer, stringLength); ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (string)") } else { OSFatal("String buffer size exceeded"); } + + return stringLength; } // ########## End socket_functions.h ############ @@ -1389,6 +1394,17 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) { break; } + case COMMAND_PERSIST_ASSEMBLY: { + unsigned int length = receiveString(bss, clientfd, (unsigned char *) buffer, DATA_BUFFER_SIZE); + persistAssembly(buffer, length); + + break; + } + case COMMAND_CLEAR_ASSEMBLY: { + clearAssembly(); + + break; + } default: { reportIllegalCommandByte(ret); @@ -1492,6 +1508,10 @@ static int startTCPGeckoThread(int argc, void *argv) { usleep(9000); // log_print("Running code handler...\n"); codeHandlerFunction(); + + if (assemblySize > 0) { + executeAssembly(); + } } } else { log_print("Code handler not installed...\n"); diff --git a/tcpgecko.elf b/tcpgecko.elf index 703d973..a48a1f4 100644 Binary files a/tcpgecko.elf and b/tcpgecko.elf differ