How to extract a .OV (extention) firmware file?

G33RT

n3wb
Joined
Apr 15, 2017
Messages
24
Reaction score
1
Location
Belgium
Hi,

Does someone knows how to extract a .OV (extention) firmware file?

Any help on this is welcome!
 
Joined
Aug 3, 2015
Messages
3,827
Reaction score
12,289
Location
Charlotte
Hi,

Does someone knows how to extract a .OV (extention) firmware file?

Any help on this is welcome!
Use any of the free hex editors available on the web (I prefer Frhed, the free hex editor) to open the file, and post a screen shot here.
Otherwise, use a GNU/Linux/BSD system and try the command 'file xxxxxxxxx.ov'.
 

alastairstevenson

Staff member
Joined
Oct 28, 2014
Messages
15,966
Reaction score
6,795
Location
Scotland
It's a bit of an open-ended question, and quite a common file extension for firmware but -
binwalk the file, inspect and validate (usually quite a few wrong guesses) the results and write a shellscript to split out the components, then treat each component according to its type.
 

alastairstevenson

Staff member
Joined
Oct 28, 2014
Messages
15,966
Reaction score
6,795
Location
Scotland
The firmware file consists of a "Linux-3.0.8" kernel and a JFFS2 file system.
The devinfo in the file system states that it is for a "VVVIPC1507283580" device.
In the file system are the usual Linux structures, and modules for a variety of Omnivision and Aptiva sensors, and a web GUI.

*edit*
And the telnet root password just popped up - it's cat1029
 
Last edited:

G33RT

n3wb
Joined
Apr 15, 2017
Messages
24
Reaction score
1
Location
Belgium
Hmmm so that "devinfo" contains for what device it is mented as I correctly understand.
What do we now about VVVIPC1507283580 a search on Google gives no results.
My camera hardware is Hi3518(C) I think it's a "C" and a second AR0130 board.
 

alastairstevenson

Staff member
Joined
Oct 28, 2014
Messages
15,966
Reaction score
6,795
Location
Scotland
I have (had, just selling it on eBay) an Amovision Q645R camera and an IPCC B10 both with that 'VVVIPC...' model code prefix. I think it's fairly generic.
The firmware may have support for these sensors:
echo -e "Available sensors: ar0130, imx104, icx692, ov9715, 9m034, imx122, mt9p006"
 
Joined
Aug 3, 2015
Messages
3,827
Reaction score
12,289
Location
Charlotte
bootargs=mem=45M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:256K(boot),2560K(kernel),12544K(rootfs),64K(key),960K(config)
bootcmd=mw 0x200F0104 1;bootstart;upgrade;sf probe 0;sf read 0x82000000 0x00040000 0x280000;bootm 0x82000000
bootdelay=1
baudrate=115200
ethaddr=00:00:18:18:ee:66
ipaddr=192.168.0.17
serverip=192.168.0.98
netmask=255.255.255.0
bootfile="uImage"

The bootargs and mtdparts values are most helpful when attempting to manually restore/overwrite the firmware partitions.
 

G33RT

n3wb
Joined
Apr 15, 2017
Messages
24
Reaction score
1
Location
Belgium
I just have received a firmware from someone at a Russian forum.
The firmware is for a IPS-HA1312L 1.3MP 960P Hi3518C + AR0130 exactly the same hardware as my IPCC-B13L camera.
 

Attachments

alastairstevenson

Staff member
Joined
Oct 28, 2014
Messages
15,966
Reaction score
6,795
Location
Scotland
I was asked by @G33RT how the firmware could be extracted, so I said I'd put up an example to share with others.
Hopefully we'll see some refinement contributions.

This is an example of how you might take a first look at an embedded Linux firmware update file.
This 'first-cut' look is not aimed at a rigorous unpack/modify/repack but rather for getting an overview of the contents.

Create a couple of folders, to hold the contents, and a temporary mount point, and any files.

Useful for a first look is to use 'binwalk'. This can give some good clues, though it also can give lots of false indications, as well as miss lots of stuff.
In this case, the results are somewhat sparse.
The uImage signature should be reliable (as opposed to just a Linux copyright string), as should the jffs2 indication.
The gzip data looks like a false match, judging from the lack of date.
And there is nothing matched in the 131k bytes preceding the uImage, so we'll probably have to inspect that for clues with a hex editor.
But first, let's cut out the chunks that seem like a reasonable match. The sizes are taken directly from the binwalk numbers.
The 'file' command can be pretty useful in helping figure file types.
Code:
alastair@PC-I5 ~/ipcc $ ll
total 13076
drwxr-xr-x  2 alastair alastair     4096 Apr 23 11:50 ./
drwxr-xr-x 68 alastair alastair     4096 Apr 23 09:13 ../
-rw-r--r--  1 alastair alastair     6296 Apr 23 10:22 readme.txt
-rw-r--r--  1 alastair alastair 13369612 Apr 20 18:23 UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov
alastair@PC-I5 ~/ipcc $ mkdir tmp_mount
alastair@PC-I5 ~/ipcc $ mkdir fw_contents
alastair@PC-I5 ~/ipcc $ binwalk UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov

DECIMAL       HEX           DESCRIPTION
-------------------------------------------------------------------------------------------------------
131340        0x2010C       uImage header, header size: 64 bytes, header CRC: 0x6D151FDF, created: Wed Sep 17 18:14:06 2014, image size: 2519356 bytes, Data Address: 0x80008000, Entry Point: 0x80008000, data CRC: 0xC84C5528, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-3.0.8"
153948        0x2595C       gzip compressed data, from Unix, NULL date: Thu Jan  1 01:00:00 1970, max compression
2687244       0x29010C      JFFS2 filesystem, little endian

alastair@PC-I5 ~/ipcc $ tail -c +131341 UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov | head -c 2555904 > chunk_uImage
alastair@PC-I5 ~/ipcc $ tail -c +2687245 UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov > chunk_jffs2
alastair@PC-I5 ~/ipcc $ head -c 131340 UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov > chunk_header
alastair@PC-I5 ~/ipcc $ ll
total 26144
drwxr-xr-x  4 alastair alastair     4096 Apr 23 12:06 ./
drwxr-xr-x 68 alastair alastair     4096 Apr 23 09:13 ../
-rw-r--r--  1 alastair alastair   131340 Apr 23 12:06 chunk_header
-rw-r--r--  1 alastair alastair 10682368 Apr 23 12:02 chunk_jffs2
-rw-r--r--  1 alastair alastair  2555904 Apr 23 12:02 chunk_uImage
drwxr-xr-x  2 alastair alastair     4096 Apr 23 11:58 fw_contents/
-rw-r--r--  1 alastair alastair     6296 Apr 23 10:22 readme.txt
drwxr-xr-x  2 alastair alastair     4096 Apr 23 11:58 tmp_mount/
-rw-r--r--  1 alastair alastair 13369612 Apr 20 18:23 UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov
alastair@PC-I5 ~/ipcc $ file *
chunk_header:                                    data
chunk_jffs2:                                     Linux jffs2 filesystem data little endian
chunk_uImage:                                    u-boot legacy uImage, Linux-3.0.8, Linux/ARM, OS Kernel Image (Not compressed), 2519356 bytes, Wed Sep 17 18:14:06 2014, Load Address: 0x80008000, Entry Point: 0x80008000, Header CRC: 0x6D151FDF, Data CRC: 0xC84C5528
fw_contents:                                     directory
readme.txt:                                      ASCII text, with very long lines
tmp_mount:                                       directory
UPG_ipc3580ar-w7-M20-hi3518e-20150728_013643.ov: data
alastair@PC-I5 ~/ipcc $
Now for the trickier stuff - extracting the jffs2 contents.
This requires creating a dummy block device to mount the jffs2 file system contents, copying the files to permanent storage, and tidying up after.
Code:
alastair@PC-I5 ~/ipcc $ ll /dev/mtd*
ls: cannot access /dev/mtd*: No such file or directory
alastair@PC-I5 ~/ipcc $ sudo modprobe mtdram total_size=32768
[sudo] password for alastair:
alastair@PC-I5 ~/ipcc $ sudo modprobe mtdblock
alastair@PC-I5 ~/ipcc $ ll /dev/mtd*
crw------- 1 root root 90, 0 Apr 23 12:10 /dev/mtd0
crw------- 1 root root 90, 1 Apr 23 12:10 /dev/mtd0ro
brw-rw---- 1 root disk 31, 0 Apr 23 12:10 /dev/mtdblock0
alastair@PC-I5 ~/ipcc $ sudo dd if=chunk_jffs2 of=/dev/mtdblock0
20864+0 records in
20864+0 records out
10682368 bytes (11 MB) copied, 0.0716073 s, 149 MB/s
alastair@PC-I5 ~/ipcc $ sudo mount -t jffs2 /dev/mtdblock0 ~/ipcc/tmp_mount
alastair@PC-I5 ~/ipcc $ ll tmp_mount
total 6
drwxr-xr-x 28 root     root         0 Jan  1  1970 ./
drwxr-xr-x  4 alastair alastair  4096 Apr 23 12:06 ../
drwxr-xr-x  3 alastair wireshark    0 Sep 28  2013 bin/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 boot/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 cifs/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 cifstest/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 dev/
drwxr-xr-x  5 alastair wireshark    0 Jul 27  2015 etc/
drwxr-xr-x  2 alastair wireshark    0 Sep 28  2013 font/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 home/
lrwxrwxrwx  1 alastair wireshark    9 Feb 19  2014 init -> sbin/init*
drwxrwxr-x  3 alastair wireshark    0 Jul  1  2015 komod/
drwxr-xr-x  2 alastair wireshark    0 Apr 19  2012 lib/
lrwxrwxrwx  1 alastair wireshark   11 Feb 19  2014 linuxrc -> bin/busybox*
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 lost+found/
drwxr-xr-x  3 alastair wireshark    0 Jul 27  2015 mnt/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 nfsroot/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 opt/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 proc/
drwxr-xr-x  2 alastair wireshark    0 Dec 10  2007 root/
lrwxrwxrwx  1 alastair wireshark   15 Dec 19  2014 rt -> /mnt/config/usr
drwxr-xr-x  2 alastair wireshark    0 Feb 19  2014 sbin/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 share/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 sys/
drwxr-xr-x  3 alastair wireshark    0 Jul 27  2015 system/
drwxr-xr-x  2 alastair wireshark    0 Jul  9  2013 tmp/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 tmpfs/
drwxr-xr-x  2 alastair wireshark    0 Jul 27  2015 tmpfs2/
drwxr-xr-x  6 alastair wireshark    0 Jul 27  2015 usr/
drwxr-xr-x  4 alastair wireshark    0 Jul  9  2013 var/
alastair@PC-I5 ~/ipcc $ cp -R tmp_mount/* fw_contents
alastair@PC-I5 ~/ipcc $ sudo umount  ~/ipcc/tmp_mount
alastair@PC-I5 ~/ipcc $ sudo modprobe -r mtdram
alastair@PC-I5 ~/ipcc $ sudo modprobe -r mtdblock
alastair@PC-I5 ~/ipcc $
So far, so good.

But what about that chunk_header?
Well, another useful tool is 'strings'.
When this is run against the file, the result is a set of strings that's typical of u-boot. And the size is about right too.
Example : "U-Boot 2010.06-svn3738 (Jul 14 2015 - 18:33:44)"
There is more though, it looks like it may have built-in firmware update code:
Code:
do_upgrade now
upgradeAddr:0x%x
upgradeAddr erro
------------------Upgrade Version 1------------------
 magic:%x
 version:%x
 UpgradeBitmap:%x
 BootLen:%x
 BootAddr:%x
 BootPartitionLen:%x
 KernelLen:%x
 KernelAddr:%x
 KernelPartitionLen:%x
 RootfsLen:%x
 RootfsAddr:%x
 RootPartitionLen:%x
 AppLen:%x
 AppAddr:%x
 AppPartitionLen%x
 ConfigAddr:%x
 ConfigLen:%x
 ConfigPartitionLen:%x
 ParaAddr:%x
 ParaLen:%x
 ParaPartitionLen:%x
upgrade fail magic error
------------------start check crc------------------
check crc success
check crc failure
------------------start upgrade boot------------------
------------------end upgrade boot------------------
------------------start upgrade kernel------------------
------------------end upgrade kernel------------------
------------------start upgrade rootfs------------------
------------------end upgrade rootfs------------------
------------------start upgrade app------------------
------------------end upgrade app------------------
------------------start upgrade config------------------
------------------end upgrade config------------------
------------------start upgrade para------------------
------------------end upgrade para------------------
------------------upgrade success------------------
------------------clean upgrade pos------------------
------------------Upgrade Version 2------------------
 magic:%x
 version:%x
 UpgradeBitmap:%x
 BootLen:%x
 BootAddr:%x
 BootFlashStartAddr:%x
 BootPartitionLen:%x
 KernelLen:%x
 KernelAddr:%x
 KernelFlashStartAddr:%x
 KernelPartitionLen:%x
 RootfsLen:%x
 RootfsAddr:%x
 RootfsFlashStartAddr:%x
 RootPartitionLen:%x
 AppLen:%x
 AppAddr:%x
 AppFlashStartAddr:%x
 AppPartitionLen%x
 ConfigAddr:%x
 ConfigFlashStartAddr:%x
 ConfigLen:%x
 ConfigPartitionLen:%x
 ParaFlashStartAddr:%x
 ParaAddr:%x
 ParaLen:%x
 ParaPartitionLen:%x
upgrade fail magic11 error
 magic:%08x
 version:%08x
 crc:%08x
 envcnt:%08x
setenv %s %s
------------------set boot env success------------------
upgradepos
upgradePos null!!!
upgradePos %#x!!!
upgrade board
print monitor version
%-*s- %s
Unknown command '%s' - try 'help' without arguments for list of all known commands
runtop18e #
No input devices available!
No output devices available!
No error devices available!
*** Warning - bad CRC, using default environment
SPI Flash
Environment SPI flash not initialized
Warning: Erase size 0x%08x smaller than one erase block 0x%08x
         Erasing 0x%08x instead
Erasing SPI flash, offset 0x%08x size %s ...
Writing to SPI flash, offset 0x%08x size %s ...
Comments / critique / extras / improvements welcome.
 

alastairstevenson

Staff member
Joined
Oct 28, 2014
Messages
15,966
Reaction score
6,795
Location
Scotland
Thanks!
Yes, for all it's elegant simplicity, dd is a powerful tool.
I would usually use it for cutting chunks out of a file, but I find that to save figuring a common input and output block size for the skips and seeks and counts I get lazy and use a block size of 1
Which might have raised a few eyebrows on here for its crudeness lol!
 
Top