Editing SPU Isolated Modules Reverse Engineering

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
== anergistic ==
[[Category:Software]]
 
Using a static analysis (IDA) could give you a good view of what the program does, but sometimes you want to know what a program does in real time and how it reacts to different parameters, this is where anergistics becomes a powerful tool. It simulates the SPU including its communication, and storage.
 
=== Current repos===
 
*https://github.com/kraiskil/anergistic.git
*http://git.gitbrew.org/ps3/anergistic.git/
*https://github.com/psfree/anergistic
*<span style="text-decoration: line-through;">http://foxbrew.org/git/anergistic.git/</span>
*<span style="text-decoration: line-through;">http://git.fail0verflow.com/?p=anergistic.git</span>
 
=== Usage ===
 
anergistic can be launched in two different modes, one that '''only emulates''' (runs) the program through the SPU and the the other that lets you '''debug''' the process through gdb
 
==== only emulate ====
 
{{keyboard|content=<syntaxhighlight lang="bash">./anergistic spu_elf_name.elf</syntaxhighlight>}}
 
this mode runs an elf with all the parameters and actions defined on main.c, channel.c a
 
==== debug ====
 
terminal 1
{{keyboard|content=<syntaxhighlight lang="bash">./anergistic -g1234 spu_elf_name.elf</syntaxhighlight>}}
 
simulate debug server in the local host on port 1234
 
terminal 2
{{keyboard|content=<syntaxhighlight lang="bash">
spu-gdb spu_elf_name.elf
(gdb)target remote :1234
</syntaxhighlight>}}
 
connect to the local host on port 1234
 
(gdb)help will give you information of the command available
 
==== Documentation ====
 
*http://publib.boulder.ibm.com/infocenter/ieduasst/stgv1r0/topic/com.ibm.iea.cbe/cbe/1.0/LinuxOnCell/L2T1H1_31_LinuxonCellToolchainGDB.pdf
*SPU specific commands
**http://sourceware.org/gdb/onlinedocs/gdb/SPU.html
 
this mode performs the same as above but lets you debug the process through gdb
 
=== Customizations ===
 
See example below.
 
'''Running in aim_spu_module anergistic'''
 
=== Problems ===
 
==== Connection problem ====
 
when in debugger mode
<pre>
Waiting for gdb to connect...
Client connected.
recv failed: Success
</pre>
 
==== Solution ====
 
Use spu-gdb.
 
=== Tools ===
 
