📚 OpenRCE is preserved as a read-only archive. Launched at RECon Montreal in 2005. Registration and posting are disabled.








Flag: Tornado! Hurricane!

 Forums >>  Target Specific - General  >>  Guessing a 16-bit Checksum Algorithm

Topic created on: April 14, 2007 02:59 CDT by bushing .

I'm trying to reverse-engineer the firmware files loaded onto my AVIC car GPS unit;  my goal is to eventually be able to modify the code on the unit, but I'd settle for being able to edit the strings file.  I can't seem to generate a valid checksum for the files.

The file format used has been easy enough to decode -- both code and data files use the same format with a 64-byte header, and the last 16 bits of each file appear to be a checksum.  (The gruesome details are in this forum post, if anyone's interested... it seems like I went a bit beyond the scope of that board, but oh well).  I was also able to determine that the header isn't included in the checksum.

Here's what I have to work with:
* Several files with valid checksums.  
* An "oracle" -- I can burn a DVDRW and use a service menu to force the unit to reflash using my modified files, but if the checksum fails, when it next starts it demands that I insert a DVD with a valid firmware image so that it can reflash.  So, it's not possible to automatically test for checksum collisions.
* The binary which contains the code that checks this firmware; I have about 400k of program data for the unit's NEC V830 microcontroller, and the fact that the failure messages are embedded tells me I should be able to figure it out by analyzing this file.  However, this is an obscure processor for which no good disassemblers exist; I have a partially-working IDA processor module, but it doesn't work well enough to figure out what code references what strings.

All that I've been able to do is try common 16-bit checksum algorithms on the data between the end of header and the checksum on some of the files, hoping that something will match.  I've tried:

* Summing each byte into a 16-bit variable, both big and little-endian
* Summing each halfword, both big and little-endian
* The above, using XOR instead of addition
* 16 bit CRC (CRC-16-CCITT, CRC-16-IBM)
* 1's complement of all of the above.

Nothing has matched.  Can anyone suggest a better approach?  (16-bit checksum algorithms don't seem to lend themselves to obvious magic lookup tables...)

  itsme     April 14, 2007 10:48.18 CDT
did you check if it is maybe 2 bytes of a hash function ( md5, sha1, sha256, ... )?
or 2 bytes of a crc32? or 2 bytes of a 32bit sum?

did you also calculate the checksum/crc including your checksum byte, maybe the total result is a constant value?

maybe something like the ppp frame checksum, which is a crc16 with polynomial 0x8408,  where the frame crc always is supposed to be 0xf0b8

or maybe one byte is the sum of the odd bytes, the other the sum of the even bytes?

  aeppert     April 17, 2007 16:34.42 CDT
I apologize upfront for not being familiar with the NEC V820 microcontroller.

Checks in firmware are always an interesting adventure.  There are several problems, that you generally run into:

1) Which algorithm? (This is of course the captain obvious one you have already done an excellent job of commenting!)

2) Where is the checksum _actually starting_ its' calculation from?  You mentioned the header was not included in the checksum, but I have seen instances where there the actual files checksumming did not begin until well after the header file - I was only assuming this was for some kind of future expansion or patching facility in these instances.

3) Is it really a 16bit checksum or simply a larger checksum that was truncated?  

These are only a handful of course.  My next question would be does the device have JTAG exposed?  If so, you might be able to perform some kind of debugging on the unit.

  bushing     April 17, 2007 19:55.38 CDT
> itsme: did you check if it is maybe 2 bytes of a hash function ( md5, sha1, sha256, ... )?
>or 2 bytes of a crc32? or 2 bytes of a 32bit sum?

I don't *think it's a complicated hash function, because I ran Ilfak's findcrypt2 plugin on it and it didn't find any magic constants.  Still, it's a possibility.  I'll update my little test program to generate those sums and print them out.

>did you also calculate the checksum/crc including your checksum byte, maybe the total result is a constant value?

Hmm... ok, I'll add that too

>maybe something like the ppp frame checksum, which is a crc16 with polynomial 0x8408,  where the frame crc always is supposed to be 0xf0b8

I've been afraid it might be something like that -- how would I find the polynomial if I can't find the crc routine in the firmware?  Then again, if there are only 2^16 different polynomials, I could always brute-force it and try them all.  (I have several files with the same kind of checksum, so I can make sure it matches all files.)

>or maybe one byte is the sum of the odd bytes, the other the sum of the even bytes?

If it's a simple sum (and not a checksum), I should be able to swap bytes (or halfwords?) and not make the checksum fail, so I will try that, too.

