Unpacking, editing and packaging of firmware of DVRs and IP cameras from Xiong Mai

    Background


    Not so long ago I bought an IP camera on Aliexpress (Hi3516 chip 53H20L platform) and a 16-channel hybrid video recorder (Hi3521 chip MBD6508E platform). Both are based on the HiSilicon chipset, so they do not experience compatibility problems with each other.
    Of course, not without glitches. The first and most important one - WiFi was crooked on the camera - it was impossible to connect to the network if the key was specified in the HEX form, and also periodically there was a problem with the default gateway.

    The firmware turned out to be old, still June. I got some fresh firmware and tried it. Some turned out to be buggy, but one worked fine.
    Another problem occurred - the default password for telnet connection was changed. I could not tolerate this and began to look for ways to return it back.
    I’ll immediately warn you that this method has been tested on DVRs and cameras based on HiSilicon chips, but it should work with a different platform, since the Chinese widely use the U-boot bootloader.

    Unpacking


    The unpacking instructions are described in some detail in this article , but the packaging process is not described anywhere, which prompted me to write this post.
    I paint in steps so as not to miss anything:
    Install Linux, I chose ubuntu.
    Check the type of firmware file:
    root@xc:~/firmware# file General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin 
    General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin: Zip archive data, at least v2.0 to extract
    

    Unpack:
    root@xc:~/firmware# unzip General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin 
    Archive:  General_HZXM_IPC_HI3516C_53H20L_V4.02.R11.20131108_ALL.bin
      inflating: Install                 
      inflating: u-boot-all.bin.img      
      inflating: web-x.cramfs.img        
      inflating: custom-x.cramfs.img     
      inflating: user-x.cramfs.img       
      inflating: romfs-x.cramfs.img      
      inflating: logo-x.cramfs.img       
      inflating: InstallDesc
    

    We look at the contents of Install:
    {
       "Commands" : [
          "burn custom-x.cramfs.img custom",
          "burn romfs-x.cramfs.img romfs",
          "burn user-x.cramfs.img user",
          "burn logo-x.cramfs.img logo",
          "burn web-x.cramfs.img web"
       ],
       "Devices" : [
          [ "53H20L", "1.00" ]
       ]
    }
    

    InstallDesc:
       "UpgradeCommand" : [
          {
             "Command" : "Burn",
             "FileName" : "u-boot-all.bin.img"
          },
          {
             "Command" : "Burn",
             "FileName" : "custom-x.cramfs.img"
          },
          {
             "Command" : "Burn",
             "FileName" : "romfs-x.cramfs.img"
          },
          {
             "Command" : "Burn",
             "FileName" : "user-x.cramfs.img"
          },
          {
             "Command" : "Burn",
             "FileName" : "web-x.cramfs.img"
          },
          {
             "Command" : "Burn",
             "FileName" : "logo-x.cramfs.img"
          }
       ],
       "Hardware" : "53H20L",
       "Vendor" : "General"
    }
    

    The word u-boot-all suggests that img files are images of the U-boot loader, so we put the appropriate package:
    root@xc:~/firmware# apt-get install u-boot-tools
    

    We look at the files we had in the archive:
    root@xc:~/firmware# file u-boot-all.bin.img 
    u-boot-all.bin.img: u-boot legacy uImage, linux, Linux/ARM, Firmware Image (gzip), 524288 bytes, Fri Nov  8 05:15:49 2013, Load Address: 0x00000000, Entry Point: 0x00080000, Header CRC: 0x8A551AA8, Data CRC: 0x8290AD90
    root@xc:~/firmware# file romfs-x.cramfs.img 
    romfs-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, OS Kernel Image (gzip), 4100096 bytes, Fri Nov  8 05:16:04 2013, Load Address: 0x00080000, Entry Point: 0x00580000, Header CRC: 0xD16AC90F, Data CRC: 0x54CDD868
    root@xc:~/firmware# file user-x.cramfs.img 
    user-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, OS Kernel Image (gzip), 7602112 bytes, Fri Nov  8 05:16:02 2013, Load Address: 0x00580000, Entry Point: 0x00CC0000, Header CRC: 0x106C19AD, Data CRC: 0x6D54ADA7
    root@xc:~/firmware# file web-x.cramfs.img 
    web-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 1572800 bytes, Fri Nov  8 05:15:51 2013, Load Address: 0x00CC0000, Entry Point: 0x00E40000, Header CRC: 0x87611FE5, Data CRC: 0x6BD90EBD
    root@xc:~/firmware# file custom-x.cramfs.img 
    custom-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 262080 bytes, Fri Nov  8 05:15:49 2013, Load Address: 0x00E40000, Entry Point: 0x00E80000, Header CRC: 0xF7C82692, Data CRC: 0x5A27F74C
    root@xc:~/firmware# file logo-x.cramfs.img 
    logo-x.cramfs.img: u-boot legacy uImage, linux, Linux/ARM, Standalone Program (gzip), 262080 bytes, Fri Nov  8 05:15:47 2013, Load Address: 0x00E80000, Entry Point: 0x00EC0000, Header CRC: 0x4FE4A821, Data CRC: 0xF6671BD1
    

    Please pay attention to two parameters Load Address and Entry Point. During the first assembly, I forgot to specify them, by default they became zeros, and this is the address of the bootloader, which turned out to be wiped after the firmware! Because of this, I spent an extra hour restoring - I had to remove the camera from the street, disassemble, and restore the firmware on the programmer. (Although it’s not for nothing that he dismantled the camera, he added a bag of silica gel to the casing to remove any moisture from the air.)

    Now a little explanation: the .img image from this firmware is a slightly modified image of the cramfs file system. Here there can be read in detail. To bring the image back to normal, you need to cut off 64 bytes of the header.
    root@xc:~/firmware# dd bs=1 skip=64 if=logo-x.cramfs.img of=logo-x.cramfs
    262080+0 записей получено
    262080+0 записей отправлено
    скопировано 262080 байт (262 kB), 0,891322 c, 294 kB/c
    

    For other files, the commands are similar.
    We look at what happened:
    root@xc:~/firmware# file logo-x.cramfs 
    logo-x.cramfs: Linux Compressed ROM File System data, little endian size 28672 version #2 sorted_dirs CRC 0xe29e6340, edition 0, 199 blocks, 2 files
    

    Already looks like cramfs. To work with cramfs images, install or update the appropriate package:
    root@xc:~/firmware# apt-get install cramfsprogs
    

    Unpack the images:
    root@xc:~/firmware# cramfsck -x logo logo-x.cramfs
    root@xc:~/firmware# cramfsck -x user user.cramfs
    root@xc:~/firmware# cramfsck -x romfs romfs-x.cramfs
    root@xc:~/firmware# cramfsck -x web web-x.cramfs
    root@xc:~/firmware# cramfsck -x custom custom-x.cramfs
    

    I do not create directories, they will be created automatically.
    The loader cannot be unpacked like that, this is not a cramfs image, but it should not be touched.

    What's inside


    I’ll quickly go through the contents of each file inside the firmware archive:
    • InstallDesc - describes the actions that need to be performed with these files when updating the firmware, install-script.
    • logo-x.cramfs.img - a picture in the format 800x600 with the logo of the manufacturer, which appears when the device boots.
    • romfs-x.cramfs.img - the linux operating system itself for the ARM architecture
    • u-boot-all.bin.img - U-boot loader
    • custom-x.cramfs.img - contains the name of the platform and additional settings
    • user-x.cramfs.img - application software, including Sofia - the DVR program itself
    • web-x.cramfs.img - pictures of the web interface, web.cab - plug-in for Internet Explorer with localization, manufacturer logos.

    We are interested in romfs-x.cramfs.img, since this is where the passwd file is located, in which the password is stored. Here are its contents, those who wish can try to smuggle:
    root:$1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0:0:0:root:/:/bin/sh
    

    I just generated a new hash on the site and changed it in the file.

    Putting it back


    After the changes made, you need to pack everything back:
    root@xc:~/firmware# mkcramfs romfs romfs-x.cramfs
    Directory data: 3624 bytes
    Everything: 4004 kilobytes
    Super block: 76 bytes
    CRC: 28c62b9b
    

    Remember, I focused on the values ​​of Load Address and Entry Point? It's time to remember them and add to the team.
    Create the U-boot image:
    root@xc:~/firmware# mkimage -A arm -O linux -T ramdisk -n "linux" -e 0x00580000 -a 0x00080000 -d romfs-x.cramfs romfs-x.cramfs.img
    Image Name:   linux
    Created:      Fri Feb 21 14:27:38 2014
    Image Type:   ARM Linux RAMDisk Image (gzip compressed)
    Data Size:    4100096 Bytes = 4004.00 kB = 3.91 MB
    Load Address: 00080000
    Entry Point:  00580000
    

    By the way, in order to update one module it is not necessary to flash the entire firmware, it is enough to put only the necessary one and edit the Install and InstallDesc files, leaving only the necessary lines.
    We put the received files in a separate directory, let it be new. We give the command:
    root@xc:~/new# zip -D -X firmware.bin *
      adding: Install (deflated 22%)
      adding: InstallDesc (deflated 30%)
      adding: romfs-x.cramfs.img (deflated 0%)
    

    Everything, the firmware is ready. It remains only to flash it through the web interface through the update item

    Warning


    By following the recommendations from this article, you do at your own peril and risk. The author is not responsible for your actions. Having made a mistake when modifying the firmware, you can easily get a brick that can only be restored on the programmer. Therefore, if you are not confident in your actions, do not do this.

    References


    Burn-in root shell in Vesta IP cameras and not only
    GNU / Linux and a device on Rockchip 2918
    Hacking RAM disks

    Also popular now: