Implement raw assembly cheat code support
This commit is contained in:
parent
c276347b62
commit
7f629d1d7c
@ -3,7 +3,7 @@
|
|||||||
<app>
|
<app>
|
||||||
<name>TCP Gecko</name>
|
<name>TCP Gecko</name>
|
||||||
<coder>BullyWiiPlaza, wj44, dimok, Chadderz, Marionumber1</coder>
|
<coder>BullyWiiPlaza, wj44, dimok, Chadderz, Marionumber1</coder>
|
||||||
<version>2.4</version>
|
<version>2.5</version>
|
||||||
<short_description>WiiU RAM Hacking</short_description>
|
<short_description>WiiU RAM Hacking</short_description>
|
||||||
<long_description>A memory editor that does magical things to your games. In order to develop and apply real-time
|
<long_description>A memory editor that does magical things to your games. In order to develop and apply real-time
|
||||||
cheats use JGecko U.
|
cheats use JGecko U.
|
||||||
|
40
src/system/raw_assembly_cheats.h
Normal file
40
src/system/raw_assembly_cheats.h
Normal file
@ -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");
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
#include "system/pause.h"
|
#include "system/pause.h"
|
||||||
#include "utils/sd_ip_reader.hpp"
|
#include "utils/sd_ip_reader.hpp"
|
||||||
#include "patcher/function_patcher_gx2.h"
|
#include "patcher/function_patcher_gx2.h"
|
||||||
|
#include "system/raw_assembly_cheats.h"
|
||||||
|
|
||||||
void *client;
|
void *client;
|
||||||
void *commandBlock;
|
void *commandBlock;
|
||||||
@ -74,6 +75,8 @@ struct pygecko_bss_t {
|
|||||||
#define COMMAND_RUN_KERNEL_COPY_SERVICE 0xCD
|
#define COMMAND_RUN_KERNEL_COPY_SERVICE 0xCD
|
||||||
#define COMMAND_IOSU_HAX_READ_FILE 0xD0
|
#define COMMAND_IOSU_HAX_READ_FILE 0xD0
|
||||||
#define COMMAND_GET_VERSION_HASH 0xE0
|
#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 CHECK_ERROR(cond) if (cond) { bss->line = __LINE__; goto error; }
|
||||||
#define errno (*__gh_errno_ptr())
|
#define errno (*__gh_errno_ptr())
|
||||||
@ -84,7 +87,7 @@ struct pygecko_bss_t {
|
|||||||
#define ONLY_ZEROS_READ 0xB0
|
#define ONLY_ZEROS_READ 0xB0
|
||||||
#define NON_ZEROS_READ 0xBD
|
#define NON_ZEROS_READ 0xBD
|
||||||
|
|
||||||
#define VERSION_HASH 0xC9D0452
|
#define VERSION_HASH 0x7FB223
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT
|
ZEXTERN int ZEXPORT
|
||||||
deflateEnd OF((z_streamp
|
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);
|
return sendwait(bss, sock, buffer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void receiveString(struct pygecko_bss_t *bss,
|
unsigned int receiveString(struct pygecko_bss_t *bss,
|
||||||
int clientfd,
|
int clientfd,
|
||||||
unsigned char *stringBuffer,
|
unsigned char *stringBuffer,
|
||||||
int bufferSize) {
|
unsigned int bufferSize) {
|
||||||
// Receive the string length
|
// Receive the string length
|
||||||
unsigned char lengthBuffer[4] = {0};
|
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)")
|
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
|
// Receive the actual string
|
||||||
ret = recvwait(bss, clientfd, stringBuffer, stringLength);
|
ret = recvwait(bss, clientfd, stringBuffer, stringLength);
|
||||||
ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (string)")
|
ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (string)")
|
||||||
} else {
|
} else {
|
||||||
OSFatal("String buffer size exceeded");
|
OSFatal("String buffer size exceeded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stringLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ########## End socket_functions.h ############
|
// ########## End socket_functions.h ############
|
||||||
@ -1389,6 +1394,17 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
|
|||||||
|
|
||||||
break;
|
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: {
|
default: {
|
||||||
reportIllegalCommandByte(ret);
|
reportIllegalCommandByte(ret);
|
||||||
|
|
||||||
@ -1492,6 +1508,10 @@ static int startTCPGeckoThread(int argc, void *argv) {
|
|||||||
usleep(9000);
|
usleep(9000);
|
||||||
// log_print("Running code handler...\n");
|
// log_print("Running code handler...\n");
|
||||||
codeHandlerFunction();
|
codeHandlerFunction();
|
||||||
|
|
||||||
|
if (assemblySize > 0) {
|
||||||
|
executeAssembly();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_print("Code handler not installed...\n");
|
log_print("Code handler not installed...\n");
|
||||||
|
BIN
tcpgecko.elf
BIN
tcpgecko.elf
Binary file not shown.
Loading…
Reference in New Issue
Block a user