Wednesday, 9 July 2014

Just a simple shell disassembler for ppc64 elfs

I had more the an hour and i decided to write a concept of shell disassembler for the ppc64 elfs, and i used capstone disassembler (capstone [git])

this was the result:







An advice: DO NOT USE MY CODE! it's buggy and has errors!

[Download][git] https://github.com/wargio/disassemble_ppc64

Friday, 7 March 2014

AES on the Wii U bootrom

[Update 2]

Ok, it's not an 'obfuscation' as i said. I'm an idiot! as a man, i am, i make mistakes. This post was about the problem i had on finding where the aes function was called, and i just wanted to share with the people!
Errors makes people happy! :D

So these are the correct things: They save some addresses into the memory somewhere after this offset 0xE0000000 then when they call a function to save the address of the AES implementation, then they call it via a function as a function pointer.



AES obfuscation on the Wii U bootrom

I've read the whole bootrom code and i have to admit, that big N has done a good job on hiding where and how it calls the AES code.
Finding the AES implementation is easy, it's just before the ancast header check function and after the most useless function.
Finding how the AES implementation is called, is a little bit hard, for two reasons:
  • there are no cross references in the text segment; This means you will not see something like:
    • bl AES_Decrypt
  • there are no addresses saved in the data segment:
    • AES_offset: .long AES_Decrypt
So how to find it? you have to read the code, because the value is hardcoded and saved into a memory on an unknown address (like 0xE0000000); then a function will load that addresses to the count (CTR) register and jumps there.
I'll make an example:


How normally should be:


#---------------------------------------------
AES_Decrypt: # (r3, r4, r5)
.set LR_old,  4
 mfspr     r0, LR            #  r0 = LR
 stwu      r1, -4(r1)        #  SP = SP-4
 stw       r0, 4+LR_old(r1)  # *SP = r0
 # AES code
 lwz       r0, 4+LR_old(r1)  # r0 = *SP
 addi      r1, r1, 4         # SP = SP+4
 mtspr     LR, r0            # LR = r0
 blr 
#---------------------------------------------
main: 
.set LR_old,  4
 mfspr     r0, LR            #  r0 = LR
 stwu      r1, -4(r1)        #  SP = SP-4
 stw       r0, 4+LR_old(r1)  # *SP = r0

 # Fill r3, r4, r5
 lis       r5, 0x20F0        # key
 lis       r3, 0x2100        # AES Context
 li        r4, 0x0080        # key size = 128
 bl        AES_Decrypt

 lwz       r0, 4+LR_old(r1)  # r0 = *SP
 addi      r1, r1, 4         # SP = SP+4
 mtspr     LR, r0            # LR = r0
 blr 

How is obfuscated on the Wii U:

#---------------------------------------------
set_AES_call:
 lis       r30, -0x2000       # 0xE0000000
 li        r31,  0x0010       # relative location
 stw       r31,  0x000A (r30) # 0xE000000A
 blr 
#---------------------------------------------
AES_Decrypt: # (r3, r4, r5)
.set LR_old,  4
 mfspr     r0, LR             #  r0 = LR
 stwu      r1, -4(r1)         #  SP = SP-4
 stw       r0, 4+LR_old(r1)   # *SP = r0
 # AES code
 lwz       r0, 4+LR_old(r1)   # r0 = *SP
 addi      r1, r1, 4          # SP = SP+4
 mtspr     LR, r0             # LR = r0
 blr 
#---------------------------------------------
call_AES: # (r3, r4, r5)
.set LR_old,  4
 mfspr     r0, LR             #  r0 = LR
 stwu      r1, -4(r1)         #  SP = SP-4
 stw       r0, 4+LR_old(r1)   # *SP = r0
 lis       r30, -0x2000       # 0xE0000000
 lwz       r0 ,  0x000A (r30) # 0xE000000A
 nop
 mtspr     CTR, r0            # CTR = r0
 nop 
 bctrl                        # jump to AES
 lwz       r0, 4+LR_old(r1)   # r0 = *SP
 addi      r1, r1, 4          # SP = SP+4
 mtspr     LR, r0             # LR = r0
 blr  
#---------------------------------------------
main: 
.set LR_old,  4
 mfspr     r0, LR             #  r0 = LR
 stwu      r1, -4(r1)         #  SP = SP-4
 stw       r0, 4+LR_old(r1)   # *SP = r0
 # Obfuscate AES
 bl        set_AES_call
 
 # Fill r3, r4, r5
 lis       r5, 0x20F0        # key
 lis       r3, 0x2100        # AES Context
 li        r4, 0x0080        # key size = 128
 bl        call_AES
 
 lwz       r0, 4+LR_old(r1)  # r0 = *SP
 addi      r1, r1, 4         # SP = SP+4
 mtspr     LR, r0            # LR = r0
 blr 

