Pandora: Difference between revisions

From PSP Developer wiki
Jump to navigation Jump to search
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 21: Line 21:
= Official JigKick =
= Official JigKick =


The official Jigkick is running as a battery emulator which communicates to the PSP's System Controller, it passes an authentication using special key IDs set during the challenge when the battery serial is 0xFFFFFFFF if it passes, the GPIO that sets service mode is enabled.
The official Jigkick is running as a battery emulator which communicates to the PSP's System Controller using the Baryon k line., it passes an authentication using special key IDs set during the challenge when the battery serial is 0xFFFFFFFF if it passes, the GPIO that sets service mode is enabled.


= DTP-T1000/Development Tool JIG Memory Stick Test Mode =
== PSP-1000/PSP-2000/PSP-3000 ==
 
The battery emulator connects to the Baryon K Line (middle pin (PIN 2) on the battery connector)
 
== PSP-N1000 ==
See [[Psp Go Jigkick|PSP Go Jigkick]]
 
== PSP-E1000 ==
 
On the PSP-E1000, the battery emulator connects to the Baryon K Line on the ID PIN of the Mini USB connector.
 
 
Button combo:
 
To initiate the Jigkick challenge, Hold down LTrigger + RTrigger + Left + Circle when the k line and DC 5V are connected;
Turn on Power on console without letting go of buttons.
 
 
== DTP-T1000/Development Tool JIG Test/emulation Mode ==


Starting from kbooti 0.7.0, a special JIG test mode exists, it will read an IPL block at 0x2000 on the Memory Stick instead of address 0xBFE01000 if the specific condition is met:  
Starting from kbooti 0.7.0, a special JIG test mode exists, it will read an IPL block at 0x2000 on the Memory Stick instead of address 0xBFE01000 if the specific condition is met:  
Line 38: Line 56:
In kbooti revision 3.5.0 this mode skips the XOR step (overwrites the xor key with 00s in the scratchpad) on the kirk header, allowing to use a regular IPL block to achieve code execution and dump the payload (without the xor key).
In kbooti revision 3.5.0 this mode skips the XOR step (overwrites the xor key with 00s in the scratchpad) on the kirk header, allowing to use a regular IPL block to achieve code execution and dump the payload (without the xor key).


= DTP-H1500/Testing Tool JIG Mode =
== DTP-H1500/Testing Tool JIG Mode ==


The Battery emulator will simulate a Pandora battery (serial 0xFFFFFFFF) when the P24 switch on the S3503 DIPSW is set to 1.
The Battery emulator will simulate a Pandora battery (serial 0xFFFFFFFF) when the P24 switch on the S3503 DIPSW is set to 1.
Line 44: Line 62:
= Custom IPL =
= Custom IPL =


[[JigKick Battery]] and [[Magic Memory Stick]] allow loading [[IPL]] from [[Memory Stick]] instead of NAND, which is useful for unbricking. But the [[IPL]] still has to be encrypted and signed to be accepted by [[PRE-IPL]]. This was first solved by Bruteforce attack (?2005? ?2007?). Then in 2011 [[KIRK Crypto Engine]] command 1 key got retrieved thanks to PS3 hack, and allowed properly encrypting and signing IPL, as demonstrated by mathieulh in 2018.
[[JigKick Battery]] and [[Magic Memory Stick]] allow loading [[IPL]] from [[Memory Stick]] instead of NAND, which is useful for unbricking. But the [[IPL]] still has to be encrypted and signed to be accepted by the [[iplloader]]. This was first solved by Bruteforce attack (?2005? ?2007?). Then in 2011 [[KIRK Crypto Engine]] command 1 key got retrieved thanks to PS3 hack, and allowed properly encrypting and signing IPL, as demonstrated by mathieulh in 2018.


== IPL Bruteforce Attack ==
== IPL Bruteforce Attack ==


