Page 1 of 1

Misc. Wii code snippets

Posted: Sun Jun 30, 2013 11:28 am
by tueidj
Over the past few years I've written a lot of wii code that has been kept private for various reasons. I think it might be time to show some of it off and give somebody else the chance to do something useful with it. Having said that, all code posted here falls under the following licence:

Code: Select all

/* Copyright 2013 tueidj All Rights Reserved
 * This code may not be used in any project
 * without explicit permission from the author.
 */
Lesson 1: Loading your own IOS module into the currently running IOS
Most people know IOS runs on its own dedicated CPU - an ARM926EJ-S commonly known as Starlet. For the majority of the time, Starlet sits in an idle loop waiting for interrupts - why not give it some real work to do by making IOS run some custom code?
First you need to be able to modify the existing IOS code. This requires the MEM2 protection to be disabled, which needs AHBPROT disabled. HBC can take of AHBPROT and the rest is fairly trivial.
Since the ES module is the only part of IOS that is "allowed" to load a new module, we're going to modify one of its ioctls. Choosing which one is pretty simple; it should be one that isn't used under normal conditions, it should have uniquely identifiable code (so we can find where it is in memory) and there should be plenty of space for us to overwrite with our own code. ES_ImportBoot2 fits these requirements - it's used to upgrade boot2 which no regular application will want to do.
After deciding which ioctl to overwrite all we need to do is write our custom IOS module to the wii's NAND (the /tmp directory is a good choice) and use the following function:

Code: Select all

#define ES_MODULE_START     ((u8*)0x939F0000)
#define ES_MODULE_SIZE      0x20000
static int load_module_file(s32 es_fd, const char *filename)
{
	// this is the original code for the ES_ImportBoot2 ioctl
	const u8 old_es_code[24] = {
		0x68, 0x4B, 0x2B, 0x06, 0xD1, 0x0C, 0x68, 0x8B, 0x2B, 0x00,
		0xD1, 0x09, 0x68, 0xC8, 0x68, 0x42, 0x23, 0xA9, 0x00, 0x9B,
		0x42, 0x9A, 0xD1, 0x03};

	// this is the code that will overwrite it
	const u16 load_module[12] =
	{
		0x68CE, // ldr r6, [r1, #0x0c]	; ipcmessage.vec
		0x6830, // ldr r0, [r6]			; vec[0].data (filename of module)
		0x4778, // thumb->arm (BX PC)
		0x46C0, // nop (for alignment, assumes this block starts 4-byte aligned)
		0xE600,	0x0B50, // syscall_5a (load_ios_module)
		0xE28D,	0xD020, // ADD SP, SP, #0x20
		0xE8BD,	0x4070, // LDMFD SP!,{R4-R6,LR}
		0xE12F,	0xFF1E, // BX LR
	};

	u8 *addr;
	s32 ret=1;
	ioctlv vec;

	for (addr=ES_MODULE_START;addr < ES_MODULE_START+ES_MODULE_SIZE-sizeof(old_es_code);addr++) {
		if (!memcmp(addr, old_es_code, sizeof(old_es_code))) {
			memcpy(addr, load_module, sizeof(load_module));
			DCFlushRange((void*)((u32)addr&~0x1F), 32);
			vec.data = (void*)filename;
			vec.len = strlen(filename)+1;
			// call ES_ImportBoot2 with the module filename as a parameter
			ret = IOS_Ioctlv(es_fd, 0x1F, 1, 0, &vec);

			// restore the old code and flush
			memcpy(addr, old_es_code, sizeof(load_module));
			DCFlushRange((void*)((u32)addr&~0x1F), 32);
			break;
		}
	}

	return !ret;
}
If the function returns 1 it succeeded, you should be able to communicate with your IOS module using regular IPC calls - you did make it register a device name, right?

Re: Misc. Wii code snippets

Posted: Sun Jun 30, 2013 11:50 am
by emu_kidid
Very nice, I know some people would find this easy, but not having looked at much Wii Starlet side code this is quite useful/interesting. Thanks for sharing :) looking forward to more

Re: Misc. Wii code snippets

Posted: Sun Jun 30, 2013 11:55 am
by wii_HD
^ emu took the words from my keyboard already.

Thank you for sharing and also your work thus far tueidj.

Re: Misc. Wii code snippets

Posted: Mon Jul 01, 2013 6:20 am
by 47iscool
I'm not a programmer...but wow.

Re: Misc. Wii code snippets

Posted: Tue Jul 02, 2013 1:44 pm
by KirovAir
Thanks for sharing.

Re: Misc. Wii code snippets

Posted: Fri Jul 05, 2013 9:15 pm
by barcapedro
tueidj wrote:

Code: Select all

/* Copyright 2013 tueidj All Rights Reserved
 * This code may not be used in any project
 * without explicit permission from the author.
 */
Why releasing this piece of code, while forbidding to use it? Seems rather stupid to me. I mean this licence makes your code pretty useless.

Re: Misc. Wii code snippets

Posted: Fri Jul 05, 2013 10:35 pm
by pr0ton
barcapedro wrote:Why releasing this piece of code, while forbidding to use it? Seems rather stupid to me. I mean this licence makes your code pretty useless.
It isn't forbidden, his permission is needed. Plus his code wasn't meant for copy&paste work, but rather learning and insight lessons, I think.

Even when you aren't a reincarnation of therandomizer, you should appreciate tueidj publishing this. He/she certainly doesn't owe you something..

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 2:23 am
by megalomaniac
i smell randomizer

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 4:06 am
by tueidj
What's so hard about asking permission?

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 6:45 am
by barcapedro
tueidj wrote:What's so hard about asking permission?
OK. Will you let me use it?

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 9:05 am
by tueidj
What do you want to use it for?

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 12:17 pm
by manic.blood
i wasn't really sure where to add this ... so here I go. I see that the CorsixTH port you made can play .midi music using libtimidity. WiiDoom had a lot of potential, it could already play the original and mods using various controllers and SD/USB support.

However there was always that issue with No music. Originally Doom music worked by writing midi data form DOOM.WAD to the HDD constantly. This cannot be done on SD/USB as it severly shortens their life.

Please could you explain you solution using libtimidity?

Re: Misc. Wii code snippets

Posted: Sat Jul 06, 2013 1:46 pm
by tueidj
Firstly, doing such a thing wouldn't significantly affect SD/USB lifetime at all.

The music in CorsixTH is actually handled by SDL which incorporates timidity, so I didn't have to add any extra code to make it work. Descent-wii was a different story; like Doom, the music files use a format that is not-quite-midi-but-if-you-look-closely-it's-just-rearranged-a-bit. Each midi song is only a few hundred KB at most so when a new song is loaded it gets converted to proper midi format and stored in a memory buffer. Then timidity is told to load the song/buffer (via Timidity_LoadSong()) and whenever more raw audio data is needed it can be fetched by calling Timidity_PlaySome().

Re: Misc. Wii code snippets

Posted: Sun Jul 07, 2013 10:53 pm
by Maxternal
May I use your IOS patching code, plz?

What I would use it for is the following:
Currently, to initiate the race attack to unlock 3 cores on vWii we are extracting the BootMii IOS from a normal Wii to install it on the Wii U to load our modified mini onto Starlet. It would be far easier for the user if I either
1. just patch in IOS with syscall 0x43 (which I'm told loads a new IOS from memory) and load our mini that way ...
2. or to just temporarily add the race attack code as a new IOS module which could keep the IOS in place if needed afterward.

I was also thinking of using #1 to make a nSwitch that doesn't need BootMii IOS installed as well as a boot.dol that would just load any armboot.bin from storage without said IOS (potentially facilitating others running custom ARM code on Wii U).



Also, if you were to give permission, would inclusion in the above mentioned open source code (and googlcode repository) require your code that I modify to be precompiled with no source code and with a copyright declaration or would just clearly marking parts of the code derived from yours with a copyright notice be good enough?

Re: Misc. Wii code snippets

Posted: Mon Jul 08, 2013 8:40 am
by tueidj
AFAIK Bootmii IOS is installed automatically by the Hackmii installer on all systems, including WiiU. It's definitely installed on my WiiU and I never did anything extra to get it on there. I would recommend using it above any other method if you want to boot a customised IOS kernel, since it can be launched directly from HBC (or any other app capable of loading IOS 254). Making a method to do it without using Bootmii IOS isn't worth the effort since you still need AHBPROT disabled and HBC is the enabler for that.
Regardless, a custom IOS module wouldn't be able to do what you want. Syscall 0x43 can only be called by the ES module (otherwise it does nothing and returns an error), and the race attack involves rebooting the PowerPC CPU which can only be done by the IOS kernel (regular IOS code can't access the required hardware registers).

Re: Misc. Wii code snippets

Posted: Mon Jul 08, 2013 4:03 pm
by nick255
pr0ton wrote:
barcapedro wrote:Why releasing this piece of code, while forbidding to use it? Seems rather stupid to me. I mean this licence makes your code pretty useless.
It isn't forbidden, his permission is needed. Plus his code wasn't meant for copy&paste work, but rather learning and insight lessons, I think.

Even when you aren't a reincarnation of therandomizer, you should appreciate tueidj publishing this. He/she certainly doesn't owe you something..
Actually, it is useless even for learning and it would have been better had he not published it. As it is now, how many developers have been "contaminated" by viewing this and thus will be unable to load their own IOS module into an existing IOS period unless some other developer who has done this before Jun 30, 2013 kindly posts their code snippets. Key terms to remember are "subconscious copying" "substantial similarity" and "Bright Tunes v Harrisongs".

Re: Misc. Wii code snippets

Posted: Mon Jul 08, 2013 4:41 pm
by tueidj
I'm sure there are plenty of other ways to achieve the same result, this is just one of them.

Re: Misc. Wii code snippets

Posted: Mon Jul 08, 2013 5:49 pm
by Ashen
Alright, I'm gonna put it out there in black and white. Since some people just don't seem to get it.

Constructive criticism: OK.
General talk about ways that code (or whatever else for that matter) could be modified or improved: OK.
Suggestions on ways to improve code/stuff: OK.
Pointing out in a positive manner, ways that code/whatever may be bad, broken, wont work: OK.

Blatantly attacking someone or their work and looking to start a flame war: NOT OK.

From now on if you have less than 5 posts and are found to be doing the above. You will receive an immediate ban. I will not even bother to consult with Emu about it. It seems that there is an influx of new members lately just looking to start a fight, for whatever reason. This is not the place for it. Take your boxing gloves somewhere else. I don't give a shit where, just don't do it here.

Re: Misc. Wii code snippets

Posted: Mon Jul 08, 2013 8:56 pm
by Maxternal
tueidj wrote:AFAIK Bootmii IOS is installed automatically by the Hackmii installer on all systems, including WiiU. It's definitely installed on my WiiU and I never did anything extra to get it on there. I would recommend using it above any other method if you want to boot a customised IOS kernel, since it can be launched directly from HBC (or any other app capable of loading IOS 254). Making a method to do it without using Bootmii IOS isn't worth the effort since you still need AHBPROT disabled and HBC is the enabler for that.
Regardless, a custom IOS module wouldn't be able to do what you want. Syscall 0x43 can only be called by the ES module (otherwise it does nothing and returns an error), and the race attack involves rebooting the PowerPC CPU which can only be done by the IOS kernel (regular IOS code can't access the required hardware registers).
Okay, thanks for letting me know why some of my ideas wouldn't work before I wasted the time trying to implement them. ;)

Anyway, maybe you have the bootmii IOS from a beta version of the latest hackmii installer that the public didn't have access to or something because the public 1.2 version refuses to install on Wii U

I'm only guessing it was removed for Wii U because with the changes in how the processor resets (which they used when loading ppcboot.elf), the lack of a reset button or GC ports for full control and the lack of a boot2 (which they used to load HBC and the system menu ... and the MIOS from GC mode although that doesn't really apply here), the rest of bootmii didn't work on vWii, at least not without some modification first.


No problem, though. The way we're doing it right now seems to work fine.

Re: Misc. Wii code snippets

Posted: Fri Sep 27, 2013 6:11 am
by tueidj
Been kinda longer than I intended between lessons...

Lesson 2: Wifi Scanning

Whilst trying to find a way to get low-level access to the network adapter I RE'd the WD (Wireless Device) Command interface. It provides status information (available APs, wireless link state etc.) as well as a few commands that in theory can be used to communicate with a DS - I never bothered following them up since I don't have one. But I did end up throwing together a quick demo that scans for nearby access points and lists their SSID, channel and security (if any).

Code is here; forum doesn't seem to support spoilers.

Note that all the WD commands are handled in a dedicated thread (WD_Thread()), this isn't really used to any advantage by the demo since WDProcess always blocks for the response but in a regular app the scanning could be performed as a background task, triggering a UI update when completed.