The last thing:

I had a lot of fun on reverse the whole bootrom. You'll find interesting stuff, there (but not keys :P).

[Update 1]

Some said that it's a function pointer. Yes, it's true, but the 'obfuscation' that i'm talking about is quite different.
When you create a function pointer, you can have the following things:
#---------------------------------------------
AES_Decrypt: # (r3, r4, r5)
.set LR_old,  4
 mfspr     r0, LR             #  r0 = LR
 stwu      r1, -4(r1)         #  SP = SP-4
 stw       r0, 4+LR_old(r1)   # *SP = r0
 # AES code
 lwz       r0, 4+LR_old(r1)   # r0 = *SP
 addi      r1, r1, 4          # SP = SP+4
 mtspr     LR, r0             # LR = r0
 blr 
#---------------------------------------------
#stored in the data segment
.long AES_Decrypt

#stored in register
lis       r0,     AES_Decrypt@h
addi      r0, r0, AES_Decrypt@l

On the Wii U ths is a little bit different. The address is stored in the register, but it's relatively static to the copy of the bootrom, not to the bootrom itself. this means, the addresses was coded by thinking that the rom was going to be loaded at another offset. In this simple way you obscurate partially of the code. There is no reason to make a function pointer that you are going to use just once. Function pointers are useful, if you are going to use callbacks, arrays, etc., but not in this case. In fact if you change the loading offset to the 'suitably one' of the bootrom you will get the cross references..

By the idiot who has wrote a stupid thing :P

Tuesday, 14 January 2014

Reversing Wii U Executables

First thing to say, Wii U uses Executable and Linkable Format (ELF) with dynamic linking (since Wii U has a real OS), but they are different from the normal ones:

  • Wii U libraries are called RPL
  • Wii U executables are called RPX, but these are actually RPL.
The only difference between RPX and RPL is that the first one has the main entry point, but both are ELFs.Ok, so this is what i understood about the header:
/* Total size 0x500 -> elf + section table */
typedef struct __cafe_elf {
 uint8_t  e_ident[0x10]; // {0x7f,0x45,0x4c,0x46, <-- 'elf'
       // 0x01,     <-- one
       // 0x01,0x05,    <-- sdk version ?
       // 0xca,0xfe,    <-- 0xcafe
       // 0x00,0x00, ... ,0x00} 
 uint16_t e_type;  // 0xfe01 = rpl
 uint16_t e_machine;  // 0x0014 PPC
 uint32_t e_version;  // 0x00000001
 uint32_t e_entry;  // 0x02000000
 uint32_t e_phoff;  // 0x00000000
 uint32_t e_shoff;  // 0x00000040
 uint32_t e_flags;  // 0x00000000
 uint16_t e_ehsize;  // 0x0032 (54)
 uint16_t e_phentsize; // 0x0000
 uint16_t e_phnum;  // 0x0000
 uint16_t e_shentsize; // 0x0028 (40)
 uint16_t e_shnum;  // 0x0015 (19)
 uint16_t e_shstrndx; // 0x0012 (16)
 uint8_t  _pad[0xC];  // zero filled
 uint8_t  zero[0x28]; // zero filled
 uint32_t one_0;   // 0x00000001
 uint32_t one_1;   // 0x00000001
} cafe_elf;


typedef struct __cafe_elf_section_tbl {
 uint32_t flags;  // 0x08000006 <-- example
      // 0x08000000 <-- z
      // 0x00000001 <-- w
      // 0x00000002 <-- a
      // 0x00000004 <-- x
 uint32_t address; // 0x02000000 <-- memory addr (.text)
 uint32_t offset; // 0x0019D740 <-- file offset
 uint32_t size;  // 0x00003EC8 <-- compressed size
 uint32_t data0;  // 0x00000000 <-- unknown
 uint32_t data1;  // 0x00000000 <-- unknown
 uint32_t align;  // 0x00000020 (32) <-- data align
 uint32_t data3;  // 0x00000000 <-- unknown
 uint32_t data4;  // 0x00000007 <-- unknown
 uint32_t data5;  // 0x80000001 <-- unknown
} cafe_elf_section_tbl;
Each section is compressed through ZLIB and has this structure:
typedef struct __cafe_elf_section_data {
 uint32_t decompressed_size;
 uint16_t zlib_compression_hdr;
 uint8_t data[];
} cafe_elf_section_tbl;

Sunday, 20 October 2013

Twitch Streamer for Linux

This Screenshot comes from a linux streaming session.


