Well this is going to be completely impromptu just like most other things I do, but...
I'd like it if this thread was kept clean, it's fine if it's only posted in every other day as long as all posts are adding new info
TODO: Loading IOSU and/or cafe2wii into IDA and more details about them cause I'm running out of steam
What you're looking for is the version for OSv10 for the firmware you're targetting, be it 5.3.2, 5.5.X, or something lower.
PPC Kernel
Binary Method
Basic Notes
Tables
Starting from 0xFFF00000, every 0x100 bytes is a new piece of code with null bytes in between, including numerous infinite loops, you'll have to convert these manually.
When an sc instruction is run, r0 is passed in for the syscall number. If a number is not divisible by 0x100, it goes to one of the fastcalls. 0xFFF00C00 handles fastcalls, and it'll go to 0xFFF021A0 + (num * 0x20). Because all normal syscalls are divisible by 0x100, it'll go to "fastcall 0", 0xFFF021A0 is a jump to 0xFFF01EC0, which is the table dispatcher for all "normal" syscalls.
Aaaand that's about all the farther I've gotten, next step would be to rename all the syscalls and translate them into C to look for possible bugs.
I'd like it if this thread was kept clean, it's fine if it's only posted in every other day as long as all posts are adding new info
TODO: Loading IOSU and/or cafe2wii into IDA and more details about them cause I'm running out of steam
Tools Usually Used
- OpenSSL is needed to decrypt the various binaries once you get them from NUS
- A hex editor, I use HxD even tho there are probably better ones
- Windows or Linux recommended
- The Interactive Disassembler, or "IDA" Pro, I am currently using 6.8 and I've also used 6.1 and 6.6 in the past, 6.1 is too outdated to have support for Paired Singles, the unique instructions that the Gamecube, Wii, and Wii U all use
- Once you've obtained a copy, you're gonna want to edit cfg/ppc.cfg with these Special Purpose Registers, should be all the ones the Wii U uses, put it right after the .default line and before the .pcc section so it's at the very start of the file, and change that default to .wiiu if you want
-
Code:
.wiiu SIMD=PAIRED PROFILE=EMBEDDED ;-------------------------------------- ; All registers for Wii U Espresso Processor spr xer 1 Integer Exception Register spr lr 8 Link Register spr ctr 9 Count Register spr dsisr 18 Data Storage Interrupt Status Register spr dar 19 Data Address Register spr dec 22 Decrementer spr sdr1 25 Storage Description Register 1 spr srr0 26 Machine Status Save/Restore Register 0 spr srr1 27 Machine Status Save/Restore Register 1 spr utbl 0x10C User-Mode Time Base Register (lower) spr utbu 0x10D User-Mode Time Base Register (upper) spr sprg0 0x110 General Special Purpose Register 0 spr sprg1 0x111 General Special Purpose Register 1 spr sprg2 0x112 General Special Purpose Register 2 spr sprg3 0x113 General Special Purpose Register 3 spr ear 0x11A External Access Register spr tbl 0x11C Time Base Register (lower) spr tbu 0x11D Time Base Register (upper) spr pvr 0x11F Processor Version Register spr ibat0u 0x210 Instruction BAT Register 0 (upper) spr ibat0l 0x211 Instruction BAT Register 0 (lower) spr ibat1u 0x212 Instruction BAT Register 1 (upper) spr ibat1l 0x213 Instruction BAT Register 1 (lower) spr ibat2u 0x214 Instruction BAT Register 2 (upper) spr ibat2l 0x215 Instruction BAT Register 2 (lower) spr ibat3u 0x216 Instruction BAT Register 3 (upper) spr ibat3l 0x217 Instruction BAT Register 3 (lower) spr dbat0u 0x218 Data BAT Register 0 (upper) spr dbat0l 0x219 Data BAT Register 0 (lower) spr dbat1u 0x21A Data BAT Register 1 (upper) spr dbat1l 0x21B Data BAT Register 1 (lower) spr dbat2u 0x21C Data BAT Register 2 (upper) spr dbat2l 0x21D Data BAT Register 2 (lower) spr dbat3u 0x21E Data BAT Register 3 (upper) spr dbat3l 0x21F Data BAT Register 3 (lower) spr ibat4u 0x230 Instruction BAT Register 4 (upper) spr ibat4l 0x231 Instruction BAT Register 4 (lower) spr ibat5u 0x232 Instruction BAT Register 5 (upper) spr ibat5l 0x233 Instruction BAT Register 5 (lower) spr ibat6u 0x234 Instruction BAT Register 6 (upper) spr ibat6l 0x235 Instruction BAT Register 6 (lower) spr ibat7u 0x236 Instruction BAT Register 7 (upper) spr ibat7l 0x237 Instruction BAT Register 7 (lower) spr dbat4u 0x238 Data BAT Register 4 (upper) spr dbat4l 0x239 Data BAT Register 4 (lower) spr dbat5u 0x23A Data BAT Register 5 (upper) spr dbat5l 0x23B Data BAT Register 5 (lower) spr dbat6u 0x23C Data BAT Register 6 (upper) spr dbat6l 0x23D Data BAT Register 6 (lower) spr dbat7u 0x23E Data BAT Register 7 (upper) spr dbat7l 0x23F Data BAT Register 7 (lower) spr ugqr0 0x380 User-Mode Graphics Quantization Register 0 spr ugqr1 0x381 User-Mode Graphics Quantization Register 1 spr ugqr2 0x382 User-Mode Graphics Quantization Register 2 spr ugqr3 0x383 User-Mode Graphics Quantization Register 3 spr ugqr4 0x384 User-Mode Graphics Quantization Register 4 spr ugqr5 0x385 User-Mode Graphics Quantization Register 5 spr ugqr6 0x386 User-Mode Graphics Quantization Register 6 spr ugqr7 0x387 User-Mode Graphics Quantization Register 7 spr uhid2 0x388 User-Mode Hardware Implementation-Dependent Register 2 spr uwpar 0x389 User-Mode Write Pipe Address Register spr udmau 0x38A User-Mode Direct Memory Access Register (upper) spr udmal 0x38B User-Mode Direct Memory Access Register (lower) spr gqr0 0x390 Graphics Quantization Register 0 spr gqr1 0x391 Graphics Quantization Register 1 spr gqr2 0x392 Graphics Quantization Register 2 spr gqr3 0x393 Graphics Quantization Register 3 spr gqr4 0x394 Graphics Quantization Register 4 spr gqr5 0x395 Graphics Quantization Register 5 spr gqr6 0x396 Graphics Quantization Register 6 spr gqr7 0x397 Graphics Quantization Register 7 spr hid2 0x398 Hardware Implementation-Dependent Register 2 spr wpar 0x399 Write Pipe Address Register spr dma_u 0x39A Direct Memory Access Register (upper) spr dma_l 0x39B Direct Memory Access Register (lower) spr ummcr0 0x3A8 User-Mode Monitor Mode Control Register 0 spr upmc1 0x3A9 User-Mode Performance-Monitor Counter Register 1 spr upmc2 0x3AA User-Mode Performance-Monitor Counter Register 2 spr usia 0x3AB User-Mode Sampled Instruction Address Register spr ummcr1 0x3AC User-Mode Monitor Mode Control Register 1 spr upmc3 0x3AD User-Mode Performance-Monitor Counter Register 3 spr upmc4 0x3AE User-Mode Performance-Monitor Counter Register 4 spr hid5 0x3B0 Hardware Implementation-Dependent Register 5 spr pcsr 0x3B2 spr scr 0x3B3 spr car 0x3B4 Cache Address Register spr bcr 0x3B5 spr wpsar 0x3B6 spr mmcr0 0x3B8 Monitor Mode Control Register 0 spr pmc1 0x3B9 Performance-Monitor Counter Register 1 spr pmc2 0x3BA Performance-Monitor Counter Register 2 spr sia 0x3BB Sampled Instruction Address Register spr mmcr1 0x3BC Monitor Mode Control Register 1 spr pmc3 0x3BD Performance-Monitor Counter Register 3 spr pmc4 0x3BE Performance-Monitor Counter Register 4 spr dcate 0x3D0 spr dcatr 0x3D1 spr dmatl0 0x3D8 spr dmatu0 0x3D9 spr dmatr0 0x3DA spr dmatl1 0x3DB spr dmatu1 0x3DC spr dmatr1 0x3DD spr pir 0x3EF Processor ID Register spr hid0 0x3F0 Hardware Implementation-Dependent Register 0 spr hid1 0x3F1 Hardware Implementation-Dependent Register 1 spr iabr 0x3F2 Instruction Address Breakpoint Register spr hid4 0x3F3 Hardware Implementation-Dependent Register 4 spr tdcl 0x3F4 Thermal Diode Calibration Register (Low?) spr dabr 0x3F5 Data Address Breakpoint Register spr l2cr 0x3F9 L2 Cache Control Register spr tdch 0x3FA Thermal Diode Calibration Register (High?) spr ictc 0x3FB Instruction Cache Throttling Control Register spr thrm1 0x3FC Thermal Management Register 1 spr thrm2 0x3FD Thermal Management Register 2 spr thrm3 0x3FE Thermal Management Register 3
- Note that this is only for the Espresso but since the Starbuck is ARM and this is ppc.cfg we don't need to worry about stuff being messed up
- Something to keep track of all your data EG Dropbox or MEGA so it doesn't get lost as easily
Obtaining decrypted binaries
What you're looking for is the version for OSv10 for the firmware you're targetting, be it 5.3.2, 5.5.X, or something lower.
- Get the Title ID from http://wiiubrew.org/wiki/Title_database
- Grab some program to download it, like this or this, and download/decrypt the files
- root.rpx, not sure its actual importance, it's RAMPID 1 after the kernel and most of the first .rodata section is just a giant zlib compressed file, on the original firmware it was a tga but it seems they changed up the format some time since then. Probably sets up userspace after the kernel initializes
- kernel.img is the Espresso's Kernel Ancast Image, which is what lets us gain more privileges on it to allow for custom memory mappings and starting our code before a program runs.
- As such, it needs the Espresso Ancast Key and IV (which I'm not sure the IV matters after a quick usage, only affects first 0x10 bytes, probably some sort of key check thing).
- Hopefully you have openssl installed for command line use, just cd folder and run "openssl enc -d -aes-128-cbc -nopad -K key -iv iv -in kernel.img -out kernel.d.img"
- run OpenSSL, specify decryption
- we want to use the AES algorithm with a 128 bit key using Cipher Block Chaining
- -nopad is needed for Windows, not sure about other OSes
- we specify the key, in this case the Espresso Ancast Key
- then the IV which you can either try to find or set to 0, zecoxao so kindly put it on his page on the PS3 Dev Wiki
- Then you specify the in and out files, I like using .d.img cause it keeps it short
- If it worked correctly, you should be able to open it in a hex editor (I use HxD), scroll down, and see plaintext and also lots of null bytes (00).
- Then you want to copy and drag to select the first 0x100 bytes and delete them, then save as some other filename, I'd suggest something like kernel.anc (ancast), kernel.bin, or kernel.ppc, it'll automatically detect as a binary file in IDA so it doesn't matter as long as you can find it
- fw.img or firmware.img is "IOSU" or the IOSU Ancast Image (even tho the entire file isn't IOS_KERNEL) that runs on the Starbuck after chainloaded from boot0 and boot1
- This will need the Starbuck Ancast Key and IV (not the common key)
- Again need to run "openssl enc -d -aes-128-cbc -nopad -K key -iv iv -in fw.img -out fw.d.img
- see kernel.img for what the command does
- This time you want to select everything up to the .ELF magic (including the 00 00 01 00 before it), should be at like 0x804.
- c2w.img or cafe2wii is in a different title so you'll need to go back to your NUS program and download OSv0 or OSv1, I'd stick with OSv0 though.
- It's also a Starbuck Ancast Image so use the same key and IV you used with fw.img, and it also contains an ELF
Loading into IDA
PPC Kernel
Binary Method
- If you haven't edited the ppc.cfg file, do that now with the code in "Tools Usually Used" above
- Open the binary file to bring up the GUI
- Scroll Processor type to PowerPC Big-endian [PPC] and click set
- Kernel Options 1
- Turn off "delete instructions with no xrefs"
- Also turn off "Use flirt signatures" since we don't have any anyways
- Turn on "create function" right after
- Turn off "Create stack variables" and "trace stack pointer"
- The rest should all be on
- Kernel Options 2
- Highly suggest turning off BOTH "Coagulate data segments" and "Coagulate code segments" further down, otherwise you'll have to do more cleanup
- Turn off "Automatically hide library functions" since there aren't any anyways
- Turn off "Check for unicode string", "comment anonymous library functions", "Multiple copy library function recognition", and especially "Create function tails", saves you a lot of headache when cleaning up
- Turn on "full stack pointer analysis"
- Turn off "truncate functions"
- Processor options
- If you want to compare binaries between versions, you'll want to keep "create subi functions" off for when you load the database into bindiff from zynamics
- Change instruction set support to "PS" for Paired Singles, if you don't have this you should probably obtain a newer version of IDA
- Turn off Server if you wish
- Hit OK, Disassembly memory organization
- ROM start address and loading address, if you deleted the first 0x100 bytes, should be 0xFFE00100, else 0xFFE00000, then hit OK again
- Might ask you about devices, just click wiiu and hit OK, turn off Memory layout, then hit OK again
- Then you can begin cleaning and exploring.
Let me estimate you got a decrypted binary file with readable text and call it decryptedbin.out.
And you want to create an elf file (decryptedbin.elf). Then use DevkitPPC executable ...
powerpc-eabi-objcopy -I binary -O elf32-powerpc -B powerpc --change-addresses=0xffe00000 --set-section-flags .data=code decryptedbin.out decryptedbin.elf
PPC Kernel Specifics
Basic Notes
- We only really need to worry about syscall_system at FFEAAA60 in 5.5.X because as long as we're running code thru the browser, that's all the ones it can access. Could use syscall_games at FFE85070 if someone ever made a game-based exploit
- As such, once we have a kernel exploit, we should install kern_read and kern_write in both of those so games can access those as well with TCPGecko
- Syscall tables are 0x100 words long, 00 thru FF
- IRQs and IPC are all documented on WiiUBrew, thanks MN1. The Processor Interface is also another good page to look at
Tables
- interrupt_data_tbl is at FFE84438 (table for next 3 tables)
- ints_masks is at FFE84624 (8 entries, 3 words each)
- dsp_irqs is at FFE84684 (8 entries, 3 words each)
- ipc_irqs is at FFE846E4 (10 entries, 3 words each)
- CodegenCopyAreas (???) is at FFE8475C
- unknown syscall table at FFE84850, most loader w/ two empty
- syscall_empty is at FFE84870
- syscall_RAMPID1 is at FFE84C70
- syscall_games is at FFE85070 (Might wanna use loadiine installer/launcher.h header as ref)
- syscall_loader is at FFE85470
- syscall_table is at FFEAAA40 (based on RAMPID, 0 is Kernel, 4 is Browser, 7 is Games)
- syscall_system is at FFEAAA60
- syscall_unknown at FFEAAE60 isn't linked to, previously KERN_SYSCALL_TBL for writing custom syscalls
- memmap_tbl is at FFEAB7A0 (0x24 before means 0x24 entries of 4 words, Virtual Address, Size, Physical Address, Flags)
Starting from 0xFFF00000, every 0x100 bytes is a new piece of code with null bytes in between, including numerous infinite loops, you'll have to convert these manually.
When an sc instruction is run, r0 is passed in for the syscall number. If a number is not divisible by 0x100, it goes to one of the fastcalls. 0xFFF00C00 handles fastcalls, and it'll go to 0xFFF021A0 + (num * 0x20). Because all normal syscalls are divisible by 0x100, it'll go to "fastcall 0", 0xFFF021A0 is a jump to 0xFFF01EC0, which is the table dispatcher for all "normal" syscalls.
Aaaand that's about all the farther I've gotten, next step would be to rename all the syscalls and translate them into C to look for possible bugs.
Last edited by NWPlayer123,