> aeppert: I apologize upfront for not being familiar with the NEC V820 microcontroller.
>
> Checks in firmware are always an interesting adventure.  There are several problems, that you generally run into:
>
> 1) Which algorithm? (This is of course the captain obvious one you have already done an excellent job of commenting!)
>
> 2) Where is the checksum _actually starting_ its\' calculation from?  You mentioned the header was not included in the checksum, but I have seen instances where there the actual files checksumming did not begin until well after the header file - I was only assuming this was for some kind of future expansion or patching facility in these instances.

I changed some bytes in the header and verified that it still loaded, but I didn't try more than that.  I'll try changing some of the bytes immediately after the header to see if that causes a failure.

>
> 3) Is it really a 16bit checksum or simply a larger checksum that was truncated?  

No clue.  I had looked at some 32bit cksums and didn't see anything, then I somehow decided that the V820 was a 16-bit processor, and so probably wouldn't be doing a full checksum.  (You'd think that the 32-bit opcodes would have clued me in there ... I'll go back and look again at the 32-bit numbers.)

> These are only a handful of course.  My next question would be does the device have JTAG exposed?  If so, you might be able to perform some kind of debugging on the unit.

That's a different idea entirely!  There's a connector, but you have to take apart the unit to reach it; it would probably be easier / better for me to fix my IDA module to correctly calculate memory references so I could find the routines.

Thanks for all of the great ideas -- that's why I came here :)  I'll post my IDA module in case it helps anyone.

  PSUJobu     April 17, 2007 21:18.59 CDT
Here's another "different" (but obvious) idea: You mentioned that there was an error message on the next bootup. Is this message in the firmware? I would think it likely that some sort of boot loader in Flash is generating this error, but it's worth a look.

On a related note, if there is a mechanism to update the boot loader (and you have such a file), reversing that code would give you the answer. I found some cases where the checksum routine was carried in a boot loader as well as in the main firmware, but unless there are strings it is a needle-in-the-haystack type of problem.

There was an interesting discussion spawned from a cracker about finding such "atypical" code (in that case serial number generation routines, in this case, a checksum routine). Some sort of histogram of opcodes to detect routines with an abnormal concentration of shifts and other bitwise math might help... I don't know of anything like this publicly available, but it seems like a good idea.

  bushing     May 17, 2007 05:47.22 CDT
Okay, I ended up deciding that the best use of my time would be to work on my V830 module... and I think, at last, I found the checksumming code.

I'm still trying to work through the specifics of this, but does this algorithm (or more likely, the lookup table) look familiar to anyone?

(Pardon the wonky disassembly, this is my first try at writing a processor module.)

checksum_func:
             ld.w    r11, 0(r6)      ; r11 = buf?
             ld.w    r12, 4(r6)      ; r12 = len?
             cmp     r12, 0          ; is len <= 0?
             ble     return_error
             mov     r13, #FFFFFFFFh
             shr     r13, #8
             movea   r14, lookup_table
             br     loc_40AE9C
loop:
             mov     r15, r13
             shr     r15, #8         ; r15 = r13 >> 8
             ld.b    r16, 0(r11)     ; r16 = *buf
             add     r11, #1         ; buf++
             xor     r16, r13        ; *buf ^= r13
             andi    r16, #FFh       ; *buf &= 0xFF
             shl     r16, #1         ; *buf << 1
             add     r14, r16
             ld.h    r17, 0(r16)     ; r17 = lookup_table [((*buf ^ r13) & 0xFF))]
             xor     r17, r15
             andi    r13, r17, #FFFFh
loc_40AE9C:
             add     r12, -1        ; len--
             cmp     r12, 0
             bge    loop
             xori    r13, #FFFFh ; r13 ^= 0x0000FFFF
             st.h    0(r7), r13  ; *r7 holds checksum?
             mov     r10, 0      ; r10 = 0 -> success?
             ret

return_error:
             mov     r10, #D00Ah
             ret