Since my friend asked me to help him to stream on twitch.tv from linux, i've decided to write something really user-friendly that can be used by everyone. so here it is: Twitch-Streamer-Linux (github)
This little script allows you to stream on Twitch like the non-free apps on windows. You can choose the quality and if stream with the webcam or not.

There is an HOW-TO on the Readme (LINK). if you have any question, just write here or on github.

have fun!

[UPDATE 1]

i have added also some flags to get "Excellent" as quality on Twitch. now works as good as non-free programs :D

Friday, 11 October 2013

Unofficial scetool 0.3.0

I have added an option to add a custom path for the "data" folder.

scetool -v --data-path=$(PS3DEV)/bin/data --sce-type=SELF --compress-data=TRUE --skip-sections=TRUE --key-revision=1 --self-auth-id=1010000001000003 --self-vendor-id=01000002 --self-type=NPDRM --self-app-version=0001000000000000 --self-fw-version=0003004100000000 --np-content-id=UP0001-RSX00004_00-0000000000000000 --np-license-type=FREE --np-app-type=EXEC --np-real-fname=EBOOT.BIN --encrypt EBOOT.elf EBOOT.BIN

https://github.com/wargio/scetool

Thursday, 18 July 2013

Playstation 4 Update Package list is online, but no PUP




Hey readers, as i posted a loooooong time ago on the Ps3 dev wiki (then moved by Euss on the PS4 Dev Wiki) the ps4 update list is finally online!! (yes, servers was already online, but not the files.)

http://fjp01.ps4.update.playstation.net/update/ps4/list/jp/ps4-updatelist.xml

what we can expect inside the PS4 firmware? well, we can get some information by reading the list (don't take my words as 'ABSOLUTELY TRUE', mine are just guesses :D )


<?xml version="1.0" ?>
<update_data_list>
  <region id="jp" >
    <force_update>
      <system level0_system_version="00.000.000" level1_system_version="00.000.000" />
    </force_update>
    <system_pup version="00.000.000" label="0.000" >
      <update_data update_type="full" >
 <image size="1" >http://djp01.ps4.update.playstation.net/update/ps4/image/xxxx/PS4UPDATE.PUP?dest=jp</image>
      </update_data>
    </system_pup>
    <recovery_pup type="default" >
      <preinst_pup  version="00.000.000" />
      <system_pup version="00.000.000" label="0.000" />
      <system_ex_pup id="0" version="00.000.000.000" label="0.000.000.000" />
      <image size="1">http://djp01.ps4.update.playstation.net/update/ps4/image/xxxx/PS4UPDATE.PUP?dest=jp</image>
    </recovery_pup>
  </region>
</update_data_list>

As you can see, there is a "full update" and a "preinst update", called also "recovery pup". 

probably in the future the structure of the PUP link will be this one:

http://d<TLD>01.ps4.update.playstation.net/update/ps4/image/YYYY_MMDD>/pre_<md5>/PS4UPDATE.PUP?dest=<TLD>
(TLD=2 region letter abbreviation, YYYY_MMDD is release date, md5 is 22-digits long HASH)
 

Monday, 20 May 2013

[Update] Recycling Heatsinker and Fans for a Raspberry Pi


It's known that hardware sometime is expensive and most of the time we buy things that we already own. That's why i'm writing this: i had 2 PC broken by a lightning and one that stopped working by itself for unknown reasons, but this was very very old, so yesterday i have dismantled these old PCs. Most of the pieces were old and not compatible with newer desktops except some hardware like heat sinkers ,fans and some cables. Most of the fans on desktops works from 0.5A to 0.1A at 12V so by knowing your hardware you can add them to your desktop.
While i was disassembling the last pc, i found 3 really useful fans and a great heat sinker for my Raspberry Pi:
This is the heat sinker



and the 3 fans.

Now the heat sinker can be added without needing any skills; you just need it and the thermal paste.
Fans: first you need to check how much current it will draw with 5V (it MUST draw less then 300mA on Rev. B and less then 500mA on Rev. A according with the Wiki page http://elinux.org/Rpi_Low-level_peripherals#Power_pins).
second thing to do is checking the GPIO pins that you need:


Be very careful with the 5 V pins P1-02 and P1-04, because if you short 5 V to any other P1 pin you may permanently damage your Raspberry Pi.

then you can simply use some cables taken from the old pc connectors (like jtag cables) to connect your fan to your Rasp Pi.
As you can see it works perfectly on my Raspberry Pi :) 



according to the "vcgencmd measure_temp" command, the temperature of my raspberry after 3 hours of works (i use it as a torrent client) is temp=27.7'C, pretty low :)

[Update]

For those asking what fan i have used, mine is this one:

  DC 12V, 0.45 A.

as always, sorry for my bad english, i'm Italian :D