Code: Select all
jr ra
syscall
is there a way to get the game key then? if i reverse a little and see how a0 (saveDataParams) is set how would i know which register has the game key and whats the possible lenghts of the game key
Code: Select all
jr ra
syscall

Code: Select all
typedef struct SceUtilitySavedataParam660
{
SceUtilityParamBase base;
int type;
unsigned int bind;
unsigned int overWriteMode;
char titleId[SCE_UTILITY_SD_TITLEID_SIZE];
char reserved[3];
char userId[SCE_UTILITY_SD_USERID_SIZE];
char (* pUserIds)[SCE_UTILITY_SD_USERID_SIZE];
char fileName[SCE_UTILITY_SD_FILENAME_SIZE];
char reserved1[3];
void * pDataBuf;
unsigned int dataBufSize;
unsigned int dataFileSize;
SceUtilitySDSystemFileParam systemFile;
SceUtilitySDExtFile icon0;
SceUtilitySDExtFile icon1;
SceUtilitySDExtFile pic1;
SceUtilitySDExtFile snd0;
SceUtilitySavedataListSaveNewData * pNewData;
unsigned int initFocus;
int abortedStatus;
SceUtilitySavedataMsFreeSize * pMs;
SceUtilitySavedataMsDataSize * pMsData;
SceUtilitySavedataUtilityDataSize * pUtilityData;
unsigned char secureFileId[SCE_UTILITY_SD_SECUREFILEID_SIZE];
unsigned int dataVersion;
unsigned int mcStatus;
SceUtilitySavedataUserIdList * pUserIdList;
SceUtilitySavedataFileList * pFileList;
SceUtilitySavedataCheckSize * pCheckSize;
} SceUtilitySavedataParam660;Code: Select all
u32 code[2];
u32 UtilitySavedataInitStart_pointer;
void (* _sceKernelDcacheWritebackAll)(void);
SceUID (* _sceIoOpen)(const char *, int, SceMode);
int (* _sceIoWrite)(SceUID, const void *, SceSize);
int (* _sceIoClose)(SceUID);
#define MAKE_JUMP(f) (0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF))
int ValidUserAddress(void *addr, int mode)
{
if (mode)
return ((u32)addr >= 0x08400000 && (u32)addr < 0x08800000);
return ((u32)addr >= 0x08800000 && (u32)addr < 0x0A000000);
}
//mode = 0 for search range 0x08800000 to 0x0A000000
//mode = 1 for search range 0x08400000 to 0x08800000
u32 FindImport(char *libname, u32 nid, int mode)
{
u32 lower = 0x08400000;
u32 higher = 0x08800000;
if (!mode) {
lower = 0x08800000;
higher = 0x0A000000;
}
u32 i;
for (i = lower; i < higher; i += 4) {
SceLibraryStubTable *stub = (SceLibraryStubTable *)i;
if ((stub->libname != libname) && ValidUserAddress((void *)stub->libname, mode) \
&& ValidUserAddress(stub->nidtable, mode) && ValidUserAddress(stub->stubtable, mode)) {
if (strcmp(libname, stub->libname) == 0) {
u32 *table = stub->nidtable;
int j;
for (j = 0; j < stub->stubcount; j++) {
if (table[j] == nid) {
return ((u32)stub->stubtable + (j * 8));
}
}
}
}
}
return 0;
}
int (* sceUtilitySavedataInitStart_)(SceUtilitySavedataParam *param);
int sceUtilitySavedataInitStart_hook(SceUtilitySavedataParam *param)
{
u32 size = param->base.size;
u8 *key = (u8 *)((u32)param + (size - 0x24));
SceUID fd = _sceIoOpen("ms0:/gamekey.bin", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC, 0777);
_sceIoWrite(fd, key, 16);
_sceIoClose(fd);
int ret = sceUtilitySavedataInitStart_(param);
//restore patch as it's not needed anymore after this.
memcpy((void *)UtilitySavedataInitStart_pointer, &code, 8);
_sceKernelDcacheWritebackAll();
return ret;
}
int main(SceSize args, void *argp)
{
_sceIoOpen = (void *)FindImport("IoFileMgrForUser", 0x109F50BC, 0);
_sceIoWrite = (void *)FindImport("IoFileMgrForUser", 0x42EC03AC, 0);
_sceIoClose = (void *)FindImport("IoFileMgrForUser", 0x810C4BC3, 0);
_sceKernelDcacheWritebackAll = (void *)FindImport("UtilsForUser", 0x79D1C3FA, 0);
UtilitySavedataInitStart_pointer = FindImport("sceUtility", 0x50C4CD57, 0);
memcpy(&code, (const void *)UtilitySavedataInitStart_pointer, 8);
_sw(MAKE_JUMP(sceUtilitySavedataInitStart_hook), UtilitySavedataInitStart_pointer);
_sw(0x00000000, UtilitySavedataInitStart_pointer + 4);
sceUtilitySavedataInitStart_ = (void *)&code;
_sceKernelDcacheWritebackAll();
}a few questions on thatqwikrazor87 wrote:This should work despite the firmware being used, won't work as is, but you should get the idea of how the patch works and tailor it to your needs.
Code: Select all
u32 code[2]; u32 UtilitySavedataInitStart_pointer; void (* _sceKernelDcacheWritebackAll)(void); SceUID (* _sceIoOpen)(const char *, int, SceMode); int (* _sceIoWrite)(SceUID, const void *, SceSize); int (* _sceIoClose)(SceUID); #define MAKE_JUMP(f) (0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF)) int ValidUserAddress(void *addr, int mode) { if (mode) return ((u32)addr >= 0x08400000 && (u32)addr < 0x08800000); return ((u32)addr >= 0x08800000 && (u32)addr < 0x0A000000); } //mode = 0 for search range 0x08800000 to 0x0A000000 //mode = 1 for search range 0x08400000 to 0x08800000 u32 FindImport(char *libname, u32 nid, int mode) { u32 lower = 0x08400000; u32 higher = 0x08800000; if (!mode) { lower = 0x08800000; higher = 0x0A000000; } u32 i; for (i = lower; i < higher; i += 4) { SceLibraryStubTable *stub = (SceLibraryStubTable *)i; if ((stub->libname != libname) && ValidUserAddress((void *)stub->libname, mode) \ && ValidUserAddress(stub->nidtable, mode) && ValidUserAddress(stub->stubtable, mode)) { if (strcmp(libname, stub->libname) == 0) { u32 *table = stub->nidtable; int j; for (j = 0; j < stub->stubcount; j++) { if (table[j] == nid) { return ((u32)stub->stubtable + (j * 8)); } } } } } return 0; } int (* sceUtilitySavedataInitStart_)(SceUtilitySavedataParam *param); int sceUtilitySavedataInitStart_hook(SceUtilitySavedataParam *param) { u32 size = param->base.size; u8 *key = (u8 *)((u32)param + (size - 0x24)); SceUID fd = _sceIoOpen("ms0:/gamekey.bin", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC, 0777); _sceIoWrite(fd, key, 16); _sceIoClose(fd); int ret = sceUtilitySavedataInitStart_(param); //restore patch as it's not needed anymore after this. memcpy((void *)UtilitySavedataInitStart_pointer, &code, 8); _sceKernelDcacheWritebackAll(); return ret; } int main(SceSize args, void *argp) { _sceIoOpen = (void *)FindImport("IoFileMgrForUser", 0x109F50BC, 0); _sceIoWrite = (void *)FindImport("IoFileMgrForUser", 0x42EC03AC, 0); _sceIoClose = (void *)FindImport("IoFileMgrForUser", 0x810C4BC3, 0); _sceKernelDcacheWritebackAll = (void *)FindImport("UtilsForUser", 0x79D1C3FA, 0); UtilitySavedataInitStart_pointer = FindImport("sceUtility", 0x50C4CD57, 0); memcpy(&code, (const void *)UtilitySavedataInitStart_pointer, 8); _sw(MAKE_JUMP(sceUtilitySavedataInitStart_hook), UtilitySavedataInitStart_pointer); _sw(0x00000000, UtilitySavedataInitStart_pointer + 4); sceUtilitySavedataInitStart_ = (void *)&code; _sceKernelDcacheWritebackAll(); }
1) I wouldn't know as I don't use any PC PSP emus, but I don't see any reason why they'd need to change the struct.grief3r wrote:a few questions on that
1) does this apply to the memory layout on the ppsspp emulator as well
2) does #define MAKE_JUMP(f) (0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF)) generates a jump instruction opcode given address f? ( i don't know a lot about how opcodes are generated but this seems to be the case here, as increasing the immediate value of a j opcode by 0x01 is the same as shifting 0x04 >> 2)
stub->libname != libname , shouldn't this be stub->libname == libname if we are trying to find the name of the library, or is there something im missing (on the findImport() func), need to know this as i am gonna compile this code into mips code, then try to inject it to a decrypted iso and then i could manually jump to it by finding a hook and find saveDataInintStartqwikrazor87 wrote:1) I wouldn't know as I don't use any PC PSP emus, but I don't see any reason why they'd need to change the struct.grief3r wrote:a few questions on that
1) does this apply to the memory layout on the ppsspp emulator as well
2) does #define MAKE_JUMP(f) (0x08000000 | (((u32)(f) >> 2) & 0x03FFFFFF)) generates a jump instruction opcode given address f? ( i don't know a lot about how opcodes are generated but this seems to be the case here, as increasing the immediate value of a j opcode by 0x01 is the same as shifting 0x04 >> 2)
2) yes, a jump instruction is basically the jump address divided by 4 + 0x08000000 (a jal would be 0x0C000000).
Let's say we are looking for the "sceCtrl" string in RAM.grief3r wrote:stub->libname != libname , shouldn't this be stub->libname == libname if we are trying to find the name of the library, or is there something im missing (on the findImport() func)
u8 *key = (u8 *)((u32)param + (size - 0x24));qwikrazor87 wrote:Let's say we are looking for the "sceCtrl" string in RAM.grief3r wrote:stub->libname != libname , shouldn't this be stub->libname == libname if we are trying to find the name of the library, or is there something im missing (on the findImport() func)
"sceCtrl" would be found in the stub entries, and since we are looking for it with our code it would also appear in our code, so we make sure the string we find is not the string in our code.