Increase code list size limit
This commit is contained in:
parent
0d42c264e2
commit
767bc71cb5
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
BIN
tcpgecko.elf
BIN
tcpgecko.elf
Binary file not shown.
Loading…
Reference in New Issue
Block a user