Increase code list size limit

This commit is contained in:
BullyWiiPlaza 2017-07-09 12:04:27 +02:00
parent 0d42c264e2
commit 767bc71cb5
5 changed files with 121 additions and 47 deletions

View File

@ -103,7 +103,7 @@ static const unsigned char codeHandler[] = {
0x3C, 0xC0, 0x01, 0x13, 0x3C, 0xC0, 0x01, 0x13,
0x60, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00,
0x3C, 0xE0, 0x01, 0x13, 0x3C, 0xE0, 0x01, 0x13,
0x60, 0xE7, 0x43, 0x00, 0x60, 0xE7, 0xD6, 0x00,
0x7C, 0x06, 0x38, 0x00, 0x7C, 0x06, 0x38, 0x00,
0x40, 0x80, 0x01, 0xEC, 0x40, 0x80, 0x01, 0xEC,
0x80, 0x46, 0x00, 0x00, 0x80, 0x46, 0x00, 0x00,

View File

@ -19,14 +19,48 @@
#include <gd.h> // image library #include <gd.h> // image library
#include "../utils/function_patcher.h" #include "../utils/function_patcher.h"
#include "../utils/logger.h" #include "../utils/logger.h"
#include "texture.h" #include "function_patcher_gx2.h"
#include <gd.h> #include <gd.h>
#include <string.h> // memcpy()
static volatile int executionCounter = 0; static volatile int executionCounter = 0;
declareFunctionHook(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, s32 scan_target) { bool shouldTakeScreenShot = false;
unsigned int remainingImageSize = 0;
unsigned int totalImageSize = 0;
int bufferedImageSize = 0;
void *bufferedImageData = NULL;
declareFunctionHook(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, s32
scan_target) {
if (executionCounter > 120) { if (executionCounter > 120) {
GX2Surface surface = colorBuffer->surface; GX2Surface surface = colorBuffer->surface;
log_printf("GX2CopyColorBufferToScanBuffer {surface width:%d, height:%d, image size:%d, image data:%x}\n",
surface.width, surface.height, surface.image_size, surface.image_data);
if (shouldTakeScreenShot) {
void *imageData = surface.image_data;
totalImageSize = surface.image_size;
remainingImageSize = totalImageSize;
int bufferSize = IMAGE_BUFFER_SIZE;
while (remainingImageSize > 0) {
bufferedImageData = malloc(bufferSize);
u32 imageSizeRead = totalImageSize - remainingImageSize;
memcpy(bufferedImageData, imageData + imageSizeRead, bufferSize);
bufferedImageSize = bufferSize;
// Wait while the data is not read yet
while (bufferedImageSize > 0) {
usleep(WAITING_TIME_MILLISECONDS);
}
free(bufferedImageData);
remainingImageSize -= bufferSize;
}
shouldTakeScreenShot = false;
}
/*s32 format = surface.format; /*s32 format = surface.format;
gdImagePtr gdImagePtr = 0; gdImagePtr gdImagePtr = 0;
@ -52,8 +86,6 @@ declareFunctionHook(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *
jpeg.img_id = 0; jpeg.img_id = 0;
}*/ }*/
log_printf("GX2CopyColorBufferToScanBuffer {surface width:%d, height:%d, image size:%d, image data:%x}\n", surface.width, surface.height, surface.image_size, surface.image_data);
executionCounter = 0; executionCounter = 0;
} }

View File

@ -23,8 +23,31 @@ extern "C" {
#include "../utils/function_patcher.h" #include "../utils/function_patcher.h"
// The dynamically allocated buffer size for the image copy
#define IMAGE_BUFFER_SIZE 100
// The time the producer and consumer wait while there is nothing to do
#define WAITING_TIME_MILLISECONDS 1
// Flag for telling the hook whether to dump a screen shot
extern bool shouldTakeScreenShot;
// Indication for the consumer how many bytes are there to read in total
extern unsigned int totalImageSize;
// Indication for the consumer how many bytes are left to read
extern unsigned int remainingImageSize;
// Indication for the consumer how many bytes can be read from the buffer at once
extern int bufferedImageSize;
// The actual image data buffer for the consumer to consume
extern void *bufferedImageData;
extern FunctionHook method_hooks_gx2[]; extern FunctionHook method_hooks_gx2[];
extern u32 method_hooks_size_gx2; extern u32 method_hooks_size_gx2;
extern volatile unsigned int method_calls_gx2[]; extern volatile unsigned int method_calls_gx2[];
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -19,6 +19,7 @@
#include "system/stack.h" #include "system/stack.h"
#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"
void *client; void *client;
void *commandBlock; void *commandBlock;
@ -99,16 +100,6 @@ strm,
int flush int flush
)); ));
// ########## Being kernel_copy.h ############
// ########## End kernel_copy.h ############
// ########## Begin pause.h ############
// ########## End pause.h ############
// ########## Being socket_functions.h ############ // ########## Being socket_functions.h ############
static int recvwait(struct pygecko_bss_t *bss, int sock, unsigned char *buffer, int len) { static int recvwait(struct pygecko_bss_t *bss, int sock, unsigned char *buffer, int len) {
@ -251,18 +242,17 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
switch (ret) { switch (ret) {
case COMMAND_WRITE_8: { case COMMAND_WRITE_8: {
char *destinationAddress; ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
ret = recvwait(bss, clientfd, buffer, 8);
CHECK_ERROR(ret < 0); CHECK_ERROR(ret < 0);
destinationAddress = ((char **) buffer)[0]; char *destinationAddress = ((char **) buffer)[0];
*destinationAddress = buffer[7]; *destinationAddress = buffer[7];
DCFlushRange(destinationAddress, 1); DCFlushRange(destinationAddress, 1);
break; break;
} }
case COMMAND_WRITE_16: { case COMMAND_WRITE_16: {
short *destinationAddress; short *destinationAddress;
ret = recvwait(bss, clientfd, buffer, 8); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
destinationAddress = ((short **) buffer)[0]; destinationAddress = ((short **) buffer)[0];
@ -272,18 +262,18 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
} }
case COMMAND_WRITE_32: { case COMMAND_WRITE_32: {
int destinationAddress, value; int destinationAddress, value;
ret = recvwait(bss, clientfd, buffer, 8); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
destinationAddress = ((int *) buffer)[0]; destinationAddress = ((int *) buffer)[0];
value = ((int *) buffer)[1]; value = ((int *) buffer)[1];
kernelCopyData((unsigned char *) destinationAddress, (unsigned char *) &value, 4); kernelCopyData((unsigned char *) destinationAddress, (unsigned char *) &value, sizeof(int));
break; break;
} }
case COMMAND_READ_MEMORY: { case COMMAND_READ_MEMORY: {
const unsigned char *startingAddress, *endingAddress; const unsigned char *startingAddress, *endingAddress;
ret = recvwait(bss, clientfd, buffer, 2 * 4); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
startingAddress = ((const unsigned char **) buffer)[0]; startingAddress = ((const unsigned char **) buffer)[0];
endingAddress = ((const unsigned char **) buffer)[1]; endingAddress = ((const unsigned char **) buffer)[1];
@ -456,7 +446,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
break;*/ break;*/
} }
case COMMAND_VALIDATE_ADDRESS_RANGE: { case COMMAND_VALIDATE_ADDRESS_RANGE: {
ret = recvwait(bss, clientfd, buffer, 8); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
// Retrieve the data // Retrieve the data
@ -496,7 +486,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
}*/ }*/
case COMMAND_MEMORY_DISASSEMBLE: { case COMMAND_MEMORY_DISASSEMBLE: {
// Receive the starting address, ending address and disassembler options // Receive the starting address, ending address and disassembler options
ret = recvwait(bss, clientfd, buffer, 4 + 4 + 4); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 3);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
int startingAddress = ((int *) buffer)[0]; int startingAddress = ((int *) buffer)[0];
int endingAddress = ((int *) buffer)[1]; int endingAddress = ((int *) buffer)[1];
@ -536,7 +526,7 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
} }
int bytesToSend = currentIntegerIndex * integerSize; int bytesToSend = currentIntegerIndex * integerSize;
ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, 4); ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, sizeof(int));
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Buffer size)") ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (Buffer size)")
// VALUE(4)|STATUS(4)|LENGTH(4)|DISASSEMBLED(LENGTH) // VALUE(4)|STATUS(4)|LENGTH(4)|DISASSEMBLED(LENGTH)
@ -545,14 +535,14 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
} }
int bytesToSend = 0; int bytesToSend = 0;
ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, 4); ret = sendwait(bss, clientfd, (unsigned char *) &bytesToSend, sizeof(int));
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (No more bytes)") ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (No more bytes)")
break; break;
} }
case COMMAND_READ_MEMORY_COMPRESSED: { case COMMAND_READ_MEMORY_COMPRESSED: {
// Receive the starting address and length // Receive the starting address and length
ret = recvwait(bss, clientfd, buffer, 4 + 4); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
int startingAddress = ((int *) buffer)[0]; int startingAddress = ((int *) buffer)[0];
unsigned int inputLength = ((unsigned int *) buffer)[1]; unsigned int inputLength = ((unsigned int *) buffer)[1];
@ -625,38 +615,67 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
break;*/ break;*/
} }
case COMMAND_KERNEL_WRITE: { case COMMAND_KERNEL_WRITE: {
void *ptr, *value;
ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
ptr = ((void **) buffer)[0]; void *address = ((void **) buffer)[0];
value = ((void **) buffer)[1]; void *value = ((void **) buffer)[1];
writeKernelMemory(ptr, (uint32_t) value); writeKernelMemory(address, (uint32_t) value);
break; break;
} }
case COMMAND_KERNEL_READ: { case COMMAND_KERNEL_READ: {
void *ptr, *value;
ret = recvwait(bss, clientfd, buffer, sizeof(int)); ret = recvwait(bss, clientfd, buffer, sizeof(int));
CHECK_ERROR(ret < 0); CHECK_ERROR(ret < 0)
ptr = ((void **) buffer)[0]; void *address = ((void **) buffer)[0];
void *value = (void *) readKernelMemory(address);
value = (void *) readKernelMemory(ptr);
*(void **) buffer = value; *(void **) buffer = value;
sendwait(bss, clientfd, buffer, sizeof(int)); sendwait(bss, clientfd, buffer, sizeof(int));
break; break;
} }
case COMMAND_TAKE_SCREEN_SHOT: { case COMMAND_TAKE_SCREEN_SHOT: {
GX2ColorBuffer colorBuffer; // Tell the hook to dump the screen shot now
shouldTakeScreenShot = true;
// Tell the client the size of the upcoming image
ret = sendwait(bss, clientfd, (unsigned char *) &totalImageSize, sizeof(int));
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (total image size)")
// Keep sending the image data
while (remainingImageSize > 0) {
int bufferPosition = 0;
// Fill the buffer till it is full
while (bufferPosition <= DATA_BUFFER_SIZE) {
// Wait for data to be available
while (bufferedImageSize == 0) {
usleep(WAITING_TIME_MILLISECONDS);
}
memcpy(buffer + bufferPosition, bufferedImageData, bufferedImageSize);
bufferPosition += bufferedImageSize;
bufferedImageSize = 0;
}
// Send the size of the current chunk
ret = sendwait(bss, clientfd, (unsigned char *) &bufferPosition, sizeof(int));
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image data chunk size)")
// Send the image data itself
ret = sendwait(bss, clientfd, buffer, bufferPosition);
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image data)")
}
/*GX2ColorBuffer colorBuffer;
// TODO Initialize colorBuffer! // TODO Initialize colorBuffer!
GX2Surface surface = colorBuffer.surface; GX2Surface surface = colorBuffer.surface;
void *image_data = surface.image_data; void *image_data = surface.image_data;
u32 image_size = surface.image_size; u32 image_size = surface.image_size;
// Send the image size so that the client knows how much to read // Send the image size so that the client knows how much to read
ret = sendwait(bss, clientfd, (unsigned char *) &image_size, 4); ret = sendwait(bss, clientfd, (unsigned char *) &image_size, sizeof(int));
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image size)") ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image size)")
unsigned int imageBytesSent = 0; unsigned int imageBytesSent = 0;
@ -674,37 +693,37 @@ static int processCommands(struct pygecko_bss_t *bss, int clientfd) {
ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image bytes)") ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (image bytes)")
imageBytesSent += length; imageBytesSent += length;
} }*/
break; break;
} }
case COMMAND_UPLOAD_MEMORY: { case COMMAND_UPLOAD_MEMORY: {
// Receive the starting and ending addresses // Receive the starting and ending addresses
ret = recvwait(bss, clientfd, buffer, 8); ret = recvwait(bss, clientfd, buffer, sizeof(int) * 2);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
unsigned char *current_address = ((unsigned char **) buffer)[0]; unsigned char *currentAddress = ((unsigned char **) buffer)[0];
unsigned char *end_address = ((unsigned char **) buffer)[1]; unsigned char *endAddress = ((unsigned char **) buffer)[1];
while (current_address != end_address) { while (currentAddress != endAddress) {
int length; int length;
length = (int) (end_address - current_address); length = (int) (endAddress - currentAddress);
if (length > DATA_BUFFER_SIZE) { if (length > DATA_BUFFER_SIZE) {
length = DATA_BUFFER_SIZE; length = DATA_BUFFER_SIZE;
} }
ret = recvwait(bss, clientfd, buffer, length); ret = recvwait(bss, clientfd, buffer, length);
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
kernelCopyData(current_address, buffer, (unsigned int) length); kernelCopyData(currentAddress, buffer, (unsigned int) length);
current_address += length; currentAddress += length;
} }
break; break;
} }
case COMMAND_GET_DATA_BUFFER_SIZE: { case COMMAND_GET_DATA_BUFFER_SIZE: {
((int *) buffer)[0] = DATA_BUFFER_SIZE; ((int *) buffer)[0] = DATA_BUFFER_SIZE;
ret = sendwait(bss, clientfd, buffer, 4); ret = sendwait(bss, clientfd, buffer, sizeof(int));
CHECK_ERROR(ret < 0) CHECK_ERROR(ret < 0)
break; break;

Binary file not shown.