For you curious people, heres an explanation of how Pandora works, by SilverSpring.
I think this deserves a sticky in the Hacks section :P
Originally Posted by TorchI meant once all the service centres have been updated with the new method.Originally Posted by SilverSpringOf course the smart thing to do is just fix the exploit in the preipl code. That way they dont have to change their service mode, it will prevent pandora from working while still letting their official service mode work. No need to update their batteries or even their methods (which would have been rather expensive).
The actual pandora battery will still enable service mode, but it just wont boot anything from the ms without the exploit. Only their own magic ms will run successfully.
I fully expect them to have already done this and will probably show up in stores once their current stock of psp's have been exhausted.Originally Posted by TorchThat was exactly what I suggested in an earlier discussion (wasnt aware of the preipl terminology n stuff), but then FreePlay said that the the pandora code was signed as authentic using a KIRK related exploit and it was as valid as officially signed boot code. (Under the presumption that the EBOOT signatures are a totally unrelated method of signing which is why we cant sign EBOOTs)
So am I correct in understanding that the pandora code is NOT signed, but just that we are able to execute it due to an exploit?Originally Posted by SilverSpringThe actual pandora code isnt signed, just a tiny fake block is signed (just enough to make use of the exploit in the preipl to make your unsigned code run). If it were possible to sign whole chunks of code there would be no need for pandora (EBOOT's are signed the exact same way), just sign your homebrew and run.
So if they fixed the exploit in the preipl, the pandora battery would still enter service mode, would still try to run the IPL off the ms, the fake signed block would still appear valid and will decrypt properly but then wont jump to your unsigned code. That's as far as it'll go, without the exploit no unsigned code will be run.Originally Posted by TorchBut is the signature actually as valid as being signed by Sony's private keys?
Since the keys are unknown, the only thing I can think of is that the chunk of fake code was so small, even smaller than the length of the private key itself, that it could be bruteforced without knowing the key, in less time.
If not that, do you know how exactly the whole exploit thing works?Originally Posted by SilverSpringYes the block was small enough to bruteforce (hence why you couldnt sign a whole EBOOT, would have to bruteforce the whole thing). The private key wasnt bruteforced though (not that it would matter if it were though, the algorithms are still unknown).
How the decryption works is this, the data is first encrypted and then the encrypted data is signed. When passed to the crypto engine, first it checks the signature and if it's valid it will decrypt the data (algorithms for both the encryption & signature are unknown, not that I know of anyway, maybe someone knows...or not ).
The fake encrypted data is bruteforced to decrypt into your chosen data (to be able to exploit the preipl). And the signature for your fake encrypted data is bruteforced again to make it appear valid in the eyes of the crypto engine so that it will will go ahead and decrypt your fake encrypted data.
The preipl exploit works like this:
First a decrypted ipl block:
0x00: load address
0x04: data size
0x08: entry address
0x0C: checksum of previous block
A typical example might be
Which means load 0xF50-byte data to 0x040F1EA0. 0xB71C6EBA is the checksum of the previous block. Then entry address is 0 since it hasnt reached the end yet and there are more blocks to load. Once it has loaded all the ipl blocks the very last block will have entry address of where the whole ipl has been loaded (typically 0x040F0000). And will then jump to that address.
Preipl pseudocode for loading & decrypting the ipl:
int iplBlockNumber = 0;
u32 checksum = 0;
// load/decrypt all encrypted ipl blocks
// copy an encrypted ipl block to 0xBFD00000-0xBFD01000 (4KB embedded cpu ram)
if (LoadIplBlock(iplBlockNum ber, block) < 0)
// decrypt the ipl block in place (uh oh...)
if (DecryptIplBlock(block, block))
// first block will have zero as its checksum since there is no previous block (another uh oh...)
if (block->checksum != checksum)
// load the 'data' section of the ipl block to the specified address (0x040Fxxxx range)
checksum = memcpy(block->loadaddr, block->data, block->blocksize);
// reached the end of the ipl, jump to the entry address (0x040F0000)
// clear caches
// jump to ipl - do not return
As the preipl loads the first ipl block (the fake one), it decrypts the block in-place, ie. the decrypted block just overwrites your encrypted block. The fake block only decrypts into four bytes of all 0's so it ends up only overwriting the first four bytes of your fake block (with four 0's) after decryption.
The fake signed block:
00000000: 00 00 00 00 00 00 00 00 00 01 D0 BF 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020: 52 A1 05 CD 3A 52 59 28 0A D1 31 F1 BD 87 2E CC
00000030: 14 DA 02 2F 77 88 C7 66 F3 32 07 BD 1A 08 9E 4C
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000070: 04 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0: 00 00 00 00 00 00 00 00 00 00 00 01 C6 5F 74 12
The most important parts to note:
0x20-0x3F is the bruteforced hash signatures
0xA0-0xAF is the bruteforced encrypted data
0x70-0x73 is the size of the decrypted data (only 4 bytes)
A slight flaw in the crypto engine allowed the bruteforce to be performed on a magnitude-times smaller scale than normally required.
After decryption, the preipl thinks the data is now a decrypted ipl block.
So note the first 0x10 bytes:
0x00000000 (load address which was faked to four 0's when decrypted)
0x00000000 (size of the block to load, none)
0xBFD00100 (the entry address, the most important part, where your unsigned code is located)
It passes the checksum test (with 0x00000000), it skips the loading of any data (since the loadaddr has been faked to 0x00000000), see's the entry address of 0xBFD00100 and thinks it has reached the end of the ipl and so goes jumps to that address (which is where your unsigned code will be).
So that's essentially it in a nutshell. But dont let a quick 5 min. summary of the exploit underestimate the enourmous effort involved in bringing it to fruition (as the final product known as Pandora).