Extending HUMAX iCord – part 1

A case study for MIPS based embedded computing

This case study will describe some aspects of embedded computing and show how such systems with non-i386 architecture could be used for a extended stuff. All I’m describing here is for evaluation purposes and not ready for mass production but it may help to understand the hurdles and how to jump over when dealing with limited resources.

What should be reached finally?

I’ve bought a settop box for DVB-S2 some months ago, a brand new HUMAX iCord HD (http://www.humax-digital.de/products/iCordHD.asp). It’s an easy to use, reliable stuff with a fantastic high quality TV experience including broadcast recording. But over time I realized some missing capabilities like

  • a comprehensive channel editor on the system itself (without the need for export / import channel list),
  • remote timer list programming (I’d like telling my iCord to record an interesting broadcast even when I’m not @ home.),
  • a nice web interface for the stuff above and much, much more.

The hurdle is that the iCord is a closed box. The only way to talk with the outside world is through FTP; but FTP shows only the media directory and isn’t suitable for executing commands. But there’s a network connectivity and the capability to update iCord’s firmware with an USB drive containing hdpvr.hmx file (the firmware container). Unfortunately the firmware is encrypted but good news is that some resourceful people has found a way to decrypt.

One word to the legal aspect: Decrypting and providing a modified version of a vendor’s software isn’t allowed by law. So far you would find nor link to the decryption tool neither to the patched firmware at all. I’ll explain the how-to and provide some basic stuff, finally the root file system with some add-ons. If you’re looking for decrypting / encrypting iCord’s firmware you may find something in Google when looking for “colibri” in relation to iCord.

So let’s come to the first step ..

Extensions described in this part

After making all modifications described in part 1 you’ll have

  • SSH access to iCord with public key authentication (that’s being used because iCord’s BusyBox is compiled without login module)
  • SCP and SFTP support including SSHFS (mount iCord’s filesystem into your’s)
  • a bootstrap mechanism for further extensibility on /mnt/hd1 (the root file system is read-only but this is a way to add extensions later on without flashing again)

Experiencing the new behaviour

My nature is to try things first to get an impression what’s going on and afterwards digging into the details of the “how-to?”. So far you may start with downloading the ready squashed file system to insert into your firmware update file. Please read following instructions carefully before changing anything. And .. there’s no guarantee that everything is working, so be prepared to have the original firmware ready to avoid stress with your family about non-available TV ;-)

Instructions:

  1. Modify your firmware with the extended root file system Flash_700000.bin (it’s based on 1.00.17).
  2. Store the updated firmware on a Fat32 formatted USB stick.
  3. Generate a file “authorized_keys” on same USB stick; this file must contain the public key part of your rsa / dss keys generated with ssh-keygen or PuTTY. You can find a detailed description of SSH public key authentication and key generation under http://hkn.eecs.berkeley.edu/~dhsu/ssh_public_key_howto.html.
  4. Plug in the USB stick into your iCord, switch on (with the back side power toggle) and hold “Record” key on the front side panel during boot. You should see the download and update progress on the screen and also on iCord’s LED panel.
  5. When finished, you’ll get a message to reboot. Important! – let the USB stick plugged in. Switch the iCord off and on again. After reboot you can plug off the USB stick.

If everything was going well you should be able to access your iCord with

[code]ssh root@<ip-address>[/code]

You should be able to access the iCord now with SCP and SFTP, both can be used for any client you’d prefer to use. Under my Ubuntu installation on my laptop I also tried to get mounted iCord’s file system with

[code]sudo sshfs root@<ip-address>:/ /media/icord -o IdentityFile=/home/username/.ssh/id_rsa[/code]

When you’re browsing the iCord’s file system you will see 2 new directories, /root and /opt. Both are symbolic links to /mnt/hd1/root and /mnt/hd1/opt. Sense of /opt is to provide an anchor for further extensions without the need for flashing again. /opt/bin has been added to iCord’s $PATH variable (this directory isn’t there at the moment but could be created easily). /opt/etc/init.d may contain later on startup scripts that following the “S??*” pattern. The trick is that at system boot both directories, /etc/init.d and /opt/etc/init.d will be parsed; scripts contained in both will be executed in sorted sequence. Means if /opt/etc/init.d contains a script S50utelnetd this one will be executed between /etc/init.d/S40/networking and /etc/init.d/S55dropbear (the new one for dropbear SSH server). /opt/bin may contain than the appropriate binary utelnetd.

So finally you’ll have an iCord with full and secure access from outside world and the option to extend functionality without flashing again.

What’s behind – the “how-to?”

Input structure for modifications

hdpvr.hmx consists of 3 parts. The interesting one is the Flash_70000.bin (contains root_fs – root file system /). Once extracted from hdpvr.hmx, you’re able to copy the Flash_700000.bin to elsewhere for further work.

“Unsquashing” the root file system

