-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,53 @@ void PatchSrvAccess() | |
*/ | ||
//----------------------------------------------------------------------------- | ||
|
||
typedef struct regionsStruct | ||
{ | ||
u32 japan:1; | ||
u32 northAmerica:1; | ||
u32 europe:1; | ||
u32 australia:1; | ||
u32 china:1; | ||
u32 korea:1; | ||
u32 taiwan :1; | ||
u32 placeholder :1; | ||
} regions; | ||
|
||
typedef struct nandTypesStruct | ||
{ | ||
u32 System:1; | ||
u32 Emu:1; | ||
u32 placeholder:6; | ||
} nands; | ||
|
||
typedef struct patchStruct | ||
{ | ||
char version; | ||
u32 patchNameSize; | ||
u32 descriptionSize; | ||
u32 processNameSize; | ||
u32 originalcodeSize; | ||
u32 patchcodeSize; | ||
u32 processType; | ||
u32 minKernelVersion; | ||
u32 maxKernelVersion; | ||
regions regionsSupported; | ||
nands nandCompability; | ||
u8 patchType; | ||
u32 startAddressProcess; | ||
u32 startAddressGlobal; | ||
u32 searchAreaSize; | ||
u32 numberOfReplacements; | ||
char binaryData[]; | ||
} patch; | ||
|
||
patch filePatch; | ||
|
||
patch* loadedPatches[256]; | ||
u32 numberOfLoadedPatches; | ||
|
||
patch* tmpPatch; | ||
|
||
int findAndPatchCode( const char* titleId, short titleIdSize, const u32 startAddress, const u32 area, unsigned char originalcode[], const char patchcode[],u32 patchcodeSize) | ||
{ | ||
KCodeSet* code_set = FindTitleCodeSet(titleId,titleIdSize); | ||
|
@@ -155,20 +202,299 @@ int patchRegionFree() | |
return 0; | ||
} | ||
|
||
int findAndPatchCode_test(patch* _patch) | ||
{ | ||
const u32 startAddress=_patch->startAddressProcess; | ||
const u32 area=_patch->searchAreaSize; | ||
|
||
short titleIdSize=_patch->processNameSize; | ||
unsigned int titleIdPosition=_patch->patchNameSize+_patch->descriptionSize; | ||
char titleId[_patch->processNameSize]; | ||
memcpy(titleId,&(_patch->binaryData[titleIdPosition]),_patch->processNameSize); | ||
|
||
unsigned char originalcode[_patch->originalcodeSize]; | ||
unsigned int originalCodePosition=_patch->patchNameSize+_patch->descriptionSize+_patch->processNameSize; | ||
memcpy(originalcode,&(_patch->binaryData[originalCodePosition]),_patch->originalcodeSize); | ||
|
||
u32 patchcodeSize=_patch->patchcodeSize; | ||
char patchcode[patchcodeSize]; | ||
unsigned int patchCodePosition=originalCodePosition+_patch->originalcodeSize; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Hartie95
Author
Owner
|
||
memcpy(patchcode,&(_patch->binaryData[patchCodePosition]),patchcodeSize); | ||
|
||
|
||
KCodeSet* code_set = FindTitleCodeSet(titleId,titleIdSize); | ||
if (code_set == nullptr) | ||
return 1; | ||
|
||
unsigned char * startAddressPointer = (unsigned char*)FindCodeOffsetKAddr(code_set, startAddress); | ||
unsigned char * destination=nullptr; | ||
for(unsigned int i = 0; i < area && destination==nullptr; i+=4) | ||
{ | ||
//check for the original code position | ||
if( (*((unsigned int*)(startAddressPointer + i + 0x0)) == *((unsigned int*)&originalcode[0x0])) && | ||
(*((unsigned int*)(startAddressPointer + i + 0x4)) == *((unsigned int*)&originalcode[0x4])) && | ||
(*((unsigned int*)(startAddressPointer + i + 0x8)) == *((unsigned int*)&originalcode[0x8])) && | ||
(*((unsigned int*)(startAddressPointer + i + 0xC)) == *((unsigned int*)&originalcode[0xC]))) | ||
{ | ||
destination = startAddressPointer + i; | ||
} | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
Syphurith
|
||
|
||
//Apply patches, if the address was found | ||
if(destination!=nullptr) | ||
memcpy(destination, patchcode, patchcodeSize); | ||
/*else | ||
return 2; | ||
*/ | ||
return 0; | ||
} | ||
|
||
int patchMenu() | ||
{ | ||
/*static patch menuPatch= | ||
// patch Homemenu to show out of region applications | ||
// 9.0.0 Address: 0x00101B8C; | ||
{ | ||
0x00 ,//short version; | ||
17 ,//short patchNameSize; | ||
49 ,//short descriptionSize; | ||
4 ,//short processNameSize | ||
16 ,//short originalcodeSize; | ||
8 ,//short patchcodeSize; | ||
0x01 ,//short processType; | ||
0x00 ,//u32 minKernelVersion; | ||
0xffffffff ,//u32 maxKernelVersion; | ||
{1,1,1,1,1,1,1,1},//regions regionssupported; | ||
0x00 ,//short nandCompability; | ||
0x00 ,//short patchType; | ||
0x00100000 ,//u32 startAddressProcess; | ||
0x26A00000 ,//u32 startAddressGlobal; | ||
0x00100000 ,//u32 searchAreaSize; | ||
0x01 ,//u32 numberOfReplacements | ||
// /*patchName*/ //"region patch menu" | ||
// /*description*/ "Patches the home menu to show out of region games" | ||
// /*processname*/ "menu" | ||
// /*OriginalCode*/ "\x00\x00\x55\xE3\x01\x10\xA0\xE3\x11\x00\xA0\xE1\x03\x00\x00\x0A" | ||
// /*patchBegin*/ "\x01\x00\xA0\xE3\x70\x80\xBD\xE8" | ||
|
||
// BYTE binaryData[]; | ||
//}; | ||
|
||
|
||
// memcpy(menuPatch.binaryData,binary,sizeof(binary)); | ||
// Set generell informations for patching | ||
static const char * titleId = "menu"; | ||
/* static const char * titleId = "menu"; | ||
static const u32 startAddress = 0x00100000; | ||
// patch Homemenu to show out of region applications | ||
// 9.0.0 Address: 0x00101B8C; | ||
static unsigned char originalcode[] = { 0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0, 0xE3, 0x11, 0x00, 0xA0, 0xE1, 0x03, 0x00, 0x00, 0x0A }; | ||
static char patchcode[] = { 0x01, 0x00, 0xA0, 0xE3, 0x70, 0x80, 0xBD, 0xE8 }; | ||
findAndPatchCode(titleId, 4, startAddress, 0x00100000, originalcode, patchcode, sizeof(patchcode)); | ||
findAndPatchCode(titleId, 4, startAddress, 0x00100000, originalcode, patchcode, sizeof(patchcode));*/ | ||
/* const u32 startAddress=_patch->startAddressProcess; | ||
const u32 area=_patch->searchAreaSize; | ||
short titleIdSize=_patch->patchNameSize; | ||
unsigned int titleIdPosition=_patch->patchNameSize+_patch->descriptionSize; | ||
unsigned int originalCodePosition=_patch->patchNameSize+_patch->descriptionSize+_patch->processNameSize; | ||
u32 patchcodeSize=_patch->patchcodeSize; | ||
unsigned int patchCodePosition=originalCodePosition+_patch->originalcodeSize; | ||
*/ | ||
//findAndPatchCode(&_patch->binaryData[titleIdPosition], 4, _patch->startAddressProcess, 0x00100000, &_patch->binaryData[originalCodePosition], &_patch->binaryData[patchCodePosition], _patch->patchcodeSize); | ||
for(u32 i = 0; i<numberOfLoadedPatches;i++) | ||
{ | ||
findAndPatchCode_test(loadedPatches[i]); | ||
} | ||
return 0; | ||
} | ||
#include <ctrcommon/gpu.hpp> | ||
#include <ctrcommon/fs.hpp> | ||
|
||
#include <sys/dirent.h> | ||
#include <sys/stat.h> | ||
using namespace std; | ||
|
||
static const string patchesFolder="sdmc:/fmp/patches/"; | ||
static const string patchExtension=".patch"; | ||
|
||
void createDefaultPatches() | ||
{ | ||
// check if the patches Folder exists | ||
if(!fsExists(patchesFolder)) | ||
mkdir(patchesFolder.c_str(), 0777); | ||
|
||
// create the default patch files | ||
// patch Homemenu to show out of region applications | ||
// 9.0.0 Address: 0x00101B8C; | ||
char menuBytes[]=/*patchName*/ "region patch menu" | ||
/*description*/ "Patches the home menu to show out of region games" | ||
/*processname*/ "menu" | ||
/*OriginalCode*/ "\x00\x00\x55\xE3\x01\x10\xA0\xE3\x11\x00\xA0\xE1\x03\x00\x00\x0A" | ||
/*patchBegin*/ "\x01\x00\xA0\xE3\x70\x80\xBD\xE8"; | ||
|
||
static patch* menuPatch=(patch*)malloc(sizeof(patch)+sizeof(menuBytes)); | ||
|
||
menuPatch->version = 0x00; | ||
menuPatch->patchNameSize = 17; | ||
menuPatch->descriptionSize = 49; | ||
menuPatch->processNameSize = 4; | ||
menuPatch->originalcodeSize = 16; | ||
menuPatch->patchcodeSize = 8; | ||
menuPatch->processType = 0x01; | ||
menuPatch->minKernelVersion = 0x0; | ||
menuPatch->maxKernelVersion = 0x0; | ||
menuPatch->regionsSupported = {1,1,1,1,1,1,1,0}; | ||
menuPatch->nandCompability = {1,1,0}; | ||
menuPatch->patchType = 0x00; | ||
menuPatch->startAddressProcess = 0x00100000; | ||
menuPatch->startAddressGlobal = 0x26A00000; | ||
menuPatch->searchAreaSize = 0x00100000; | ||
menuPatch->numberOfReplacements = 0x01; | ||
|
||
memcpy(menuPatch->binaryData, menuBytes, sizeof(menuBytes)); | ||
|
||
string menuPatchFileName="menu"+patchExtension; | ||
|
||
string filepath=patchesFolder+menuPatchFileName; | ||
FILE *file = fopen(filepath.c_str(),"w"); | ||
if (file == NULL) | ||
{ | ||
file = fopen(filepath.c_str(),"c"); | ||
} | ||
fwrite(menuPatch,1,(sizeof(patch)+sizeof(menuBytes)),file); | ||
fclose(file); | ||
|
||
|
||
|
||
// Patch nim to stop automatic update download(could be unstable) | ||
// 9.0.0 Address: 0x0000EA00 | ||
char nimBytes[]=/*patchName*/ "e-shop spoof" | ||
/*description*/ "Patches nim for E-Shop access" | ||
/*processname*/ "nim" | ||
/*OriginalCode*/ "\x25\x79\x0B\x99\x00\x24\x00\x2D\x29\xD0\x16\x4D\x2D\x68\x01\x91" | ||
/*patchBegin*/ "\xE3\xA0\x00\x00"; | ||
|
||
static patch* nimPatch=(patch*)malloc(sizeof(patch)+sizeof(nimBytes)); | ||
|
||
nimPatch->version = 0x00; | ||
nimPatch->patchNameSize = 12; | ||
nimPatch->descriptionSize = 29; | ||
nimPatch->processNameSize = 3; | ||
nimPatch->originalcodeSize = 16; | ||
nimPatch->patchcodeSize = 2; | ||
nimPatch->processType = 0x01; | ||
nimPatch->minKernelVersion = 0x0; | ||
nimPatch->maxKernelVersion = 0xFFFFFFFF; | ||
nimPatch->regionsSupported = {1,1,1,1,1,1,1,0}; | ||
nimPatch->nandCompability = {1,1,0}; | ||
nimPatch->patchType = 0x00; | ||
nimPatch->startAddressProcess = 0x00001000; | ||
nimPatch->startAddressGlobal = 0x26A00000; | ||
nimPatch->searchAreaSize = 0x00100000; | ||
nimPatch->numberOfReplacements = 0x01; | ||
|
||
memcpy(nimPatch->binaryData, nimBytes, sizeof(nimBytes)); | ||
|
||
string nimPatchFileName="nim"+patchExtension; | ||
|
||
filepath=patchesFolder+nimPatchFileName; | ||
file = fopen(filepath.c_str(),"w"); | ||
if (file == NULL) | ||
{ | ||
file = fopen(filepath.c_str(),"c"); | ||
} | ||
fwrite(nimPatch,1,(sizeof(patch)+sizeof(nimBytes)),file); | ||
fclose(file); | ||
} | ||
|
||
bool isPatch(struct dirent* file) | ||
{ | ||
u32 nameLength=strlen(file->d_name); | ||
if (nameLength >= patchExtension.size() && strcmp(file->d_name + nameLength - patchExtension.size(), patchExtension.c_str()) == 0) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
int getNumberOfPatchFiles(DIR* dir) | ||
{ | ||
u32 numberOfFiles=0; | ||
struct dirent *currenElement; | ||
while ((currenElement = readdir(dir)) != NULL) | ||
{ | ||
if(isPatch(currenElement)) | ||
numberOfFiles++; | ||
} | ||
seekdir(dir,SEEK_SET); | ||
return numberOfFiles; | ||
} | ||
|
||
patch* loadPatch(FILE* file) | ||
{ | ||
patch* loadedPatch=nullptr; | ||
if(file != NULL) | ||
{ | ||
fseek(file, 0L, SEEK_END); | ||
u32 fileSize = ftell(file); | ||
fseek(file, 0L, SEEK_SET); | ||
|
||
loadedPatch=(patch*)malloc(fileSize); | ||
if(loadedPatch!=nullptr) | ||
{ | ||
fread(loadedPatch,1,fileSize,file); | ||
} | ||
fclose(file); | ||
} | ||
return loadedPatch; | ||
} | ||
|
||
void test() | ||
{ | ||
createDefaultPatches(); | ||
|
||
DIR *dir; | ||
dir = opendir(patchesFolder.c_str()); | ||
if (dir) | ||
{ | ||
u32 numberOfPatchFiles=getNumberOfPatchFiles(dir); | ||
FILE* patchFiles[numberOfPatchFiles]; | ||
|
||
closedir(dir); | ||
dir = opendir(patchesFolder.c_str()); | ||
numberOfLoadedPatches=0; | ||
struct dirent *currenElement; | ||
while ((currenElement = readdir(dir)) != NULL) | ||
{ | ||
if(isPatch(currenElement)) | ||
{ | ||
string filepath=patchesFolder+currenElement->d_name; | ||
FILE* file = fopen(filepath.c_str(),"rb"); | ||
patch* tmp=loadPatch(file); | ||
if(tmp!=nullptr) | ||
{ | ||
loadedPatches[numberOfLoadedPatches]=tmp; | ||
numberOfLoadedPatches++; | ||
} | ||
} | ||
} | ||
//numberOfLoadedPatches=1; | ||
//tmpPatch=loadPatch(file); | ||
//loadedPatches=(patch**)malloc(sizeof(patch*)*numberOfPatchFiles); | ||
|
||
/*for(u32 i=0;i<numberOfPatchFiles;i++) | ||
{ | ||
patch* tmp=loadPatch(patchFiles[i]); | ||
if(tmp!=nullptr) | ||
tmpPatch=tmp; | ||
}*/ | ||
} | ||
closedir(dir); | ||
} | ||
|
||
int patchNs() | ||
{ | ||
|
3 comments
on commit 3ea4790
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good this is not too hacky as what i expected.. If i do understand in a wrong way, could you please tell me where you are feeling uneasy for this commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementing is not finished, and the test function loads the patches :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you mean findAndPatchCode_test
i don't find much problems.
And for the layout.. Oh it could be improved to make loading patches easier.
Just load it sequently, you don't really need to use the structure while loading (not while writing of course).
Eh if you do really like OO a lot, you could ignore such things..
Hi @hartmannaf would you please replace all
unsigned int
tou32
to make it a little shorter? alsounsigned char
tou8
. Cause you have those definitions already?