[http://pastie.org/2810870 gnuify_ida.pl][http://paste.ubuntu.com/25615421/ mirror]
 
Use this to convert IDA disassembly into a format suitable for GNU AS. Literals in IDA are unsigned while AS expects signed literals. Conversion of literals is a work in progress.
 
== Loading Isolated Modules in GameOS ==
 
This code kinda represents how GameOS applications load and execute isolated SPU SELFs. For example: psp emulator.
 
<source lang="C">
  sys_spu_initialize(1,1);
  syscall(230, sys_spu_t *id,img &iso_spuSCEself,void *arg,0,0,0); //sys_isolated_spu_create
  sys_ppu_thread_create(sys_ppu_thread_t *thread_id,void* iso_spu_handler,sys_spu_t *id, 0x64, 0x1000, 2,"iso_spu_handler");
  syscall(233, sys_spu_t *id,2,0,sys_interrupt_tag_t intrtag);  //sys_iso_spu_create_interrupt_tag
  sys_interrupt_thread_establish(sys_interrupt_thread_handle_t *ih,sys_interrupt_tag_t intrtag,sys_ppu_thread_t t_id,
  sys_spu_t id,0);
  syscall(234, sys_spu_t *id,2,7); //sys_iso_spu_set_int_mask
  syscall(232, sys_spu_t *id);    //sys_iso_spu_start
  ...
 
  iso_spu_handler(...) {
  syscall(237, sys_spu_t id,2,void *out1);  // sys_iso_spu_get_int_stat
  syscall(240, void *out2, out1);          // sys_iso_spu_mmio_read / sys_isolated_spu_read_puint_mb ?
  syscall(236, sys_spu_t id,2, out1)        // sys_iso_spu_set_int_stat
  sys_interrupt_thread_eoi()
  }
</source>
 
== aim_spu_module ==
== aim_spu_module ==
 
It is used to retrieve the device type, device id, open psid and the pscode from the EID0 data that is passed in.
It is used to retrieve the device type, Device Id, OpenPSID and the PsCode from the EID0 data that is passed in.


=== Debug messages ===
=== Debug messages ===
{| class="wikitable"
{| class="wikitable"
! colspan="2" | Address !! rowspan="2" | Message
! colspan="2" | Address !! rowspan="2" | Message
|-
|-
! ?&nbsp;3.41&nbsp;? !! 355&nbsp;CEX
! ? 3.41 ? !! 355 CEX
|-
|-
| 0x36f0 || 0x3570 || "(spu)start aim spu module!\n"
| 0x36f0 || 0x3570 || "(spu)start aim spu module!\n"
Line 115: Line 17:
| 0x3790 || 0x3610 || "(spu) PU DMA area size is not equall to AIM_DMA_SIZE\n"
| 0x3790 || 0x3610 || "(spu) PU DMA area size is not equall to AIM_DMA_SIZE\n"
|}
|}
This messages are DMAed to the ppu if a debug output address is specified.


These messages are sent via DMA to the PPU if a debug output address is specified.


=== Data ===
=== Data ===
{| class="wikitable"
{| class="wikitable"
! colspan="2" | Address !! rowspan="2" | Message
! colspan="2" | Address !! rowspan="2" | Message
|-
|-
! ?&nbsp;3.41&nbsp;? !! 355&nbsp;CEX
! ? 3.41 ? !! 355 CEX
|-
|-
| 0x37e0 || - || Reference Tool fallback IDPS
| 0x37e0 || - || Reference tool fallback IDPS
|-
|-
| 0x37f0 - ... || 0x3650 - ... || Start of [[Keys#aim_spu_module_Keys|aim_spu_module keys]]
| 0x37f0 - ... || 0x3650 - ... || Start of EID keys
|-
|-
| 0x3ac0 || 0x3870 || AES sbox (16*16 bytes)
| 0x3ac0 || 0x3870 || AES sbox (16*16 bytes)
Line 133: Line 35:
| 0x3c70 || 0x3a20 || AES inverse sbox (16*16 bytes)
| 0x3c70 || 0x3a20 || AES inverse sbox (16*16 bytes)
|}
|}


=== Functions ===
=== Functions ===
{| class="wikitable"
{| class="wikitable"
! colspan="2" | Address !! rowspan="2" | Name !! rowspan="2" | Parameters !! rowspan="2" | Info
! Address !! Name !! Parameters !! Info
|-
! &nbsp;3.41&nbsp; CEX/DEX !! 355&nbsp;CEX
|-
|-
| 0x9e0 ||  || stop_func || unknown || Stops the module execution with various stop codes.
| 0x9e0 || stop_func || unknown || Stops the module execution with various stop codes.
|-
|-
| 0xa18 ||  || main_func || unknown || Main routine.
| 0xa18 || main_func || unknown || Main routine.
|-
|-
| 0xf18 ||  || response || unknown || Sends response to ppu over DMA.
| 0xf18 || response || unknown || Sends response to ppu over DMA.
|-
|-
| 0x1158 ||  || process_eid || unknown || Decrypts EID0.
| 0x1158 || process_eid || unknown || Decrypts EID0.
|-
|-
| 0x1438 ||  || prepare_print || unknown || Prepares debug output.
| 0x1438 || prepare_print || unknown || Prepares debug output.
|-
|-
| 0x1440 ||  || debug_print || unknown || As the name already states... (this outputs over DMA)
| 0x1440 || debug_print || unknown || As the name already states... (this outputs over DMA)
|-
|-
| 0x17f0 ||  || - || - || AES 1 Part of aes implementation.
| 0x17f0 || - || - || Part of aes implementation.
|-
|-
| 0x1c48 || || aes_encrypt_ecb || - || AES 2 Part of aes implementation.
| 0x1c48 || - || - || Part of aes implementation.
|-
|-
| 0x1df0 || || cellCryptoSpuAesCbcCfb128Decrypt || - || AES 3 Probably part of aes implementation.
| 0x1df0 || - || - || Probably part of aes implementation.
|-
|-
| 0x20f0 || || aes_omac1 || - || AES 4 Probably part of aes implementation.
| 0x20f0 || - || - || Probably part of aes implementation.
|-
|-
| 0x2300 || || aes_set_key_dec || - || AES 5 Probably part of aes implementation.
| 0x2300 || - || - || Probably part of aes implementation.
|-
|-
| 0x2418 || || aes_decrypt_ecb || - || AES 6 Part of aes implementation.
| 0x2418 || - || - || Part of aes implementation.
|-
|-
| 0x2608 || || aes_decrypt_ecb_aligned || - || AES 7 Part of aes implementation.
| 0x2608 || - || - || Part of aes implementation.
|-
|-
| 0x30c0 ||  || do_dma || ls_addr:$4, dma_effective_addr:$5, size:$6, tag_id:$7, unk0:$8, unk1:$9 || Used to dma data in and out of the isolated module's LS.
| 0x30c0 || do_dma || ls_addr:$4, dma_effective_addr:$5, size:$6, tag_id:$7, unk0:$8, unk1:$9 || Used to dma data in and out of the isolated module's LS.
|-
|-
| 0x3168 ||  || write_tag_mask_bit || mask_bit:$4 || Used to set a specific bit in MFC_WrTagMask.
| 0x3168 || write_tag_mask_bit || mask_bit:$4 || Used to set a specific bit in MFC_WrTagMask.
|}
|}


==== Disasm ====
==== Disasm ====
The complete disassembly is available at [http://pastebin.com/7vArGweJ].
The complete disassembly is available at [http://pastebin.com/7vArGweJ].


== Decrypting EID ==
=== Dumper iso.self ===
Is there one ?
=== Dumper Payload ===
* [https://web.archive.org/web/20150912102728/http://pastie.org/pastes/2101977 Dumper payload code]
* [http://paste.ubuntu.com/25615310/ mirror]
=== Running aim_spu_module in anergistic ===
* [https://web.archive.org/web/20150912053633/http://pastie.org/2000330 Partial code modified to run aim_spu_module]
* [http://paste.ubuntu.com/25615344/ mirror]
== isoldr ==
Loads, decrypts, runs isolated modules, and creates through AES the required key in LS 0x0.
=== Debug messages ===
This module doesn't contain debug messages.
=== Data ===
{| class="wikitable"
! colspan="2" | Address !! rowspan="2" | Message
|-
! ?&nbsp;3.41&nbsp;? !! 355&nbsp;CEX
|-
|-
| 0x34C40 - ... || 0x34d10 || Start of isoldr keys [[Keys#Modules]]
|-
| 0x35130 || 0x35050 || AES sbox (16*16 bytes)
|-
| 0x35300 || 0x35220 || AES inverse sbox (16*16 bytes)
|}
=== Functions ===
{| class="wikitable"
! colspan="2" | Address !! rowspan="2" | Name !! rowspan="2" | Parameters !! rowspan="2" | Info
|-
! ?&nbsp;3.41&nbsp;? !! 355&nbsp;CEX
|-
| 0x259E0 ||  || cleanup_jump_code || unknown || cleans all the registers and jump to the loader
|-
| 0x259E0 ||  || main_func || unknown || Main routine.
|-
| 0x346B0 ||  || write_tag_mask_bit || mask_bit:$4 || Used to set a specific bit in MFC_WrTagMask.
|-
| 0x27438 || || aes128_cbc_decrypt || ||
|-
| 0x27508 || || aes128_cbc_encrypt || ||
|-
| 0x29DC0 || || aes_ctr || ||
|-
| 0x2BB28 || || aes_set_key_enc || ||
|-
| 0x2C0D0 || || cellCryptoSpuAesCbcCfb128Encrypt || ||
|-
| 0x2C240 || || cellCryptoSpuAesCbcCfb128Decrypt || ||
|-
| 0x2C540 || || cellCryptoSpuAesCtr || ||
|-
| 0x2C8D0 || || aes_omac1 || ||
|-
| 0x2CAE0 || || sha1_buffer || ||
|-
| 0x2CB70 || || sha1_hmac_init || ||
|-
| 0x2CC70 || || sha1_hmac_update || ||
|-
| 0x2CC90 || || sha1_hmac_final || ||
|-
| 0x2CD28 || || sha1_hmac_buffer || ||
|-
| 0x2CDC8 || || aes_set_key_dec || ||
|-
| 0x2CEE0 || || aes_encrypt_ecb_aligned || ||
|-
| 0x2D7C0 || || aes_decrypt_ecb || ||
|-
| 0x2D9B0 || || aes_decrypt_ecb_aligned || ||
|-
| 0x2E450 || || sha1_init || ||
|-
| 0x2E4C8 || || sha1_update || ||
|-
| 0x2E700 || || sha1_final || ||
|-
| 0x2EA88 || || sha1_process || ||
|}
* [https://web.archive.org/web/20141118195818/http://pastie.org/2774207 REed functions names from FW 3.41 isoldr] (offsets relative to segment start).
* [http://paste.ubuntu.com/25615363/ mirror]




{{Reverse engineering}}<noinclude>[[Category:Main]]</noinclude>
=== Running in anergistic ===
-> http://pastie.org/2000330
Please note that all contributions to PS3 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS3 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)