int start_decryption1(int code1, unsigned char * buf, int buflen, int code2, int * phandle) {
int argst[11];
int res;
memset(argst,0,0x2c);
argst[0]=0x2c;
argst[1]=code1;
argst[2]=(int)buf;
argst[3]=buflen;
argst[4]=code2;
sceClibPrintf("Calling type 1 decryption with code1 = 0x%x buf = 0x%x buflen = 0x%x code2 = 0x%x
", code1, (int) buf, buflen, code2);
res=callKernelFunction(SceSblSsUpdateMgr_0x6E8DDAC4,code1,argst,phandle,0 );
return res;
}
int start_decryption2(int code1, unsigned char * buf, int buflen, int code2, int * phandle) {
int argst[11];
int res;
memset(argst,0,0x2c);
argst[0]=0x2c;
argst[1]=code1;
argst[2]=(int)buf;
argst[3]=buflen;
argst[4]=code2;
sceClibPrintf("Calling type 2 decryption with code1 = 0x%x buf = 0x%x buflen = 0x%x code2 = 0x%x
", code1, (int) buf, buflen, code2);
res=callKernelFunction(SceSblSsUpdateMgr_0x1A39F6EE,code1,argst,phandle,0 );
return res;
}
int start_decryption3(int code1, unsigned char * buf, int buflen, int code2, int * phandle) {
int argst[11];
int res;
memset(argst,0,0x2c);
argst[0]=0x2c;
argst[1]=code1;
argst[2]=(int)buf;
argst[3]=buflen;
argst[4]=code2;
sceClibPrintf("Calling type 3 decryption with code1 = 0x%x buf = 0x%x buflen = 0x%x code2 = 0x%x
", code1, (int) buf, buflen, code2);
res=callKernelFunction(SceSblSsUpdateMgr_0xC1792A1C,code1,argst,phandle,0 );
return res;
}
int check_decryption_status(int code,int handle,int * out1, int * out2, int * out3, int * out4) {
int argst[11];
int res;
memset(argst,0,0x2c);
argst[0]=0x2c;
argst[7]=(int)out1;
argst[8]=(int)out2;
argst[9]=(int)out3;
argst[10]=(int)out4;
sceClibPrintf("Calling status with code = 0x%x handle = 0x%x
", code, handle);
res=callKernelFunction(SceSblSsUpdateMgr_0xF403143E,code,handle,argst,0);
return res;
}
int get_final_size(unsigned char * buf) {
int * poffs;
int * psize;
poffs = (int *) (buf+0x10);
psize = (int *) (buf+(*poffs)+0x20);
return *psize;
}
int get_type(unsigned char * buf) {
int * poffs;
int * psize;
if ( *(int *)buf == 0x00454353 )
{
poffs = (int *) (buf+0x10);
psize = (int *) (buf+(*poffs)+4);
return *psize;
}
else
{
return -1;
}
}
unsigned char * get_data_offset(unsigned char * buf) {
int * poffs;
poffs = (int *) (buf+0x10);
return (buf+(*poffs)+0x80);
}
int complete_decryption(int code, int handle, unsigned char * buf, int maxlen) {
int argst[11];
int res;
unsigned char * payload;
int size;
memset(argst,0,0x2c);
argst[0]=0x2c;
argst[1]=code;
argst[5]=(int)buf;
argst[6]=maxlen;
sceClibPrintf("Calling complete decryption with code = 0x%x handle = 0x%x buf = 0x%x maxlen = 0x%x
", code, handle, (int) buf, maxlen);
res=callKernelFunction(SceSblSsUpdateMgr_0x4897AD56,code,handle,argst,0);
return res;
}
int
do_decrypt_file (const char *inpath, const char *outpath, const char *errpath, unsigned int size)
{
int fd;
int res;
int memid;
int read;
int maxlen=0x810000;
int argst[0x2c/4];
int id;
int type;
int code;
unsigned char * src, *outbuf;
unsigned int handle, p1,p2,p3,p4;
res=callKernelFunction(SceSblSsUpdateMgr_0x4C06F41C,size,&src,0,0);
sceClibPrintf("Allocation returned 0x%x addr 0x%x
", res, (int)src);
if(res) {
sceClibPrintf("Cannot allocate memory. (size 0x%x) fail.
", size);
return 0;
}
//sceClibPrintf("Loading Firmware pkg file from host0:");
fd= sceIoOpen(inpath,1,0);
read = 0;
while ((read = sceIoRead(fd,src,size-read)) > 0);
sceIoClose(fd);
code = get_type(src);
switch (code) {
case -1:
sceClibPrintf("Not an encrypted file.
");
goto ERROR;
case 3:
case 4:
case 0x1B:
type = 3;
res=start_decryption3(code,src,size,9,&handle);
break;
case 0:
case 2:
case 5:
case 6:
case 7:
case 0xE:
case 0x1A:
sceClibPrintf("Warning, code %x is unsupported!
", code);
default:
type = 2;
res=start_decryption2(code,src,size,9,&handle);
break;
}
if(res) {
sceClibPrintf("start_decryption failed. (0x%x)
", res);
goto ERROR;
}
for(;
{
res=check_decryption_status(type,handle,&p1,&p2,&p3,&p4);
if(res) {
sceClibPrintf("check_decryption_status failed. (0x%x)
", res);
goto ERROR;
}
if(p3 == 5) {
break;
} else {
sceKernelDelayThread(0x7A120);
}
}
sceClibPrintf("p1= 0x%x p2 = 0x%x p3 = 0x%x p4 = 0x%x
", p1,p2,p3,p4);
if(p2 == 0) {
sceClibPrintf("Starting to write %s
", outpath);
fd= sceIoOpen(outpath,0x603,0x186);
read = get_final_size(src);
while ((read -= sceIoWrite(fd,get_data_offset(src),read)) > 0);
sceIoClose(fd);
} else {
sceClibPrintf("Error decrypting. Writing results to %s
", errpath);
fd= sceIoOpen(errpath,0x603,0x186);
read = get_final_size(src);
while ((read -= sceIoWrite(fd,get_data_offset(src),read)) > 0);
sceIoClose(fd);
goto ERROR;
}
res=complete_decryption(type,handle,src,maxlen);
if(res) {
sceClibPrintf("complete_decryption failed. (0x%x)
", res);
goto ERROR;
}
res=callKernelFunction(SceSblSsUpdateMgr_0xBD677F5A,src,0,0,0);
return 1;
ERROR:
res=callKernelFunction(SceSblSsUpdateMgr_0xBD677F5A,src,0,0,0);
return 0;
}
void
do_decrypt_dir (const char *path)
{
int fd;
SceIoDirent dir;
char input[256];
char output[256];
char errput[256];
if ((fd = sceIoDopen(path)) < 0)
{
sceClibPrintf("Error opening pkg dir.
");
return;
}
while (sceIoDread(fd, &dir) > 0)
{
sprintf(input, "%s/%s", path, dir.d_name);
sprintf(output, "%s/%s.dec", path, dir.d_name);
sprintf(errput, "%s/%s.err", path, dir.d_name);
sceClibPrintf("Decrypting %s (size 0x%x)
", input, (unsigned int)dir.d_stat.st_size);
if (do_decrypt_file(input, output, errput, (unsigned int)dir.d_stat.st_size))
sceClibPrintf("Decrypted to %s
", output);
else
sceClibPrintf("Failed to decrypt %s
", dir.d_name);
}
sceIoDclose(fd);
}