Flash_700000.bin is a squash file system image. To extract the files I’ve used squashfs tools (http://packages.debian.org/search?keywords=squashfs-tools). Take care that you’re using version 3.1 instead of 3.3 due to an error that 3.3 produces when packaging the file system back to the image. I’ve no clue what’s the reason is but 3.1. worked for me well. The command to unpack the Flash_700000.bin is

[code]sudo unsquashfs -d /home/username/icord_root_fs/ /home/username/Flash_700000.bin[/code]

For next step let’s assume that you have a directory with unsquashed root file system on your Linux OS. All further links are relatively to this point. I’ve done all the work with Ubuntu 9.04, any other distribution should work either.

Adding dropbear SSH server and start script

The iCord is based on BusyBox (http://www.busybox.net/) and uClibc (http://www.uclibc.org/). A lean SSH server extension for BusyBox is dropbear (http://matt.ucc.asn.au/dropbear/dropbear.html). I took the sources of dropbear and compiled them statically linked for for MIPS / uClibc. The compiled binary you can found under /bin/dropbearmulti. There are also located symbolic links to this binary, dropbear, dropbearkey and scp. The start script for dropbear is located under /etc/init.d/S55dropbear. The host keys will be generated at system boot under /opt/etc/dropbear. Deleting these will trigger generation again. All client public keys are stored in /root/.ssh/authorized_keys file. You may change this manually or otherwise store it on an USB stick and plug the USB stick in during system boot. I’ve also modified the startup script /etc/profiles to avoid unnecessary error messages.

Adding greenend.org.uk sftp-server

Dropbear doesn’t support SFTP out-of-the-box. Therefore I’ve done some research to find a small sftp server under http://www.greenend.org.uk/rjk/sftpserver/. This isn’t ready for large production environments (and it will not be developed further) but I tested it and it works well for such an environment. The statically compiled binary sftp-server you can also find under /home/username/icord_root_fs/bin. As dropbear will look for a binary sftp-server under /usr/libexec I’ve modified the dropbearmulti binary with a hex editor and changed the sftp-server location to /bin.

Bootstrap mechanism

The extension point is quite simple .. adding a symbolic link /opt that points to /mnt/hd1/opt. All secrets you can find in /etc/init.d/rcS. It’s a simple script that contains the bootstrap mechanism. It mounts /mnt/hd1 first and looks for start scripts in /etc/init.d and /opt/etc/init.d in sorted sequence over both directories. Due to early mount of /mnt/hd1 I commented out the matching line in /etc/fstab.

“Squashing” the root filesystem

That’s it. The final step after all work is to create a squashfs image again. This could be done with

[code]sudo mksquashfs /home/username/icord_root_fs/ /home/username/Flash_700000.bin.new -be -all-root -noappend[/code]

You may check all further details in Flash_700000.bin (see link above). I’ll proceed with further testing and some more stuff continued ..

Credits

All this work wouldn’t have been possible with a some people who helped me with lot’s of answers and tools ..

  • colibri – programming of an outstanding tool to decrypt and encrypt iCord’s firmware
  • Anthony G. Basile – providing a qemu development environment for MIPS uClibc and answering a lot of questions (http://opensource.dyc.edu/aboutus)
  • Graham White – for some about runtime debugging (http://gibbalog.blogspot.com)
  • last but not least HUMAX – for a really high-quality DVB-S2 platform

21 thoughts on “Extending HUMAX iCord – part 1”

  1. It is another milestone on the way to a “state of the art” receiver and it shows that there is life in the icord community.
    I hope you will continue with that.

  2. Thanks, works really fine. I have hope this is a good basis for future development.
    Looking forward to the next part.
    Greetings, Ben

  3. Thanks for this excellent job!

    I mounted the file system on my Linux box to see your work.
    Will try it in the evening on my iCord.

    Can’t await the next part.

    Greetings,
    Remo

  4. Great job
    Tested it a few minutes ago everything works perfectly and now I can easily test new applications without build a firmware every time.

  5. Hi catshout,

    excellent job, I just updated my iCord with your modified FW and the SSH server is listening – BUT: I always get “Permission denied (publickey).” when I try to connect via “ssh root@192.168.1.133
    I created a key on my Ubuntu Server as root user. I copied the id_rsa.pub file to my USB stick, renaming it to authorized_keys. The key looks like “ssh-rsa AAAAB3NzaC1yc2E … mWdlw== root@tux”, so I assume it’s OpenSSH format.
    When I start the box with the stick plugged in, the firmware is loaded, after reboot you see that it connects to the stick again.
    Am I missing something important?
    I thought it would be easier to have a telnet daemon running (since I have a firewall around my network this should be no security issue), but all the compiled utelnetd files seem to have removed by the admins of the boards…

    Anyway, thanks for your work, I’ll keep trying!

    pole73

  6. Seems that ssh connectivity is there but still a key pair mismatch. The user starting ssh command must be same as one created the key pairs. Furthermore you may try “ssh -i root@” to tell ssh explicitely the key being used.

  7. Hi Pieter, we’re working on httpd, I think end of August we’ll have another version containing http and ipkg + some useful extensions.

  8. I would like to add: The default busybox in the iCord already does wget, so you have a tool to get data from inside the icord. This already enables some kind of software install mechanisme, when combined with a small script.
    If you would use simple shell commands (busybox is ash like) you should be able to get and install several files in one script, which allow installation in e.g. the proper order, like a command or daemon program, then an rc script.

    If the busybox had httpd enabled you could already do a inter-icord copy which I find interesting.

  9. Yeah, that’s another way to that. But even if ipkg is a proven and commonly used mechanism I’d prefer to use that one instead of creating new stuff from scratch. And it’s not really big, I compiled and tested it successfully on a qemu test image containing iCord root filesystem. iCord’s busybox isn’t httpd enabled and I’d like to leave it as it is adding some httpd daemon on top. But this is still under discussion with some other folks. You may also check http://www.icordforum.com (it’s in German language).

  10. Below you find my two cents as a c source file that interprets
    the /mnt/hd1/reserve.info file
    //— cut
    /**
    * Hack to interpret the HUMAX iCord reserve.info file format.
    * Pieter van den Hombergh.
    * Public license. Free for any use.
    * Version 0.1, 2009-08-09.
    *
    * The size of the struct was guessed from the distances between
    * programme names. This size appears to be 276 bytes.
    * The programme names are preceded by 12 bytes.
    * The first 4 appear to be the start time, the next 4 the end time,
    * all in utc. The next two bytes are the big endian channel number,
    * The last two bytes have to do with programming options such as
    * repeat (once,daily,weekly,week(work)days and series) in the first byte.
    * The last option byte has bit 7 set when the program was programmed
    * with ‘automaitic record, i.e. press ok in programme list, and hence
    * the name is taken from the list. If you program free format (enter
    * date and time and channel), then this bit is false.
    */
    #include
    #include
    #include
    #include
    #include
    /* comment*/
    FILE * fd;
    extern char * mctime(uint32_t t);
    // total struct size is 276
    struct element {
    uint32_t time_date_start;
    uint32_t time_date_end;
    uint16_t channel;
    unsigned char options[2];
    char progname[264];
    };
    char * deffile=”reserve.info”;
    char * progoption[]={” “,”Once “,”Daily “,”Weekly “,”Weekdays”,”Series “};
    int main(int argc, char * argv[]){
    char * fname=deffile;
    if (argc > 1) {
    fname=argv[1];
    }
    fd=fopen(fname,”r”);
    int j;
    if ( 0 == fd) {
    fprintf(stderr,”cannot open file \”%s\”\n”,fname);
    exit(1);
    }
    struct element e;
    int i=0;
    printf(“###: start -end ( duration) chan options repeat prog title\n”);
    while (!feof(fd)){
    if (1==fread(&e,sizeof(e),1,fd) && e.progname[0] !=”) {
    printf(“%3d: “,i);
    // correct endiannes
    e.time_date_start= ntohl(e.time_date_start);
    e.time_date_end= ntohl(e.time_date_end);
    e.channel = ntohs(e.channel);

    // print times
    printf(“%s-%s “,mctime(e.time_date_start),mctime(e.time_date_end));

    // print duration
    printf(“(%5d min)”,((e.time_date_end-e.time_date_start)/60));

    // print channel
    printf(“%5d “,e.channel);

    // print two option bytes
    for (j=0; j >5)&7]);

    // print programme name (is in latin1, comes out wrong on utf-8
    // terminal when uncorrected
    printf(“\”%s\”\n”,e.progname);
    }
    i++;
    }
    fclose(fd);
    }

    char * mctime(uint32_t t){
    time_t tt = (long)t;
    static char buffer[28];
    strftime(buffer,sizeof(buffer),”%Y-%m-%d %H:%M”,gmtime(&tt));
    return buffer;
    }

  11. Forgive a newbie if he’s asking a silly question but.. is there a chance I might scr*w up my Humax iCord by uploading bad firmware? And can I always restore the original firmware by following the flash procedure outlined above?

    Rembo

  12. If a patched firmware contains some bad code that writes into the flash memory (e.g. into the boot loader area), yes it might break the iCord. The firmware I’ve uploaded here doesn’t contain such a piece of code. In all other cases a non working firmware can be overwritten by the original one.

  13. Sorry, but is there a way i can download the patched hmx file? I just don’t know how to path the flash file.

  14. Pieter,
    I am also a member of the iCord forum and have made many entries on the forum relating to the lack of Epg for UK users.
    Do you have anything that can be used with this firmware that will give a full EPG for UK users on Astra2.
    What I am looking for is an EPG similar (or the same!) as used for Freesat channels – not bothered about all channels on Astra2, just the main Freesat ones. – Thanks for any advice.

Leave a Comment