CVS Video Camera Firmware Dissassembly

Many things are pulled from here, a dissassembly of 3.40 firmware.

My goal in this project is to understand how the partition table on the flash works, and figure out how to extend the P4 partition in order to fit longer sounds and more detailed images and fonts. Long-term goals include rewriting the GUI of the camera to be more user-friendly. I am just getting started.

Changelog

Nov 21st, 2005 Small update.. added links to Ops and cleaned up some wording.
Nov 5th, 2005 dismipper-linux-0.9.1 posted, confirmed to work. Added more v3.40 info, clarified some things.
Nov 2nd, 2005 Added v3.40 firmware info; pulled dismipper-linux for now because it doesn't work.
Oct 29th, 2005 Initial version of this page created, with what I know so far.

Extracting firmware from the device

It is assumed that you've already used some method of breaking into your v3.40 or v3.62 camera, and can run Ops successfully.

You should also have access to a linux computer, although there's no reason you can't do the stuff below on cygwin or something similar, it just needs the GNU toolset to be present. Familiarity with the command-line is a must (for now). Commands to execute at a prompt are in italics.

TODO: Compile some windows binaries

Step 1: Extract the flash

  1. Plug the camera in, and fire up Ops
  2. Click Open Camcorder, then Unlock
  3. If you're unsure what version of camera you own, scroll the message window up a little bit. It should say "Camera revision retrieved from camcorder: xx.xx". This guide is appropriate for 03.40 and 03.62 cameras. *
  4. Click Download Flash, "All Accessable Flash" should be selected, click OK.
  5. Specify a filename ("flash.dump" for example), it will be exactly 128MB.
* On 03.70 cameras, you cannot download the part of the flash the contains the firmware. It may still be possible to fetch the firmware from memory though, see here and here.

Step 2: Get the firmware out of the flash

The firmware starts at offset 1536 and is 1334428 bytes long in v3.40 camers and 1334868 bytes in 3.62 cameras. You can actually dump more then you need, it won't confuse objdump; I originally dumped 2mb and it worked fine as well.

Win32 users should download dd for win32, and extract it to c:\winnt\system32\; Linux users already have dd installed.

Open up a console and go into the directory where you saved flash.dump, then execute:

dd if=flash.dump of=firmware.o bs=1 skip=1536 count=[size]

Where [size] is either 1334428 (3.40) or 1334868 (3.62). You should now have a firmware.o ELF binary.

Step 3: Compile a MIPS version of GNU Binutils

  1. Download http://ftp.gnu.org/gnu/binutils/binutils-2.16.1.tar.gz
  2. Extract it and go into the created directory: tar xvfz binutils-2.16.1.tar.gz; cd binutils-2.16.1
  3. Configure it as a MIPS cross-compiler: ./configure --target=mips
  4. Compile it: make
  5. Give the newly generated objdump a new name, so as not to conflict with the old one. objdump-mips seems like the reasonable choice. Put it somewhere you won't forget it, like your home directory: cp binutils/objdump ~/objdump-mips

Step 4: Dissassemble the firmware using objdump

If you're curious as to exactly what you're dealing with, you can now view the ELF headers:
objdump-mips -x firmware.o
You should get the following output for 3.62 firmware (a 3.40 header dump is available here), if you've done everything correctly so far:
firmware.o:     file format elf32-littlemips
firmware.o
architecture: mips:isa32, flags 0x00000002:
EXEC_P
start address 0x80000600

Program Header:
    LOAD off    0x000000d4 vaddr 0x80000180 paddr 0x80000180 align 2**0
         filesz 0x0000013c memsz 0x0000013c flags r-x
    LOAD off    0x00000220 vaddr 0x80000600 paddr 0x80000600 align 2**5
         filesz 0x0012e344 memsz 0x0012e344 flags r-x
    LOAD off    0x0012e568 vaddr 0x8012e948 paddr 0x8012e948 align 2**4
         filesz 0x0000a830 memsz 0x000173c8 flags rw-
    LOAD off    0x00138d9c vaddr 0x90009800 paddr 0x90009800 align 2**2
         filesz 0x00000400 memsz 0x00000400 flags rw-
    LOAD off    0x0013919c vaddr 0xbfc08000 paddr 0xbfc08000 align 2**2
         filesz 0x00000210 memsz 0x00000210 flags rwx
private flags = 50000001: [no abi set] [mips32] [not 32bitmode]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .spc0         00000210  bfc08000  bfc08000  0013919c  2**2
                  CONTENTS, ALLOC, LOAD, CODE
  1 .spc1         00000000  bfc09000  bfc09000  001393ac  2**0
                  CONTENTS
  2 .spc2         00000000  bfc09400  bfc09400  001393ac  2**0
                  CONTENTS
  3 .spc3         00000000  bfc09800  bfc09800  001393ac  2**0
                  CONTENTS
  4 .spd0         00000000  90008000  90008000  001393ac  2**0
                  CONTENTS
  5 .spd1         00000000  90009000  90009000  001393ac  2**0
                  CONTENTS
  6 .spd2         00000000  90009400  90009400  001393ac  2**0
                  CONTENTS
  7 .spd3         00000400  90009800  90009800  00138d9c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .exception    0000013c  80000180  80000180  000000d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .boot         00000040  80000600  80000600  00000220  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .text         0012e168  80000640  80000640  00000260  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 __ex_table    00000010  8012e7a8  8012e7a8  0012e3c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .scratch      0000011c  8012e7b8  8012e7b8  0012e3d8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .scratchpad3  00000070  8012e8d4  8012e8d4  0012e4f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .data         0000a818  8012e948  8012e948  0012e568  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 15 .data1        00000018  80139160  80139160  00138d80  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .sbss         000005c4  80139178  80139178  00138d98  2**2
                  ALLOC
 17 .bss          0000c5d0  80139740  80139740  00138d9c  2**4
                  ALLOC
SYMBOL TABLE:
no symbols
Now you're ready to do the decompile. Execute:
objdump-mips -h -D -M reg-names=r3000 firmware.o > firmware.hd
This will generate firmware.hd, the input to dismipper.

Step 5: Compile dismipper

I have patched dismipper-0.9 to run on Linux (thanks CVSFan), and provided a makefile.
  1. Download dismipper-0.9.1-linux.tar.gz
  2. Extract it and go into the created directory: tar xvfz dismipper-0.9.1-linux.tar.gz; cd dismipper-0.9.1-linux
  3. Compile it: make
  4. Put it somewhere you won't forget it, like your home directory: cp dismipper ~

Step 6: Run dismipper

From the directory with firmware.hd, execute:
dismipper > firmware.lst
And open up firmware.lst in your favorite editor!

Problems

Doesn't give very good output on 3.62 firmware, as the firmware.comments is 3.40 specific.

Comments

Comments/suggestions? E-mail kRYPT (krypt@mountaincable.net)