[Archive] DS Exploits and Whax


Editor’s Note: This is a combination of two articles I wrote on July 31, 2015 on one of my old blogs that can be found here and here when I was 15 years old, and another post titled “More Whax” on February 8, 2016 when I was also still 15 years old that can be found here, so please excuse my immaturity. As a fun fact, I did once get an email from someone asking me about this post, which I never followed up on.

I lost some of my work on this in a hard drive crash, but I still had some notes on this I saved on a pen drive (Including the T3PK decompression code, I had to re-do my reverse engineering for the exploit though since I lost my shellcode), so I presented an updated presentation of this at Sherpasec in 2023 (You can find the slides I used on my Linkedin) and plan to eventually write a new blog posts with more details on it.

I remember I used a pirated version of no$gba debugger with the password “veta”, which at that point was not free (It became free a few years later.), because IDA Free didn’t have ARM support, and Ghidra was not out yet for another few years. I remember also using a simple ARM simulator program to help me understand things. I later tried many times on reversing exploit the Nintendo 3DS flashcart (Gateway 3ds) used, and got pretty far, but unfortunately lost my work in a hard drive crash and never published it anywhere.


DS Exploits

I was, at one point in 2013, interested in trying to ‘hack’ a gaming console. Inspired by smealum’s bangai-o-sploit and his Fifa Exploit, I sought to first try to recreate Fifa Exploit, and then discover my own.

At that time, CTurt’s excellent articles on DS exploits (here) did not exist. However, hacker ‘St4rk’ had successfully exploited a Fifa game as well as a game called ‘The-Biggest-Loser’, which ran in DSI mode.

So I was more or less on my own. Take note that I hardly knew any programming at the time, and I wouldn’t have been able to tell apart a bit and a byte.

I downloaded 2 DS emulators (Desmume and NO$GBA, the latter which helpfully has a debugger) and was on my way. I was reluctant at first to look at the disassembled ARM assembly code (It was not meant to be human readable besides, assembly is not used to program big games like Fifa) to find the checksum so I resolved to static analysis. This however, yielded me no results. I am sure that the reason being I was not looking at it carefully enough, but I gave up.

Several months later, I found Wintermute’s savesploits github page, which included code for fixing the checksum. After that, was well on my way. I easily managed to overflow the ‘Name’ field and execute my own code. I will not go into details as I would prefer to explain it with my Whax, which is very similiar in concept and will be written later on in another post

As an exercise, and also due to me being too lazy setting up a C compiler (I didn’t have one at the time) and makefiles, I carefully analysed the code in NO$GBA  to find code for displaying text. Before I found Wintermute’s github page, I had tried learning ARM assembly to attempt to find the code to fix the checksum. While my skills could not fix the checksum, I could however, find the address in memory to display text.

And so, I used ROP (Return-Oriented-Programming) to display “<3 Emma Watson <3” if I remember correctly.

Sadly, I did not take any screenshots at the time, so I could not share them here. Perhaps I did, but it is now lost in time….or somewhere in the 238 GB of memory in my hard drive.

Whax

Lo and Behold! I present to you, Whax!

I spent months working on Whax, months. What exactly is Whax you ask? Well…. It stands for….

Winx Hax

Yup. An exploit for this game.

Yup. This game.

Yup. This game.

Why? For one, I was attracted to the fact that it can supposedly store huge amounts of text (like, a diary) . This led me to believe that it was possible that I can Reverse Engineer the compression/decompression and somehow exploit the decompression in a fashion similiar to how smealum exploited Bangai O Spirits.I did not choose a game utilising the microphone because at the time, soundhax was not released, though smea stated it might be possible.

Also simply because I liked Winx Club when I was younger. Though I stopped watching at some point in Season 2. This was waaaaay back in the day, like, when Winx Club was just starting to show on TV.

Lastly, it is one of the few games to use such a big save file, presumably to store all the diary entries.

I, at first, had misconceptions. I believed that it might just be possible….. That there can be compressed homebrew applications! How cool would that be? Unfortunately, doing RE in the game’s code, I quickly found out that that was not the case. The compression/decompression was aimed towards compressing ASCII text, not code.

The checksum, thankfully, didn’t take me relatively long. Although I do have a few text files trying to reverse the checksum algorithm used. For some reason, the checksum relies on data inside the game. Perhaps a form of encryption? a public key? I don’t know. But I worked around this by dumping the large area of memory in the game which it uses to generate the checksum. My program fixing the checksum always worked for me, so I guess the dump is big enough.

Sadly, I could never wrap my head around the compression of the journal entries. Perhaps I should have looked into LZ compression and attempted that first as an exercise (indeed, up till this day, I have not attempted to do anything of the sort). So I gave up.

Months later, I thought maybe I was looking at it in the wrong way. Maybe it didn’t need to be exploited through decompression. I had already checked all the journal biography information for overflow (ie. Name, DOB, etc.) but could not find any overflow of the sort.

Fun Fact : I did find out that, surprisingly, although In-Game they only allow for up to 10 characters for your D.O.B, the savefile allows up till a whopping 21 characters! Besides that, the email entry allows for up to 50 characters! I have not checked for how much is allowed for In-Game input of email address though…

While absent-mindedly playing a maze mini-game in the game for fun, I discovered a High Score system. Just for fun, I decided… Why not try overflow the High-Score list? Amazingly, even though all of the other information was checked properly, the High Score was not!

Quickly, I looked at NO$GBA to find the address of failure, and gather relevant information. I will not take the time to explain what a stack is, but I suggest you find out. Anyway, the name was located in stack, I overflowed it, It overwrote some stuff, and then overflowed onto the return address. Now was my time to attempt at a ‘Hello World’ of sorts.

I wrote my payload (my code) into the area of where the ‘drawing’ in the diary is stored. Mainly so that I know it won’t mess things up (If I write over the name and overflow it, the game will automatically ‘fix’ it for me, thus corrupting the payload)

coloured

Here’s how it looks like inside the ‘painting’ application of WCSD09

And here is one of my earliest attempts, based off Reverse engineered code off this close-sourced save exploit for Fifa 08. The code is meant to turn the bottom screen red. Here is what happened.

Grrr&hellip;.

Grrr….

I could not for my life explain why the top screen is like that.

I tried disabling Interrupts and resetting ARM7/ARM9 (or so i thought), but that instead resulted in this

inaction

And it sounds like a dying walrus

At first sight, this seems OK. Yeah….but what if I told you that it makes this high-pitched noise afterwards? And wait a minute, isn’t it supposed to be at the bottom screen?!

At this point, I said ‘I did good enough,’ and went off my own business for many more months.

At one point, when there was a power failure and I was just messing around with 50% of my laptop battery left, I figure out what was the problem. I was not clearing the cache.

For some odd reason, not clearing the cache is what causes the top screen not to react accordingly (see my first attempt). Wintermute must have somehow figured this out, as he had code in his incomplete FifaSploit2 reproduction (I never managed to run that however, it was designed for a DSI) to clear the cache.

A bit of technical stuff if you’re into these things and you’re a bit stuck. Clear the cache, reset the system (see reset.c of libnds) and do not attempt to disable REG_IME, that does weird stuff. Resetting is not really necessary, but I guess it helps somehow.

3453 - Winx Club - Secret Diary 2009 (EU)(M5)(EXiMiUS)__22265

Works exactly as coded!

I also managed to port St4rk’s payload into it, but since I don’t have permission, I won’t be showing it. Smealum had a much cooler screen for his Fifa hack, but I supposed a red screen would do.

Where to go from here?

Like bangai-o-sploit, perhaps we can put an arm7/arm9 code somewhere, and then reset the system to go there. That way, we can convert nds homebrews directly to savefiles.That would be super cool, but time consuming, and not really worth it IMO, unless you have the cart and need a way to have DS mode homebrew on a 3ds.

I attempted loading an image into the program and displaying it, however, all images just seem far too big to be placed into the save file.That’s not to say the space is small, but as I said, it has to be in certain positions and such.

