Nikon Firmware Insights #02

So once the D5100 1.01 firmware was update was released, I couldn’t help but decrypt it.

As noted in the previous post, the bundle is checksum’ed, but I didn’t mention that each sub-file is also checksum’ed. But you can see the checksum at the end of the files:

File Checksum
File Checksum

Now on some Pentax forum I was reading about people wondering if the checksum was checked. So I altered the help file text for the viewing firmware information to make the ‘c’ of camera upper case.

D5100 Help Text
D5100 Help Text
Firmware version
Firmware version

Now the file is just XOR’d with the larger one time pad discussed earlier, and ‘c’ to ‘C’ is just XOR’ing with 0x20, applying the same XOR to the encrypted file at the same location, will have the net result of making the output upper case.

I put this altered firmware on a SD stick, and popped in into the D5100. Long story short, it recognized the update, but once I started the update, it quit really early in the process. The amount of time I’d expect for the checksum to be checked…

Update?
Update?

So I then turned to the internet for checksum algorithms, and it doesn’t appear to be a CRC-16-anything, as I brute forced the full possibility space, that was a fun adventure in multi-threading batch processing. Nor does it seam to be a Fletcher’s Checksum.

So now I’m up to searching for the answer in code…

[Update: 25 Nov] Answer found by Roos, see here

Interested in more, come join the us at Nikon Hacker, or use the Online Patch Tool (Help)

Comments:

Max 2011-11-20 13:30:36

What parameters did you use for searching for the CRC? I assume you swept through all possible polynomials, but there are two other parameters : initial value and bit order. Sometimes you have to start w/ 0xffff and byte-swap, depending on how the HW was implemented. Then to make matters worse, you might have a starting point that ignores the header or other parts of the content. For 16-bits brute force C code is good, but if you have to get into anything wider, FPGAs are handy :)


Simeon 2011-11-20 13:55:50

Yes, I swept the from 0x0 - 0x20000, as the code I had, marked both 16th bit and 1st, so the key was larger than a WORD. I didn’t however try swapping the word order, and I’d not be surprised if that was the issue due to FR chip is big endian.


roos 2011-11-24 15:49:19

Big thanks Simeon. We did it, or rather my friend Yann did most of the work. We have now loaded a hacked firmware into my D7000. Pics are here: http://www.flickr.com/people/69296392@N07/

D7000 A and B files use xmodem type CRC16, big endian encoding on the whole file except the checksum itself. The bundled file doesn’t need to be signed, the camera loads it fine anyway. We didn’t do much testing on the D5100 or the D3s files, however we couldn’t make it work with the same algorithm.


Simeon 2011-11-24 21:16:47

WOOT! Well done… let the fun begin.


Simeon 2011-11-24 23:08:31

Just confirmed that the B firmware for the D7000 is using the big endian CRC16, but seems the FR CPU is big endian, that implies they copied the little endian code.

You’re also correct, it does not work for the D3100 or D5100.


roos 2011-11-25 01:56:07

I’ll see if i can get a disassembler working and read up on the hw and os docs. I have an idea that modding the record movie button to a af-on button i non-lw mode may be a first and pretty straight forward usefull mod.


Simeon 2011-11-25 01:59:48

Super excited for you. I wish the D5100 checksum turned out to be so easy…


Simeon 2011-11-25 02:02:29

Hold the phone Batman!, the A firmware checksums all workout fine using the above mentioned method, but the B’s don’t… the plot thickens…


roos 2011-11-25 02:06:25

We tried quite a few algorithms before finding the right one. Each of them in different byte orders and both including and excluding the checksum bytes itself (presuming they were the same as the bytes before them). One of them might just be working on the other cams or there might be a seed to the argorithm in case it has to be brute forced. Im pretty sure though that now that we (and mostly you) have made a proof of concept on the D7000 the rest will follow as others want to mod their cams too.


Yann Vernier 2011-11-25 02:47:38

That’s very good news. It makes it more probable (to my mind) that the checksum of the B firmware is still a CRC-16; I would guess that they changed the initial value, not the polynom. If so, finding it should be fairly easy. If it’s a post-checksum xor, you’ll just need two versions. It’s a twist, but certainly not insurmountable.


Simeon 2011-11-25 03:19:48

Agreed on all points…


Kyle 2011-11-25 06:26:14

That is absolutely amazing! Really great to see what Simeon and you guys have managed to do!


Vicne 2011-11-25 09:34:35

For what it’s worth, I used http://fsumfe.sourceforge.net to do the checks and what it calls “crc16_zmodem” (which after googling seems to be a reversed xmodem indeed) is valid for the following files I tested :
D300 1.10 (A+B)
D300s 1.01 (A+B)
D3100 1.02 (A)
D5100 1.01 (A)
D7000 1.01 (A+B)
D7000 1.02 (A+B)
D7000 1.03 (A+B)

Not OK for :
D3100 1.02 (B)
D5100 1.01 (B)

D700 firmware doesn’t seem to be encrypted using the method Simeon used (at least Vitaly’s ntool says “Wrong firmware file”).

Strange that we have only those “B” fw using another CRC…

Note : D300 was not encrypted at all

Just my 2 cents.

Vicne


rob 2011-11-25 12:53:20

Holy shit this is so cool. I wish i could actually do this. Sadly all i can do is watch as more pieces to the puzzle come in to play. nice job guys


Simeon 2011-11-25 15:56:00

Cheers for the support.


Max 2011-11-26 15:41:27

Looks like this was it, nice work guys!