See [https://events.ccc.de/congress/2007/Fahrplan/attachments/1040_psphacking.odp 24C3 Talk by Tyranid (2007)]. [http://uofw.github.io/upspd/docs/SilverSpring_Blog/my.malloc.us/silverspring/pandora-exploit/index.html PRE-IPL exploit writeup by SilverSpring]
See [https://events.ccc.de/congress/2007/Fahrplan/attachments/1040_psphacking.odp 24C3 Talk by Tyranid (2007)]. [http://uofw.github.io/upspd/docs/SilverSpring_Blog/my.malloc.us/silverspring/pandora-exploit/index.html iplloader exploit writeup by SilverSpring]


The fake encrypted data is bruteforced to decrypt into your chosen data (to be able to exploit the [[PRE-IPL]]). 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 fake encrypted data is bruteforced to decrypt into your chosen data (to be able to exploit the [[iplloader]]). 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 [[PRE-IPL]] exploit works like this:
The [[iplloader]] exploit works like this:


<pre>
<pre>
Line 72: Line 90:
Which means load 0xF50-byte data to 0x040F1EA0. 0xB71C6EBA is the checksum of the previous block. Then entry address is 0 since it hasn't 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.
Which means load 0xF50-byte data to 0x040F1EA0. 0xB71C6EBA is the checksum of the previous block. Then entry address is 0 since it hasn't 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.


PRE-IPL pseudocode for loading and decrypting the IPL:
iplloader pseudocode for loading and decrypting the IPL:


<pre>
<pre>
Line 112: Line 130:
</pre>
</pre>


As the PRE-IPL 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.
As the iplloader 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:
The fake signed block:
Line 138: Line 156:
A slight flaw in the crypto engine allowed bruteforce to be performed on a magnitude-times smaller scale than normally required.
A slight flaw in the crypto engine allowed bruteforce to be performed on a magnitude-times smaller scale than normally required.


After decryption, the PRE-IPL thinks the data is now a decrypted IPL block.
After decryption, the iplloader thinks the data is now a decrypted IPL block.


So note the first 0x10 bytes:
So note the first 0x10 bytes:
Line 278: Line 296:
</pre>
</pre>


* IPL Block for Prototype (0.4 and 0.6) PRE-IPL, containing the following MIPS assembly instructions (the jal instruction is not used because of the address length, instead the address is stored to a register using the load immediate instruction, then the jump register instruction is used to jump to it, assembly is used to artificially make the jump because older IPL blocks cannot contain an entrypoint value, the old PRE-IPL instead jumps to 0x88400000 as an hardcoded entrypoint address):
* IPL Block for Prototype (0.4 and 0.6) iplloader, containing the following MIPS assembly instructions (the jal instruction is not used because of the address length, instead the address is stored to a register using the load immediate instruction, then the jump register instruction is used to jump to it, assembly is used to artificially make the jump because older IPL blocks cannot contain an entrypoint value, the old iplloader instead jumps to 0x88400000 as an hardcoded entrypoint address):
<pre>
<pre>
.set noreorder
.set noreorder
Line 290: Line 308:
</pre>
</pre>


This block will jump to 0xBFE01100 so you can use this block as if you were using a Pandora IPL block on the prototype PRE-IPL, which saves you time from encrypting new IPLs every time you need to test a new build.
This block will jump to 0xBFE01100 so you can use this block as if you were using a Pandora IPL block on the prototype iplloader, which saves you time from encrypting new IPLs every time you need to test a new build.


Note: There is no 0xBFC00100 IPL block for the prototype PRE-IPL because they do not load IPL blocks there and you cannot use that address as it would overwrite the PRE-IPL code itself which does not use a payload section/address and runs entirely from 0xBFC00000.
Note: There is no 0xBFC00100 IPL block for the prototype iplloader because they do not load IPL blocks there and you cannot use that address as it would overwrite the iplloader code itself which does not use a payload section/address and runs entirely from 0xBFC00000.


<pre>
<pre>
Line 315: Line 333:
</pre>
</pre>


* IPL Block for 0.7.0 and later (up to 2.7.1) PRE-IPL, containing the previously mentioned jr MIPS assembly instruction to address 0xBFE01100  
* IPL Block for 0.7.0 and later (up to 2.7.1) iplloader, containing the previously mentioned jr MIPS assembly instruction to address 0xBFE01100  
This IPL block has been tested successfully on 2.6.0 and 2.7.1 kbooti.
This IPL block has been tested successfully on 2.6.0 and 2.7.1 kbooti.


Line 343: Line 361:
These are available in binary format here: [https://mega.nz/#F!MlFi1QqZ!fGo2pkCEmjFiPynKtDC0Hg download link].
These are available in binary format here: [https://mega.nz/#F!MlFi1QqZ!fGo2pkCEmjFiPynKtDC0Hg download link].


The 0xBFD00100 version of these blocks work as-is by replacing the time attacked forged block with the properly encrypted ones supplied. The 0xBFE01100 and 0xBFCD00100 version (which only works on Development Tool units), may require you to rebuild/recompile your custom IPLs using 0xBFE01100 or 0xBFCD00100 as the entrypoints respectively, as well as using a modified iplboot as the one used by retail custom IPLs uses PRE-IPL hardcoded addresses. It may be wiser to rebuild it as a fully valid IPL instead using ipltool [https://github.com/zecoxao/ipltool], although using the Pandora compatible IPL block instead would allow you to port retail custom IPL projects on devkit with minimal efforts.
The 0xBFD00100 version of these blocks work as-is by replacing the time attacked forged block with the properly encrypted ones supplied. The 0xBFE01100 and 0xBFCD00100 version (which only works on Development Tool units), may require you to rebuild/recompile your custom IPLs using 0xBFE01100 or 0xBFCD00100 as the entrypoints respectively, as well as using a modified iplboot because the one used by retail custom IPLs uses iplloader hardcoded addresses. It may be wiser to rebuild it as a fully valid IPL instead using ipltool [https://github.com/zecoxao/ipltool], although using the Pandora compatible IPL block instead would allow you to port retail custom IPL projects on devkit with minimal efforts.


Keep in mind that under normal circumstances neither the Memory Stick nor the NAND devices are initialized by the DTP-T1000 PRE-IPL. Reading or writing to and from either of these devices will require you to add the initialization routine to your IPL (most likely within your iplboot binary).
Keep in mind that under normal circumstances neither the Memory Stick nor the NAND devices are initialized by the DTP-T1000 iplloader. Reading or writing to and from either of these devices will require you to add the initialization routine to your IPL (most likely within your iplboot binary).


The IPL SDK (available here: [https://github.com/mathieulh/PSP_IPL_SDK]) contains full low-level driver implementation for both devices which you can use in your projects.
The IPL SDK (available here: [https://github.com/mathieulh/PSP_IPL_SDK]) contains full low-level driver implementation for both devices which you can use in your projects.

Latest revision as of 21:34, 17 June 2024

On August 22 2007, Team C+D released the "Pandora's Battery" which was the Prometheus Project everyone was waiting for. It converted a spare Memory Stick Pro Duo and PSP battery into Magic Memory Stick and JigKick Battery. Some people mistake Pandora's Battery for the JigKick Battery, but Pandora's battery is both the Magic Memory Stick and the JigKick Battery. The Memory Stick and battery can then be used to downgrade any supported PSP from any FW version or to recover from a brick.

Usage[edit | edit source]

The official usage by SCE services is PSP unbrick. It also implicitely allows downgrade. See #Official JigKick.

The unofficial usage, permitted by Prometheus Project, is Custom IPL loading, for unbrick, downgrade, CFW installation, CFW boot and more.

Installation[edit | edit source]

Refer to Magic Memory Stick and JigKick Battery for their installation and usage.

To wikify: [1].

For custom IPL see below.

Uninstallation[edit | edit source]

After the downgrade/unbrick service has been completed, the Memory Stick and battery can be restored for normal usage.

Official JigKick[edit | edit source]

The official Jigkick is running as a battery emulator which communicates to the PSP's System Controller using the Baryon k line., it passes an authentication using special key IDs set during the challenge when the battery serial is 0xFFFFFFFF if it passes, the GPIO that sets service mode is enabled.

PSP-1000/PSP-2000/PSP-3000[edit | edit source]

The battery emulator connects to the Baryon K Line (middle pin (PIN 2) on the battery connector)

PSP-N1000[edit | edit source]

See PSP Go Jigkick

PSP-E1000[edit | edit source]

On the PSP-E1000, the battery emulator connects to the Baryon K Line on the ID PIN of the Mini USB connector.


Button combo:

To initiate the Jigkick challenge, Hold down LTrigger + RTrigger + Left + Circle when the k line and DC 5V are connected; Turn on Power on console without letting go of buttons.


DTP-T1000/Development Tool JIG Test/emulation Mode[edit | edit source]

Starting from kbooti 0.7.0, a special JIG test mode exists, it will read an IPL block at 0x2000 on the Memory Stick instead of address 0xBFE01000 if the specific condition is met:

   if ( MEMORY[0xBFEFFFFC] < 0 ) use MS

Writing 0xFFFFFFFF at 0xBFEFFFFC does indeed enable the pseudo service mode and reads the block from the Memory stick, this mode is used by Sony Engineers to debug JIG Memory sticks by writing a kbooti using bloadp and then using reset parameters to set the flag at0xBFEFFFFC using the sbootp param/arg from the reset command of either dstdb or bsreset (dspreset) such as follows: /usr/local/sony/bin/bootdispi/dspreset 80000000 (FFFEFFFF for example sets all boot flags to 0xFF), to set the DTP-T1000 into JIG emulation mode.

Because flags are incremental only the only way to clear the JIG flag using official SDK tools is to run the bloadp command again as this clears the whole tachsm0 memory including the flags.

Kbooti remains loaded in memory until the main unit is turned off or bloadp has ran again, allowing then to power cycle through different memory stick.

In kbooti revision 3.5.0 this mode skips the XOR step (overwrites the xor key with 00s in the scratchpad) on the kirk header, allowing to use a regular IPL block to achieve code execution and dump the payload (without the xor key).

DTP-H1500/Testing Tool JIG Mode[edit | edit source]

The Battery emulator will simulate a Pandora battery (serial 0xFFFFFFFF) when the P24 switch on the S3503 DIPSW is set to 1.

Custom IPL[edit | edit source]

JigKick Battery and Magic Memory Stick allow loading IPL from Memory Stick instead of NAND, which is useful for unbricking. But the IPL still has to be encrypted and signed to be accepted by the iplloader. This was first solved by Bruteforce attack (?2005? ?2007?). Then in 2011 KIRK Crypto Engine command 1 key got retrieved thanks to PS3 hack, and allowed properly encrypting and signing IPL, as demonstrated by mathieulh in 2018.

IPL Bruteforce Attack[edit | edit source]

See 24C3 Talk by Tyranid (2007). iplloader exploit writeup by SilverSpring

The fake encrypted data is bruteforced to decrypt into your chosen data (to be able to exploit the iplloader). 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 iplloader exploit works like this:

First a decrypted IPL block:
0x00: load address
0x04: data size
0x08: entry address
0x0C: checksum of previous block
0x10: data

A typical example might be
0x040F1EA0
0x00000F50
0x00000000
0xB71C6EBA
...data...

Which means load 0xF50-byte data to 0x040F1EA0. 0xB71C6EBA is the checksum of the previous block. Then entry address is 0 since it hasn't 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.

iplloader pseudocode for loading and decrypting the IPL:

int iplBlockNumber = 0;
u32 checksum = 0;

// load/decrypt all encrypted ipl blocks
while(1)
{
// copy an encrypted ipl block to 0xBFD00000-0xBFD01000 (4KB embedded cpu ram)
if (LoadIplBlock(iplBlockNum ber, block) < 0)
while(1);

// decrypt the ipl block in place (uh oh...)
if (DecryptIplBlock(block, block))
while(1);

// first block will have zero as its checksum since there is no previous block (another uh oh...)
if (block->checksum != checksum)
while(1);

// load the 'data' section of the ipl block to the specified address (0x040Fxxxx range)
if (block->loadaddr)
checksum = memcpy(block->loadaddr, block->data, block->blocksize);

// reached the end of the ipl, jump to the entry address (0x040F0000)
if (block->entry)
{
// clear caches
Dcache();
Icache();

// jump to ipl - do not return
block->entry();
}

iplBlockNumber++;
}

As the iplloader 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:

Code:
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 bruteforce to be performed on a magnitude-times smaller scale than normally required.

After decryption, the iplloader 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)
0x00000000 (checksum)

It passes the checksum test (with 0x00000000), it skips the loading of any data (since the loadaddr has been faked to 0x00000000), sees 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 minutes summary of the exploit underestimate the enormous effort involved in bringing it to fruition (as the final product known as Pandora).

Properly encrypted Pandora compatible IPL blocks[edit | edit source]

On March 10th 2018, Developer Mathieulh released properly encrypted Pandora compatible IPL blocks using KIRK command 1 key.

Here are a few of those custom IPLs:

  • Retail flagged IPL block with entrypoint set to 0xBFD00100:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  D0 F9 88 F7 09 93 B7 B5 6C 37 6E 85 87 17 A5 34  Ðùˆ÷.“·µl7n…‡.¥4
00000030  A2 EE B9 CC 8B 1F DE 39 6E 41 1D 85 94 7A 3C 20  ¢î¹Ì‹.Þ9nA.…”z< 
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  14 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  41 87 7C C4 64 43 03 3C 9B C8 E9 01 26 0F 28 0B  A‡|ÄdC.<›Èé.&.(.
000000B0  DC 34 84 75 7F D2 4D 0F B7 3E 25 9F B5 AB A4 A5  Ü4„u.ÒM.·>%Ÿµ«¤¥
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • Devkit flagged IPL block with entrypoint set to 0xBFD00100:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  DC 5C 78 5D 30 C6 15 9A 5B CF 19 CD D4 48 4E D6  Ü\x]0Æ.š[Ï.ÍÔHNÖ
00000030  51 7F 7B 4A 56 91 FE DD CC 16 B2 54 BD 5E 71 62  Q.{JV‘þÝÌ.²T½^qb
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 FF FF FF FF  ............ÿÿÿÿ
00000070  14 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  41 87 7C C4 64 43 03 3C 9B C8 E9 01 26 0F 28 0B  A‡|ÄdC.<›Èé.&.(.
000000B0  DC 34 84 75 7F D2 4D 0F B7 3E 25 9F B5 AB A4 A5  Ü4„u.ÒM.·>%Ÿµ«¤¥
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • Devkit flagged IPL block with entrypoint set to 0xBFE01100 (only works on DTP-T1000/DEM-1000!, does not work on 2.6.0+ Kbooti):
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  DC 5C 78 5D 30 C6 15 9A 5B CF 19 CD D4 48 4E D6  Ü\x]0Æ.š[Ï.ÍÔHNÖ
00000030  F4 18 98 12 F7 5B 0F F5 8E F7 82 63 8D 82 44 09  ô.˜.÷[.õŽ÷‚c.‚D.
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 FF FF FF FF  ............ÿÿÿÿ
00000070  14 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  EE E2 51 4C 7C 0C A2 F0 2C B4 D9 7C 47 F0 24 D4  îâQL|.¢ð,´Ù|Gð$Ô
000000B0  FC 0E E6 DE 16 42 A6 FC 79 2A 95 9D B1 EB 6A 96  ü.æÞ.B¦üy*•.±ëj–
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • Retail flagged IPL with entrypoint set to 0xBFE01100 (only works on DTP-T1000/DEM-1000!, does not work on 2.6.0+ Kbooti):
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  D0 F9 88 F7 09 93 B7 B5 6C 37 6E 85 87 17 A5 34  Ðùˆ÷.“·µl7n…‡.¥4
00000030  C7 07 99 1D E9 31 AC C6 67 82 E0 F3 0A 62 0D F0  Ç.™.é1¬Æg‚àó.b.ð
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  14 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  EE E2 51 4C 7C 0C A2 F0 2C B4 D9 7C 47 F0 24 D4  îâQL|.¢ð,´Ù|Gð$Ô
000000B0  FC 0E E6 DE 16 42 A6 FC 79 2A 95 9D B1 EB 6A 96  ü.æÞ.B¦üy*•.±ëj–
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • Retail flagged IPL with entrypoint set to 0xBFC00100 (only works on DTP-T1000/DEM-1000!, does not work on 2.6.0+ Kbooti):
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  D0 F9 88 F7 09 93 B7 B5 6C 37 6E 85 87 17 A5 34  Ðùˆ÷.“·µl7n…‡.¥4
00000030  F9 93 88 D8 32 EE 21 95 97 A4 0F 6E 28 40 42 05  ù“ˆØ2î!•—¤.n(@B.
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  14 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  5B 31 9E 6C DF 78 01 CD 2E 45 65 EB 92 9E 85 98  [1žlßx.Í.Eeë’ž…˜
000000B0  5B 6A E9 AF 53 B2 17 5A 1E 55 1E 39 27 9E 68 53  [jé¯S².Z.U.9'žhS
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • IPL Block for Prototype (0.4 and 0.6) iplloader, containing the following MIPS assembly instructions (the jal instruction is not used because of the address length, instead the address is stored to a register using the load immediate instruction, then the jump register instruction is used to jump to it, assembly is used to artificially make the jump because older IPL blocks cannot contain an entrypoint value, the old iplloader instead jumps to 0x88400000 as an hardcoded entrypoint address):
	.set noreorder
	.global start
	.ent    start
    li      $25, 0xBFE01100
    jr      $25
    nop
   .end start
	.set reorder

This block will jump to 0xBFE01100 so you can use this block as if you were using a Pandora IPL block on the prototype iplloader, which saves you time from encrypting new IPLs every time you need to test a new build.

Note: There is no 0xBFC00100 IPL block for the prototype iplloader because they do not load IPL blocks there and you cannot use that address as it would overwrite the iplloader code itself which does not use a payload section/address and runs entirely from 0xBFC00000.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  BF BA C0 7F E8 0C F0 30 40 B5 50 8C C4 F7 92 D4  ¿ºÀ.è.ð0@µPŒÄ÷’Ô
00000030  33 FB 54 9F 47 D6 E3 74 7E 98 3D 88 EB 8A 29 8B  3ûTŸGÖãt~˜=ˆëŠ)‹
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 FF FF FF FF  ............ÿÿÿÿ
00000070  20 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  D2 0B 01 5C 71 91 B2 19 78 09 56 E6 10 1F 93 54  Ò..\q‘².x.Væ..“T
000000B0  96 AC 78 2A 81 2D 17 79 F9 59 31 93 A0 A5 70 21  –¬x*.-.yùY1“ ¥p!
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  • IPL Block for 0.7.0 and later (up to 2.7.1) iplloader, containing the previously mentioned jr MIPS assembly instruction to address 0xBFE01100

This IPL block has been tested successfully on 2.6.0 and 2.7.1 kbooti.

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  00 8F B0 52 CB AE 94 F9 04 D8 30 3E 6D 21 9B 91  ..°RË®”ù.Ø0>m!›‘
00000010  D8 F6 D0 17 AD 37 05 E2 B0 8B 2C 5E D3 0F 73 7A  ØöÐ..7.â°‹,^Ó.sz
00000020  45 B0 6E 50 5F 46 10 7A 0A F2 0B 77 15 66 C4 80  E°nP_F.z.ò.w.fÄ€
00000030  CB 15 C4 B4 21 63 EB 7A 95 BF 7D 3D 6B 6E A3 C2  Ë.Ä´!cëz•¿}=kn£Â
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  20 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  66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E  féKÔïŠ,;ˆLúYÊ4+.
000000A0  B3 F4 93 52 DB 8E E4 99 4F 36 FA C0 71 86 F4 FE  ³ô“RÛŽä™O6úÀq†ôþ
000000B0  2E B1 77 5A 43 FE 8F DE AB 1D 80 95 87 B8 14 7D  .±wZCþ.Þ«.€•‡¸.}
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

All these IPL blocks have been properly tested and are confirmed to be working (the Devkit blocks have been successfully tested on kbooti 0.7.0 and 0.9.0, only the last one with using the jr instruction works up to kbooti 2.7.1).

These are available in binary format here: download link.

The 0xBFD00100 version of these blocks work as-is by replacing the time attacked forged block with the properly encrypted ones supplied. The 0xBFE01100 and 0xBFCD00100 version (which only works on Development Tool units), may require you to rebuild/recompile your custom IPLs using 0xBFE01100 or 0xBFCD00100 as the entrypoints respectively, as well as using a modified iplboot because the one used by retail custom IPLs uses iplloader hardcoded addresses. It may be wiser to rebuild it as a fully valid IPL instead using ipltool [6], although using the Pandora compatible IPL block instead would allow you to port retail custom IPL projects on devkit with minimal efforts.

Keep in mind that under normal circumstances neither the Memory Stick nor the NAND devices are initialized by the DTP-T1000 iplloader. Reading or writing to and from either of these devices will require you to add the initialization routine to your IPL (most likely within your iplboot binary).

The IPL SDK (available here: [7]) contains full low-level driver implementation for both devices which you can use in your projects.