This weekend I wanted to relax a bit and stop coding, so I decided to resume work on reverse engineering the ATJ227x gadgets.
You may remember I was involved in hacking with the older Actions Semiconductors MP3 players in the S1MP3 project. This never got anywhere, with more powerful hardware now being just as cheap and Rockbox being a more appropriate solution for it. Anyway, Actions Semi is not dead, and they still do some weird system-on-chip stuff. The new iteration is called G1000 and powers some cheap handheld consoles. I can name the JXD 3000, the Kulala K803, the KO W5000 and W6000, and the Juyou A320+ and S430. Never heard of them ? Well you should go buy one of those now. The cost around 30 euros, which is quite cheap, and they all share most of the same hardware: ATJ2279B system-on-chip, 480x272 LCD, USB (they act as mass storage devices), SD card connector audio out (and some of them even have video and HDMI), and a touchscreen.
As usual, besides the very cheap plastic (what did you expect at such a low price? they even added metal weights inside the case so it doesn't feel too light and crappy!), the problem with this devices is the low-quality firmware they are running. This time, instead of a completely homegrown system, Actions Semiconductor went with ┬ÁC/OS II (no, this is not compatible with Linux nor Android). Anyway, when I got my Kulala K803, there was very few information available on these devices. Now they have spread out a bit more and, more importantly, Juyou made available the firmware update tool and their firmware files. I risked breaking my different console installing that, and, well, it worked. The Juyou firmware is much better than the Kulala one. I think I lost the radio support and maybe some other features in the process, but well, at least I have an useable user interface now (it's PSP-like). I can use this as a MP3 player (Ogg doesn't work with the Juyou firmware it seems), which is already a good thing, and the thing also runs GBA, SNES, Playstation games (slowly).
More important than that, I now have a firmware file to play with! Let's throw binwalk (don't use the Debian package, it's outdated) at it and see what it finds! Well... nothing. Some invalid gzip headers, no strings, no known compression format, just nothing. Not very good, but I know the firmware files for the older z80 devices from Actions were encrypted in some way. So let's try a different approach to this.
It turns out the firmware is encrypted, but fortunately still using the same system as the previous chips. Using the atjboottool done by the RockBox project allows to decode this. Binwalk is much more happy with the result, turns out is it an sqlite database. It stores some metadata, and more interesting, the firmware files. Good thing: I can spot the well-known ELF header in there. The combination of SQLite and ELF makes things much easier to understand. That's nice from Actions. It should also make it much easier to rebuild a firmware file for updating the device, should that be needed. I think it's better to look for the possibility of adding an homebrew loader like this one done for the JXD 3000. I heard the OS structure is different in each firmware version, but maybe there are some ideas I can reuse. It seems the trick to read libs from the mass storage on boot may be JXD-specific, as other consoles (at least the Juyou upgrade guide I've found) use the ADFU firmware upgrade tool over USB instead.
So let's run binwalk again on that interesting img file. Inside there seem to be a lot of ELF files, GIF and PNG pictures, as well as... another sqlite database. The "matrioshka" option in binwalk is starting to make sense. It's a plain FAT32 partition (mount on linux with -t vfat -o loop), however, the partition size is 90MB, yet the file is only 60MB. I can imagine this will create problems if you try to write to it. The structure is quite simple, there is an APP folder with the applications, and a LIB folder with the libs. The other sqlite database is actually for the english/chinese dictionnary app, so it's not very useful for us.
Each application is made of an "app" file which is actually just ELF. Some of them have resources (in res format), a stylesheet (.sty), and sometimes other resources (for example the boot logo app has two animated gif and a startup sound). The RES-file format may be similar to what Actions used on older console, so the code in s1res may be of some use. I have no idea about the STY files, however. There are also "desktop" files which are just lists of strings in different languages for the application name.
In the lib folder, there are only 4 files: applib, style, fusion, and commonui. They are all rather small (less than 500K). A quick look at "readelf -s" shows that there are some source file names information left there. I don't have a MIPS toolchain yet to look at the disassembly and start extracting actual function prototypes, however I can already tell you that fusion seems to be some 2D drawing framework (with rotations, blits, and all that stuff), applib is some kind of system lib (timers, watchdogs, ...), and style is for the UI theming, but seems to export some file I/O functions (fopen, lseek, ...). Commonui seems to be a mix of UI widgets, system stuff, and some of the emulator code (gba_* functions ?). So, no libc or other standard OS stuff here, it seems this is all linked into the apps statically.
The OS itself isn't part of that hidden image. It seems to be built from the other files in the SQLite database. init.exe seems to be interesting, and the best place to look for hooks where to insert the homebrew loader. It's an ELF file again, like all the .so (libs) and .ko (kernel modules). There are also some configuration files in there, which may allow to turn some features on or off (HDMI output, camera input, etc.). I suspect the config is used to pick the right kernel modules and leave the others out. The init.exe has no symbols, so readelf can't tell much about it. It has the usual sections for a C program built with gcc, however, but the complete lack of symbols is strange. I'd expect at least an entry point. That being said, there is a .init section which makes a good entry point as well. strings give a good indication of what it does: initializing low-level stuff (RTC, vram, ...), mounting disks, loading some libs and kernel modules, then running manager.app to run the actual application code. Interesting note: there is a kernel module loaded from /mnt/sdisk, this should be the SD card. Others are run from diska, which may be either the hidden system partition or internal memory. Running strings on the manager.app also gives a fairly good idea of what it does. mnt/sdisk is added to the path so dropping a custom app there may be enough to get it executed in place of the system ones. /mnt/remotedisk sounds useful for development, as well.
The syscfg.sys file is actually where the syscall handlers are. It's NOT an ELF file this time (this seems to be the actual kernel code?) but has helpful strings all over the place. Uli already did the work of analyzing this but he noticed JXD firmware he worked from had different numbers from the others, so I'll have to check if any of this matches mine, and else, find a way to generate the syscall file from any firmware.
If you want to play with this, I have setup a mirror of relevant files. This includes datasheets, Juyou firmware, and update tool (windows only), and I'll add more as I make progress.