All in all, I’m pretty proud of Whax, despite not doing anything remarkably impressive. The entire process was a huge learning experience, and I hope to get to 3ds exploiting in the distant future. That may take some time however, remember the DS came out more than 10 years ago, and the 3ds less than half of that. The DS has next to no security in place compared to the 3ds.

Apologies for not being an excellent article, I am but a novice in writing blogs.

More Whax

Ok, the title is misleading. I did not continue working on Whax, but what I did was figure out how to access the files inside it.

Through dslazy, I got the some files.

Among them packfile_ds.t3p

t3pkhex

It’s an archive file. The internet didn’t help me here, though I did find some similar compression code used for The Sims, which I used as a basis for when I wrote my decompression code.I dug into the disassembled code of the game to figure it out.

(Granted, if I was just a bit smarter, I could have figured it all out through static analysis without ever looking at the code at all.)

It uses some basic form of LZ compression. Here are my notes at the time. Albeit a bit incomplete.

 

opcodes

L - Length Outwards
D - Preceding Data Distance

			Description						Exception blah
00LL LLLL		RAW copy to copy from srcBuf to destBuf			None
			Is after


01LL LLDD		(opcode << 0x1e then >> 0x16) 				Add 2 for LL and 1 more
DDDD DDDD		Sliding window backwards (decompressed)			Add with previous and one more


10LL LLLL
LLDD DDDD
DDDD DDDD 
			
11## ####

Also the outline of the t3p format I guessed through staring at the file (without looking at the disassembly)

0x00		0x04		"T3PK"		-	MAGIC
0x04		0x04		0x30302E34	-	Unknown
0x08		0x04				-	NumberOfFiles (+1?)
0x0C		0x04				-	Position of folders/filenames (folders first then filenames)
0x10		0x04				-	Length of 'filenames'
0x14		0x04				-	Length of 'folders' section

-REDUNDANT-
0x18		0x04				-	SizeOfHeader (From beginning)
Reason : while it is true that is the size of the entire header, what it actually is is the PosInFile of the first
file, which just so happens to be right after the header.

FILE DB        (Size 0x28)
0x00		0x04		PosInFile	-	Position in file of file contents
0x04		0x04		SizeOfFile	-	Size of file (while compressed)
0x08		0x04		SizeDecompressed-	Size of file after decompressed
0x0C		0x04		Unknown
0x10		0x04		char *filename	-	Filename pointer (Null-terminated)
0x14		0x04		Folder		-	Folder offset after folder string
0x18		0x10		Unknown		

FILE
0x00 		0x04		bytes_read_out	-	
0x04				RAW_FILE	-	raw compressed file

After that I wrote a C++ program to extract all of it, and then I had some interesting stuff, most interesting to me, is the language file. The textures are in there and can be opened through as ‘raw’ by gimp, but I have trouble figuring out exactly how that works and I suspect the format is converted in-game to some other format judging my comments left in the executable.

Interestingly, there was one file that had a length of ‘0’ that made me run into a problem when decompressing. Why that empty file had a length of 0, I had no idea but meh.

It’s possible what I extracted is not everything since I see some files referenced in the code comments left in that don’t exist, but I’m happy with what I got.

This is probably where I end my fiddlings with My Secret Diary, as I don’t think that modding the game through compressing my own custom language files or anything would be worth the effort. If I do, I’ll probably be exploiting Whax in High scores to do more cool stuff (my understanding of the ds is quite minimal) or possibly do what I originally intended to do, exploit the game through flawed decompression, which I think may be possible since the length of ‘0’ didn’t crash the game. Or maybe not. Maybe the save file uses a completely different compression scheme. I don’t know.

On another note, I’m thinking of doing other stuff….. Like writing stories……Making boring programs……Possibly upload my school notes,or maybe my literature notes, which is really not much and not helpful, but it will help me for easy reference through my phone…..Or doing my best to actually do game dev, which I always seem to have problems with motivation….Oh well….

Naavin Ravinthran
Naavin Ravinthran
Computer Science Graduate

My interests include cybersecurity, osdev, and graphics programming.