Advertising (This ad goes away for registered users. You can Login or Register)

trying to find gamekey in ppsspp for decryption of save data

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
grief3r
Posts: 358
Joined: Sat Nov 09, 2013 4:12 am

trying to find gamekey in ppsspp for decryption of save data

Post by grief3r »

im tryin to branch to sceUtilitySaveDataInitStart so i can get the gamekey for one of my games, however the fxn is just

Code: Select all

jr ra
syscall
and afterwards the registers are all set to 0xDEADBEEF (most of them), so it seems no way to look in the functionn itself bc it's kernel function
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
Advertising
PSV1001 2.61 FieldRunners
PSP1001 6.60 Pro-C
PSP 3001 6.20 Pro-C2
grief3r
Posts: 358
Joined: Sat Nov 09, 2013 4:12 am

Re: trying to find gamekey in ppsspp for decryption of save

Post by grief3r »

:ugeek: bump, is anyone here good with finding gamekeys ive ben stuck for the past week
Advertising
PSV1001 2.61 FieldRunners
PSP1001 6.60 Pro-C
PSP 3001 6.20 Pro-C2
Yoti
VIP
Posts: 369
Joined: Sun Oct 17, 2010 4:49 am
Location: Russia

Re: trying to find gamekey in ppsspp for decryption of save

Post by Yoti »

May be better use JPCSP?
IF SOMEONE HAS AN 07G PSP-3000 PLZ CONTACT ME VIA PM.

Image
Do not forget about adb kill-server. Really.
wth
HBL Developer
Posts: 834
Joined: Wed Aug 31, 2011 4:44 pm
Contact:

Re: trying to find gamekey in ppsspp for decryption of save

Post by wth »

I guess the SceUtilitySavedataParam pspsdk struct might be wrong (some structs even change depending on fw).

Here's the one coldbird made for 6.60 :

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;
The following sample he made was included in ark's source
Attachments
unocrypter.zip
(63.6 KiB) Downloaded 318 times
qwikrazor87
Guru
Posts: 2874
Joined: Sat Apr 21, 2012 1:23 pm
Location: The North Pole

Re: trying to find gamekey in ppsspp for decryption of save

Post by qwikrazor87 »

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();
}
PSP 2001 - TA-085 - 6.61 PRO-C2
PS Vita 3G - PCH-1101 - 3.65 HENkaku Ensō
Alcatel phone - Android 8.1.0
Laptop - Toshiba Satellite L305D-S5974 - Ubuntu 16.04 LTS
grief3r
Posts: 358
Joined: Sat Nov 09, 2013 4:12 am

Re: trying to find gamekey in ppsspp for decryption of save

Post by grief3r »

qwikrazor87 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();
}
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)
PSV1001 2.61 FieldRunners
PSP1001 6.60 Pro-C
PSP 3001 6.20 Pro-C2
qwikrazor87
Guru
Posts: 2874
Joined: Sat Apr 21, 2012 1:23 pm
Location: The North Pole

Re: trying to find gamekey in ppsspp for decryption of save

Post by qwikrazor87 »

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)
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.
2) yes, a jump instruction is basically the jump address divided by 4 + 0x08000000 (a jal would be 0x0C000000).
PSP 2001 - TA-085 - 6.61 PRO-C2
PS Vita 3G - PCH-1101 - 3.65 HENkaku Ensō
Alcatel phone - Android 8.1.0
Laptop - Toshiba Satellite L305D-S5974 - Ubuntu 16.04 LTS
grief3r
Posts: 358
Joined: Sat Nov 09, 2013 4:12 am

Re: trying to find gamekey in ppsspp for decryption of save

Post by grief3r »

qwikrazor87 wrote:
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)
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.
2) yes, a jump instruction is basically the jump address divided by 4 + 0x08000000 (a jal would be 0x0C000000).
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 saveDataInintStart

edit, nvm im guessing that is the correct code otherwise it would be reduntant to compare the strings if the pointers have been checked to be the same
Last edited by grief3r on Fri Sep 04, 2015 10:16 pm, edited 1 time in total.
PSV1001 2.61 FieldRunners
PSP1001 6.60 Pro-C
PSP 3001 6.20 Pro-C2
qwikrazor87
Guru
Posts: 2874
Joined: Sat Apr 21, 2012 1:23 pm
Location: The North Pole

Re: trying to find gamekey in ppsspp for decryption of save

Post by qwikrazor87 »

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)
Let's say we are looking for the "sceCtrl" string in RAM.
"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.
PSP 2001 - TA-085 - 6.61 PRO-C2
PS Vita 3G - PCH-1101 - 3.65 HENkaku Ensō
Alcatel phone - Android 8.1.0
Laptop - Toshiba Satellite L305D-S5974 - Ubuntu 16.04 LTS
grief3r
Posts: 358
Joined: Sat Nov 09, 2013 4:12 am

Re: trying to find gamekey in ppsspp for decryption of save

Post by grief3r »

qwikrazor87 wrote:
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)
Let's say we are looking for the "sceCtrl" string in RAM.
"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.
u8 *key = (u8 *)((u32)param + (size - 0x24));

if the key is always 24 bytes before the end of Param struct,if i know a0 (which is a pointer to a saveDataParam), would i find the gamekey there?, i do have access to that register and it seems to point to an unencrypted save data (which if i set a breakpoint to the adress where a0 still holds this pointer it breaks more than once for reasons i do not know, and the contents of the Param struct change slightly every time, but the pointer is the same).
PSV1001 2.61 FieldRunners
PSP1001 6.60 Pro-C
PSP 3001 6.20 Pro-C2
Locked

Return to “Programming and Security”