Making Isolated SPU Modules and Loaders: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
|||
(29 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:OtherOS]] | |||
=Introduction= | =Introduction= | ||
Line 5: | Line 6: | ||
=Tools= | =Tools= | ||
* My Debian LiveCD has all tools you will need. | |||
* See http://www.ps3devwiki.com/wiki/Debian_LiveCD | |||
==SPU GCC Compiler== | ==SPU GCC Compiler== | ||
* You need SPU GCC compiler to compile your code and create binary version of it. | * You need SPU GCC compiler to compile your code and create binary version of it. | ||
* On PS3 Debian, just install spu toolchain. | * On PS3 Debian, just install spu toolchain with aptitude. | ||
* You can also cross-compile SPU GCC toolchain for your Linux PC. | * You can also cross-compile SPU GCC toolchain for your Linux PC. | ||
* See http://gitorious.ps3dev.net/ps3linux/powerpc64-cross-compiler if you want to build SPU GCC cross-compiler. Just change in HOWTO target option from powerpc64-linux to spu-elf. | |||
==ps3tools== | ==ps3tools== | ||
Line 42: | Line 47: | ||
* First you need '''sb_iso_spu_module.self''' from your NOR/NAND flash or from PS3 update file. | * First you need '''sb_iso_spu_module.self''' from your NOR/NAND flash or from PS3 update file. | ||
< | {{Keyboard|content=<syntaxhighlight lang="bash"> | ||
# compile your SPU code | # compile your SPU code | ||
Line 84: | Line 89: | ||
# entry point is 0x880 which is in first program segment at file offset 0x100 | # entry point is 0x880 which is in first program segment at file offset 0x100 | ||
# now we kill all old code with 0s before we put our code there. | # now we kill all old code and data with 0s before we put our code there. | ||
# seek parameter is the offset of the first program segment. | # seek parameter is the offset of the first program segment. | ||
# count parameter is the sum of the offset of the last program segment plus its size and | # count parameter is the sum of the offset of the last program segment plus its size and | ||
# minus the offset of the first program segmnet. | # minus the offset of the first program segmnet. | ||
# killing old code and data with 0s is a good idea because 0x00000000 means stop opcode. | |||
dd if=/dev/zero of=dump_ata_keys.elf bs=1 seek=$((0x100)) count=$((0x51b0 + 0x34 - 0x100)) conv=notrunc | dd if=/dev/zero of=dump_ata_keys.elf bs=1 seek=$((0x100)) count=$((0x51b0 + 0x34 - 0x100)) conv=notrunc | ||
Line 114: | Line 121: | ||
# we are done :) | # we are done :) | ||
# time to test it with spuisofs !!! | # time to test it with spuisofs !!! | ||
</ | |||
# mount spuisofs (we do it of course on PS3 Linux and not on PC) | |||
# you could use my Debian LiveCD e.g. which has all tools you need | |||
sudo mount -t spuisofs none /mnt | |||
ls -l /mnt | |||
total 0 | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 12:12 app | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 12:12 arg1 | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 12:12 arg2 | |||
--w--w--w- 1 root root 0 Sep 7 12:12 cont | |||
-r--r--r-- 1 root root 0 Sep 7 12:12 info | |||
-rw-rw-rw- 1 root root 262144 Sep 7 12:12 ls | |||
-rw-rw-rw- 1 root root 131072 Sep 7 12:12 priv2 | |||
-rw-rw-rw- 1 root root 131072 Sep 7 12:12 problem | |||
--w--w--w- 1 root root 24 Sep 7 12:12 run | |||
-r--r--r-- 1 root root 4096 Sep 7 12:12 shadow | |||
# compile dump_ata_keys application | |||
tar xvzf dump_ata_keys.tar.gz | |||
cd dump_ata_keys | |||
make | |||
ls -l dump_ata_keys | |||
./dump_ata_keys | |||
usage: ./dump_ata_keys <self path> <eid4 path> | |||
# NOTE: you don't really need eid4 to run the application or to dump your ATA keys | |||
./dump_ata_keys ./dump_ata_keys.self ./eid4 | |||
spuisofs found at /mnt | |||
arg1 kernel virtual address d000000003375000 | |||
shadow: spe_execution_status 7 | |||
priv2: puint_mb_R 2 | |||
shadow: spe_execution_status b | |||
problem: spu_status_R 6660082 | |||
# here is important to check the stop code which is 0x666 :) | |||
# my dump_ata_keys.S code stops with stop code 0x666 when it's done | |||
# this way you can be really sure that your dump_ata_keys.self was correctly signed, | |||
# encrypted and accepted by isoldr | |||
# dump your ATA keys | |||
hexdump -C /mnt/arg1 | |||
</syntaxhighlight>}} | |||
=Example: Making dump_encdec_keys.self= | =Example: Making dump_encdec_keys.self= | ||
* First you need '''lv1ldr''' from your NOR/NAND flash or from PS3 update file. | * First you need '''lv1ldr''' from your NOR/NAND flash or from PS3 update file. | ||
{{Keyboard|content=<syntaxhighlight lang="bash"> | |||
# compile your SPU code | |||
spu-elf-gcc -c dump_encdec_keys.S | |||
ls -l dump_encdec_keys.o | |||
# convert your code to binary | |||
spu-elf-objcopy -O binary dump_encdec_keys.o dump_encdec_keys.bin | |||
ls -l dump_encdec_keys.bin | |||
# decrypt lv1ldr | |||
unself lv1ldr lv1ldr.elf | |||
ls -l lv1ldr.elf | |||
mv lv1ldr.elf dump_encdec_keys.elf | |||
# print program header of decrypted loader | |||
readelf -l dump_encdec_keys.elf | |||
Elf file type is EXEC (Executable file) | |||
Entry point 0x12c00 | |||
There are 3 program headers, starting at offset 52 | |||
Program Headers: | |||
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | |||
LOAD 0x000080 0x00000800 0x00000800 0x00000 0x0cd20 RW 0x80 | |||
LOAD 0x000100 0x00012c00 0x00012c00 0x1ca00 0x1ca00 R E 0x80 | |||
LOAD 0x01cb00 0x0002f600 0x0002f600 0x004f0 0x004f0 RW 0x80 | |||
Section to Segment mapping: | |||
Segment Sections... | |||
00 .unknown | |||
01 .unknown .unknown | |||
02 .unknown .unknown .unknown | |||
# entry point is 0x12c00 which is in second program segment at file offset 0x100 | |||
# now we kill all old code and data with 0s before we put our code there. | |||
# seek parameter is the offset of the second program segment. | |||
# count parameter is the sum of the offset of the last program segment plus its size and | |||
# minus the offset of the second program segment. | |||
# killing old code and data with 0s is a good idea because 0x00000000 means stop opcode. | |||
dd if=/dev/zero of=dump_encdec_keys.elf bs=1 seek=$((0x100)) count=$((0x1cb00 + 0x4f0 - 0x100)) conv=notrunc | |||
# after you filled out the SPU module with 0s, check it with spu-objdump | |||
spu-elf-objdump -d dump_encdec_keys.elf | |||
dump_encdec_keys.elf: file format elf32-spu | |||
Disassembly of section : | |||
00012c00 <>: | |||
... | |||
# now we copy our code to loader | |||
# seek parameter is the entry point offset in file | |||
dd if=dump_encdec_keys.bin of=dump_encdec_keys.elf bs=1 seek=$((0x100)) conv=notrunc | |||
# now build loader | |||
iso_rebuilder dump_encdec_keys.elf dump_encdec_keys.self lv1ldr | |||
# we are done :) | |||
# time to test it with spuldrfs !!! | |||
# mount spuldrfs (we do it of course on PS3 Linux and not on PC) | |||
# you could use my Debian LiveCD e.g. which has all tools you need | |||
sudo mount -t spuldrfs none /mnt | |||
ls -l /mnt | |||
total 0 | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf1 | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf2 | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf3 | |||
-r--r--r-- 1 root root 0 Sep 7 13:20 info | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 13:20 ldr | |||
-rw-rw-rw- 1 root root 262144 Sep 7 13:20 ls | |||
-rw-rw-rw- 1 root root 1048576 Sep 7 13:20 metldr | |||
-rw-rw-rw- 1 root root 131072 Sep 7 13:20 priv2 | |||
-rw-rw-rw- 1 root root 131072 Sep 7 13:20 problem | |||
--w--w--w- 1 root root 0 Sep 7 13:20 run | |||
-r--r--r-- 1 root root 4096 Sep 7 13:20 shadow | |||
# compile dump_encdec_keys application | |||
tar xvzf dump_encdec_keys.tar.gz | |||
cd dump_encdec_keys | |||
make | |||
ls -l dump_encdec_keys | |||
./dump_encdec_keys | |||
usage: ./dump_encdec_keys <metldr path> <ldr path> | |||
# NOTE: you will need your metldr | |||
./dump_encdec_keys ./metldr ./dump_encdec_keys.self | |||
spuldrfs found at /mnt | |||
buf1 kernel virtual address d000000003c48000 | |||
buf2 kernel virtual address d000000003d49000 | |||
priv2: puint_mb_R 1 | |||
problem: pu_mb_R 1 | |||
priv2: puint_mb_R 666 | |||
problem: spu_status_R 6660082 | |||
# here is important to check the stop code which is 0x666 :) | |||
# my dump_encdec_keys.S code stops with stop code 0x666 when it's done | |||
# this way you can be really sure that your dump_encdec_keys.self was correctly signed, | |||
# encrypted and accepted by metldr | |||
# dump your ENCDEC keys (not really, you have to calculate your ENCDEC keys) | |||
hexdump -C /mnt/buf2 | |||
</syntaxhighlight>}} | |||
{{Linux}}<noinclude>[[Category:Main]]</noinclude> |
Latest revision as of 02:03, 3 February 2014
Introduction[edit | edit source]
- E.g. to dump your ATA, ENCDEC or EID2 keys you have to make signed isolated SPU modules or loaders.
- This is a tutorial how to do it on Linux (it doesn't matter on PC or PS3).
Tools[edit | edit source]
- My Debian LiveCD has all tools you will need.
- See http://www.ps3devwiki.com/wiki/Debian_LiveCD
SPU GCC Compiler[edit | edit source]
- You need SPU GCC compiler to compile your code and create binary version of it.
- On PS3 Debian, just install spu toolchain with aptitude.
- You can also cross-compile SPU GCC toolchain for your Linux PC.
- See http://gitorious.ps3dev.net/ps3linux/powerpc64-cross-compiler if you want to build SPU GCC cross-compiler. Just change in HOWTO target option from powerpc64-linux to spu-elf.
ps3tools[edit | edit source]
- You need these tools to decrypt PS3 isolated SPU modules and loaders.
- You also need it to sign and encrypt your own SPU modules and loaders.
- self_rebuilder doesn't work properly with isolated SPU modules or loaders. Therefore, i made a new tool which works with isolated SPU modules and loaders. It's called iso_rebuilder and is a modified version of self_rebuilder.
- See my GIT repop: http://gitorious.ps3dev.net/ps3otheros/ps3tools
How To Test Isolated SPU Modules and Loaders[edit | edit source]
- I test my isolated SPU modules and loaders with PS3 Linux and spuisofs/spuldrfs Virtual File Systems.
spuisofs[edit | edit source]
- You can test with spuisofs isolated SPU modules which are decrypted by isoldr.
- You cannot test loaders with spuisofs.
- But spuisofs has the advantage that it's alot easier to execute isolated SPUs with it than with spuldrfs.
See http://www.ps3devwiki.com/wiki/Spuisofs
spuldrfs[edit | edit source]
- You can test with spuldrfs isolated SPU modules which are decrypted by isoldr and loaders which are decrypted by metldr.
- Use spuisofs if you want to execute isoldr SPUs, it's easier to do than with spuldrfs.
See http://www.ps3devwiki.com/wiki/Spuldrfs
Example: Making dump_ata_keys.self[edit | edit source]
- First you need sb_iso_spu_module.self from your NOR/NAND flash or from PS3 update file.
# compile your SPU code spu-elf-gcc -c dump_ata_keys.S ls -l dump_ata_keys.o # convert your code to binary spu-elf-objcopy -O binary dump_ata_keys.o dump_ata_keys.bin ls -l dump_ata_keys.bin # decrypt sb_iso_spu_module.self unself sb_iso_spu_module.self sb_iso_spu_module.elf ls -l sb_iso_spu_module.elf mv sb_iso_spu_module.elf dump_ata_keys.elf # print program header of decrypted SPU module readelf -l dump_ata_keys.elf Elf file type is EXEC (Executable file) Entry point 0x880 There are 3 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000100 0x00000880 0x00000880 0x05040 0x05040 R E 0x80 LOAD 0x005180 0x00005900 0x00005900 0x00030 0x001c0 RW 0x80 NOTE 0x0051b0 0x00000000 0x00000000 0x00034 0x00000 R 0x10 Section to Segment mapping: Segment Sections... 00 .unknown .unknown 01 .unknown .unknown .unknown .unknown 02 .unknown # entry point is 0x880 which is in first program segment at file offset 0x100 # now we kill all old code and data with 0s before we put our code there. # seek parameter is the offset of the first program segment. # count parameter is the sum of the offset of the last program segment plus its size and # minus the offset of the first program segmnet. # killing old code and data with 0s is a good idea because 0x00000000 means stop opcode. dd if=/dev/zero of=dump_ata_keys.elf bs=1 seek=$((0x100)) count=$((0x51b0 + 0x34 - 0x100)) conv=notrunc # after you filled out the SPU module with 0s, check it with spu-objdump spu-elf-objdump -d dump_ata_keys.elf dump_ata_keys.elf: file format elf32-spu Disassembly of section : 00000880 <>: ... # now we copy our code to SPU module # seek parameter is the entry point offset in file dd if=dump_ata_keys.bin of=dump_ata_keys.elf bs=1 seek=$((0x100)) conv=notrunc # now build isolated SPU module iso_rebuilder dump_ata_keys.elf dump_ata_keys.self sb_iso_spu_module.self # we are done :) # time to test it with spuisofs !!! # mount spuisofs (we do it of course on PS3 Linux and not on PC) # you could use my Debian LiveCD e.g. which has all tools you need sudo mount -t spuisofs none /mnt ls -l /mnt total 0 -rw-rw-rw- 1 root root 1048576 Sep 7 12:12 app -rw-rw-rw- 1 root root 1048576 Sep 7 12:12 arg1 -rw-rw-rw- 1 root root 1048576 Sep 7 12:12 arg2 --w--w--w- 1 root root 0 Sep 7 12:12 cont -r--r--r-- 1 root root 0 Sep 7 12:12 info -rw-rw-rw- 1 root root 262144 Sep 7 12:12 ls -rw-rw-rw- 1 root root 131072 Sep 7 12:12 priv2 -rw-rw-rw- 1 root root 131072 Sep 7 12:12 problem --w--w--w- 1 root root 24 Sep 7 12:12 run -r--r--r-- 1 root root 4096 Sep 7 12:12 shadow # compile dump_ata_keys application tar xvzf dump_ata_keys.tar.gz cd dump_ata_keys make ls -l dump_ata_keys ./dump_ata_keys usage: ./dump_ata_keys <self path> <eid4 path> # NOTE: you don't really need eid4 to run the application or to dump your ATA keys ./dump_ata_keys ./dump_ata_keys.self ./eid4 spuisofs found at /mnt arg1 kernel virtual address d000000003375000 shadow: spe_execution_status 7 priv2: puint_mb_R 2 shadow: spe_execution_status b problem: spu_status_R 6660082 # here is important to check the stop code which is 0x666 :) # my dump_ata_keys.S code stops with stop code 0x666 when it's done # this way you can be really sure that your dump_ata_keys.self was correctly signed, # encrypted and accepted by isoldr # dump your ATA keys hexdump -C /mnt/arg1
Example: Making dump_encdec_keys.self[edit | edit source]
- First you need lv1ldr from your NOR/NAND flash or from PS3 update file.
# compile your SPU code spu-elf-gcc -c dump_encdec_keys.S ls -l dump_encdec_keys.o # convert your code to binary spu-elf-objcopy -O binary dump_encdec_keys.o dump_encdec_keys.bin ls -l dump_encdec_keys.bin # decrypt lv1ldr unself lv1ldr lv1ldr.elf ls -l lv1ldr.elf mv lv1ldr.elf dump_encdec_keys.elf # print program header of decrypted loader readelf -l dump_encdec_keys.elf Elf file type is EXEC (Executable file) Entry point 0x12c00 There are 3 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000080 0x00000800 0x00000800 0x00000 0x0cd20 RW 0x80 LOAD 0x000100 0x00012c00 0x00012c00 0x1ca00 0x1ca00 R E 0x80 LOAD 0x01cb00 0x0002f600 0x0002f600 0x004f0 0x004f0 RW 0x80 Section to Segment mapping: Segment Sections... 00 .unknown 01 .unknown .unknown 02 .unknown .unknown .unknown # entry point is 0x12c00 which is in second program segment at file offset 0x100 # now we kill all old code and data with 0s before we put our code there. # seek parameter is the offset of the second program segment. # count parameter is the sum of the offset of the last program segment plus its size and # minus the offset of the second program segment. # killing old code and data with 0s is a good idea because 0x00000000 means stop opcode. dd if=/dev/zero of=dump_encdec_keys.elf bs=1 seek=$((0x100)) count=$((0x1cb00 + 0x4f0 - 0x100)) conv=notrunc # after you filled out the SPU module with 0s, check it with spu-objdump spu-elf-objdump -d dump_encdec_keys.elf dump_encdec_keys.elf: file format elf32-spu Disassembly of section : 00012c00 <>: ... # now we copy our code to loader # seek parameter is the entry point offset in file dd if=dump_encdec_keys.bin of=dump_encdec_keys.elf bs=1 seek=$((0x100)) conv=notrunc # now build loader iso_rebuilder dump_encdec_keys.elf dump_encdec_keys.self lv1ldr # we are done :) # time to test it with spuldrfs !!! # mount spuldrfs (we do it of course on PS3 Linux and not on PC) # you could use my Debian LiveCD e.g. which has all tools you need sudo mount -t spuldrfs none /mnt ls -l /mnt total 0 -rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf1 -rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf2 -rw-rw-rw- 1 root root 1048576 Sep 7 13:20 buf3 -r--r--r-- 1 root root 0 Sep 7 13:20 info -rw-rw-rw- 1 root root 1048576 Sep 7 13:20 ldr -rw-rw-rw- 1 root root 262144 Sep 7 13:20 ls -rw-rw-rw- 1 root root 1048576 Sep 7 13:20 metldr -rw-rw-rw- 1 root root 131072 Sep 7 13:20 priv2 -rw-rw-rw- 1 root root 131072 Sep 7 13:20 problem --w--w--w- 1 root root 0 Sep 7 13:20 run -r--r--r-- 1 root root 4096 Sep 7 13:20 shadow # compile dump_encdec_keys application tar xvzf dump_encdec_keys.tar.gz cd dump_encdec_keys make ls -l dump_encdec_keys ./dump_encdec_keys usage: ./dump_encdec_keys <metldr path> <ldr path> # NOTE: you will need your metldr ./dump_encdec_keys ./metldr ./dump_encdec_keys.self spuldrfs found at /mnt buf1 kernel virtual address d000000003c48000 buf2 kernel virtual address d000000003d49000 priv2: puint_mb_R 1 problem: pu_mb_R 1 priv2: puint_mb_R 666 problem: spu_status_R 6660082 # here is important to check the stop code which is 0x666 :) # my dump_encdec_keys.S code stops with stop code 0x666 when it's done # this way you can be really sure that your dump_encdec_keys.self was correctly signed, # encrypted and accepted by metldr # dump your ENCDEC keys (not really, you have to calculate your ENCDEC keys) hexdump -C /mnt/buf2