lookup_table:
            .word 0000h, 1189h, 2312h, 329Bh, 4624h, 57ADh, 6536h, 74BFh
            .word 8C48h, 9DC1h, AF5Ah, BED3h, CA6Ch, DBE5h, E97Eh, F8F7h
            .word 1081h, 0108h, 3393h, 221Ah, 56A5h, 472Ch, 75B7h, 643Eh
            .word 9CC9h, 8D40h, BFDBh, AE52h, DAEDh, CB64h, F9FFh, E876h
            .word 2102h, 308Bh, 0210h, 1399h, 6726h, 76AFh, 4434h, 55BDh
            .word AD4Ah, BCC3h, 8E58h, 9FD1h, EB6Eh, FAE7h, C87Ch, D9F5h
            .word 3183h, 200Ah, 1291h, 0318h, 77A7h, 662Eh, 54B5h, 453Ch
            .word BDCBh, AC42h, 9ED9h, 8F50h, FBEFh, EA66h, D8FDh, C974h
            .word 4204h, 538Dh, 6116h, 709Fh, 0420h, 15A9h, 2732h, 36BBh
            .word CE4Ch, DFC5h, ED5Eh, FCD7h, 8868h, 99E1h, AB7Ah, BAF3h
            .word 5285h, 430Ch, 7197h, 601Eh, 14A1h, 0528h, 37B3h, 263Ah
            .word DECDh, CF44h, FDDFh, EC56h, 98E9h, 8960h, BBFBh, AA72h
            .word 6306h, 728Fh, 4014h, 519Dh, 2522h, 34ABh, 0630h, 17B9h
            .word EF4Eh, FEC7h, CC5Ch, DDD5h, A96Ah, B8E3h, 8A78h, 9BF1h
            .word 7387h, 620Eh, 5095h, 411Ch, 35A3h, 242Ah, 16B1h, 0738h
            .word FFCFh, EE46h, DCDDh, CD54h, B9EBh, A862h, 9AF9h, 8B70h
            .word 8408h, 9581h, A71Ah, B693h, C22Ch, D3A5h, E13Eh, F0B7h
            .word 0840h, 19C9h, 2B52h, 3ADBh, 4E64h, 5FEDh, 6D76h, 7CFFh
            .word 9489h, 8500h, B79Bh, A612h, D2ADh, C324h, F1BFh, E036h
            .word 18C1h, 0948h, 3BD3h, 2A5Ah, 5EE5h, 4F6Ch, 7DF7h, 6C7Eh
            .word A50Ah, B483h, 8618h, 9791h, E32Eh, F2A7h, C03Ch, D1B5h
            .word 2942h, 38CBh, 0A50h, 1BD9h, 6F66h, 7EEFh, 4C74h, 5DFDh
            .word B58Bh, A402h, 9699h, 8710h, F3AFh, E226h, D0BDh, C134h
            .word 39C3h, 284Ah, 1AD1h, 0B58h, 7FE7h, 6E6Eh, 5CF5h, 4D7Ch
            .word C60Ch, D785h, E51Eh, F497h, 8028h, 91A1h, A33Ah, B2B3h
            .word 4A44h, 5BCDh, 6956h, 78DFh, 0C60h, 1DE9h, 2F72h, 3EFBh
            .word D68Dh, C704h, F59Fh, E416h, 90A9h, 8120h, B3BBh, A232h
            .word 5AC5h, 4B4Ch, 79D7h, 685Eh, 1CE1h, 0D68h, 3FF3h, 2E7Ah
            .word E70Eh, F687h, C41Ch, D595h, A12Ah, B0A3h, 8238h, 93B1h
            .word 6B46h, 7ACFh, 4854h, 59DDh, 2D62h, 3CEBh, 0E70h, 1FF9h
            .word F78Fh, E606h, D49Dh, C514h, B1ABh, A022h, 92B9h, 8330h
            .word 7BC7h, 6A4Eh, 58D5h, 495Ch, 3DE3h, 2C6Ah, 1EF1h, 0F78h

  lostit     May 17, 2007 07:21.10 CDT
Googled some of the constants and this was the first link i clicked.

http://mypage.bluewin.ch/horo/tech/ppp-fcs/fcs.html

and here's the rfc it references

http://www.faqs.org/rfcs/rfc1662.html

  bushing     May 17, 2007 14:21.51 CDT
Haha argh.  It was so late that I was googling "1189 2312 239b" ... which wasn't helping much.  Thanks. :)

  PSUJobu     May 17, 2007 20:03.30 CDT
Congrats on the find, and as for your "Googling typo", I think we've ALL been there at least once! :) Good work - processor modules are fun, huh?

  bushing     May 20, 2007 05:21.28 CDT
Yeah, I guess.  I'm finding the processor module frustrating, because I know there's so much more analysis I could be doing, but having trouble figuring out how to do it within the context of a processor module.  Having figured out the checksum algorithm allows me to patch the application code on this box ... but I still need to figure out what to actually change.  I'll start up another thread about that, though.

The fruits of this specific labor:  http://www.avic411.com/forum/viewtopic.php?p=47930&sid=9262a6ec948ab54f529c2d4746ea0a73#47930

Thanks to all for their help!

Note: Registration is required to post to the forums.

There are 31,328 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06
Question about memor...
Dec/12


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit