Prologue
In my previous article I showed how to extract, fix and flash the firmware with UART to make MJPEG streaming working again.In this article I'll show you how to add features like telnet and sign the firmware to flash the DVR without opening it.
Preparing Firmware
Extracting firmware
With the last version of binwalk (and all dependences installed), to extract the firmware you only need to run:
It will create a _AppImg_4.bin.extracted folder containing$ binwalk -e AppImg_4.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 200 0xC8 JFFS2 filesystem, little endian
- C8.jffs2 (the payload of the firmware, a jffs2 file system)
- jffs2-root/ (folder containing the extracted jffs2 file system)
Inside "jffs2-root" you will find a folder called "fs_1" containing the root file system.
Here is where we are going to work.
Modding firmware
Due to small size of the ROM, we can't add whatever we want directly inside the firmware image, so a solution is to use the internal Hard Drive and add only few lines of code inside the firmware to load at any boot our additional features.(On my DVR the Hard Drive is mounted on /mnt/HDD0 and USB Drive is mounted on /mnt/usb, so I'll use these paths for install and init scripts, but with newer of different firmware this location may vary)
The main script loaded during boot is "dvrApp", it is a bash script containing a lot of commands to launch all the services for recording videos, send notifications, update DDNS and many other things.
At the end of the file, just before the "exit $RETVAL" of the "start" switch case I added the following lines:
Obtaining something like this:#---- [s] EXTENSIONS ---- echo "Loading extensions..." if [ -f /mnt/usb/avext/install.sh ] && [ ! -f /mnt/HDD0/avext/.installed ] then /mnt/usb/avext/install.sh # launched after flash to install mods on Hard Drive fi if [ -f /mnt/usb/avext/init_usb.sh ] && [ ! -f /mnt/HDD0/avext/.disable_init_usb ] then /mnt/usb/avext/init_usb.sh # a "backdoor" to prevent bootloop elif [ -f /mnt/HDD0/avext/init_hdd.sh ] then /mnt/HDD0/avext/init_hdd.sh # main script on internal Hard Drive launched at any boot fi #/bin/sh # uncomment to get a command line via UART connection #---- [e] EXTENSIONS ----
[ ... ] cp /mnt/mtd/ReleaseResource.sh /bin sh /bin/ReleaseResource.sh & RETVAL=$? #---- [s] EXTENSIONS ---- echo "Loading extensions..." if [ -f /mnt/usb/avext/install.sh ] && [ ! -f /mnt/HDD0/avext/.installed ] then /mnt/usb/avext/install.sh fi if [ -f /mnt/usb/avext/init_usb.sh ] && [ ! -f /mnt/HDD0/avext/.disable_init_usb ] then /mnt/usb/avext/init_usb.sh elif [ -f /mnt/HDD0/avext/init_hdd.sh ] then /mnt/HDD0/avext/init_hdd.sh fi #/bin/sh #---- [e] EXTENSIONS ---- exit $RETVAL ;; stop) echo $"Shutting down mount root file system: ---->" # unmount filesystems echo exit $RETVAL ;; esac
Repacking firmware
Repacking the firmware is still not easy like extracting, but nothing of impossible.The ROM of my dvr is a nand (--no-cleanmarkers) and it has an erase block size of 128k (--eraseblock=0x20000).
After you installed mtd-utils, inside "fs_1" folder run:
# mkfs.jffs2 -r . -o ../AppImg_4mod.img --eraseblock=0x20000 --little-endian --no-cleanmarkers
Signing Firmware
Inside the firmware i found an executable called "upgradeHdr", who control the firmware integrity before flash the ROM when we made a firmware upgrade from USB drive.So I reversed it with IDA Pro and I made a set of tools in Python called Avtech-Firmware-Tools to sign, unsign and show info of the firmware on your computer (I'll extend this tool suite in the future to extract and patch the firmware automatically).
It requires python3.
Get original firmware info
Download my tool and run:$ ./avfwtools.py info -i AppImg_4.bin ** Show firmware info ** Product: H264DVRAV76T_4 Description: img Version: 1017 Checksum: 0x5278bd53
Sign custom firmware
With the info got from original firmware run:I modified version field to remind me that I have a custom firmware installed.$ ./avfwtools.py sign -i AppImg_4mod.img -o AppImg_4mod.bin -p H264DVRAV76T_4 -d img -v 1017mod ** Sign firmware ** Product: H264DVRAV76T_4 Description: img Version: 1017mod Checksum: 0x5278ce64 Firmware signed successfully
It's important to not modify the "Description field".
It's normal to get a different checksum, it is what DVR controls when flashing and it is calculated for the current firmware.
Now you have your signed custom firmware in AppImg_4mod.bin
Preparing USB
Now you need a FAT32 formatted USB drive to upgrade the DVR with the custom firmware and install all binaries, script and other many things you want add after flash.Copy signed custom firmware
In the root of your USB drive copy AppImg_4mod.bin and rename it AppImg_4.bin, like the original.The DVR checks for this file name when upgrading.
Extensions
Install script
Always in the root of the USB drive make a folder called "avext".Inside this folder create a text file called "install.sh" with this content:
#!/bin/sh cp -a /mnt/usb/avext/avext_hdd/ /mnt/HDD0/avext/ chmod 755 /mnt/HDD0/avext/* touch /mnt/HDD0/avext/.installed
Init script
Inside avext folder create another folder called "avext_hdd", this will be copied in the internal Hard Drive and will contain all the extensions you want to use.Inside avext_hdd create a text file called "init_hdd.sh" with this content:
In this file you can add anything you want launch at any boot.#!/bin/sh #enable telnet access /mnt/HDD0/avext/busybox-complete telnetd -p 23
Busybox
The firmware is already provided with the busybox, but it is missing a lot of features, so let's download a complete version of the busybox.For my DVR i downloaded busybox-armv4l but others versions may works too.
Then copy it inside avext_hdd and rename it "busybox-complete".
Final USB structure
For clarity:
- / (usb root) | |- AppImg_4.bin |- avext/ | | - install.sh | - avext_hdd/ | | - init_hdd.sh | - busybox-complete
Flashing Firmware
Upgrade from USB
Finally we have all ready to install our custom firmware on the DVR.Connect a mouse to a usb port on the DVR, right click and insert your administrator password (default: 0000 or 1234)
A menu like this will be showed.
Select SYSTEM, the icon at the top right corner.
In system menu go to TOOLS
And select SUBMIT on the right of UPGRADE.
Insert your prepared USB drive and go to take a (italian) coffee.
First boot
The extensions are installed during the first boot, so do NOT remove the USB drive until the DVR is totally booted (wait 5-10 minutes).Then you can remove the USB drive.
Access the DVR
Telnet
If all went OK, telnet would be accessible, so try to connect.$ telnet 192.168.2.10 Trying 192.168.2.10... Connected to 192.168.2.10. Escape character is '^]'. avtech login: root Password: Welcome to _ __ __ / \ \ \ / / / O \ \ \ / / / ___ \ \ \ / / / / \ \ \ V / /_/ \_\ \_/ For further information check: http://www.avtech.com.tw/ [root@avtech:/root]#
Default root password of my firmware was "avtech97", cracked with John the Ripper.
If yours is different you can connect with root privileges using an high privileged account of the DVR, like "admin:admin".
Future customizations
Whenever you want add features you can go to /mnt/HDD0/avext/ and modify init_hdd.shFor example adding:
If you break something in init_hdd.sh and your DVR stuck in boot loop, create a file called "init_usb.sh" in /avext/ folder of your USB drive and insert it during boot to try solving problem from there (for example enabling only telnet and then fixing from command line).# change root password echo "root:pass" | /mnt/HDD0/avext/busybox-complete chpasswd # start second web server on port 8080 /mnt/HDD0/avext/busybox-complete httpd -p 0.0.0.0:8080 -h /mnt/HDD0/avext/web/ # create a folder called "web" inside avext and put there some html files
When things are stable, if you want disable the boot backdoor you can do it creating a file called ".disable_init_usb" inside /mnt/HDD0/avext/
Custom Boot Logo
It's possible to change the boot logo without modify the firmware image.To change the boot logo you have to create a picture called "custom_logo.bmp" on the root of your USB drive and make the upgrade from tools menu.
custom_logo.bmp must be:
- about 320 x 240 pixel
- bitmap format
- max 8 bit in depth (256 colors)
- max 128 KB in size
You can easily create it with Paint on Windows and save as bitmap 256 colors, 16 colors or monochromatic.
If you have problem creating it, you can use this one as sample.
That's all!
Enjoy your unlocked DVR!
I hope I was clear, however for any question ask in comments.I'm not responsible for any damage to your DVR.