windows - CRC Reverse Engineer (Checksum from Machine / PC) -
i'm looking on how determine crc produced machine pc (and vice-versa). devices communicating using serial communication or rs232 cable.
i have data able create program used both devices. data given boss , program corrupted. trying work out. hope can help. :)
the sequence use crc calculation in protocol ascii string
- starting first printing character (e.g. 'r' req)
- until , including '1e' in calculation.
it's crc following specs according our crc calculator
crc:16,1021,0000,0000,no,no
which means:
crc width: 16 bit (of course) polynomial: 1021 hex (truncated crc polynomial) init value: 0000 final xor applied: 0000 reflectedinput: no reflectedoutput: no`
(if 'init value' ffff, "16 bit width crc designated ccitt").
see docklight crc glossary , boost crc library on crc terms mean plus sample code.
what did write small script tries out popular 16 bit crcs on varying parts of first simple "req=ini" command, , see if end sum of 4255. failed, instead of going full brute force trying sorts of polynoms, assumed maybe oddball / flawed implementation of known standards, , indeed succeeded variation of crc-ccitt.
heres slow & easy c code (not table based!) calculate sorts of crcs:
// generic, not table-based crc calculation // based on , credits following: // crc tester v1.3 written on 4th of february 2003 sven reifegerste (zorc/reflex) unsigned long reflect (unsigned long crc, int bitnum) { // reflects lower 'bitnum' bits of 'crc' unsigned long i, j=1, crcout=0; (i=(unsigned long)1<<(bitnum-1); i; i>>=1) { if (crc & i) crcout|=j; j<<= 1; } return (crcout); } calccrc( const int width, const unsigned long polynominal, const unsigned long initialremainder, const unsigned long finalxor, const int reflectedinput, const int reflectedoutput, const unsigned char message[], const long startindex, const long endindex) { // ensure width in range: 1-32 bits assert(width >= 1 && width <= 32); // constant parameters used const bool b_refinput = (reflectedinput > 0); const bool b_refoutput = (reflectedoutput > 0); const unsigned long crcmask = ((((unsigned long)1<<(width-1))-1)<<1)|1; const unsigned long crchighbit = (unsigned long)1<<(width-1); unsigned long j, c, bit; unsigned long crc = initialremainder; (long msgindex = startindex; msgindex <= endindex; ++msgindex) { c = (unsigned long)message[msgindex]; if (b_refinput) c = reflect(c, 8); (j=0x80; j; j>>=1) { bit = crc & crchighbit; crc<<= 1; if (c & j) bit^= crchighbit; if (bit) crc^= polynominal; } } if (b_refoutput) crc=reflect(crc, width); crc^= finalxor; crc&= crcmask; return(crc); }
with code , crcs specs listed above, have been able re-calculate following 3 sample crcs:
10.03.2014 22:20:57.109 [tx] - req=ini<cr><lf> <rs>crc=4255<cr><lf> <gs> 10.03.2014 22:20:57.731 [tx] - ans=ini<cr><lf> status=0<cr><lf> <rs>crc=57654<cr><lf> <gs> 10.03.2014 22:20:59.323 [tx] - ans=ini<cr><lf> status=0<cr><lf> mid="ctl1"<cr><lf> def="dtlreq";1025<cr><lf> info=0<cr><lf> <rs>crc=1683<cr><lf> <gs>
i failed on complex 1 def=
parts - didn't understand character sequence correctly.
the docklight script used reverse engineer this:
sub crcreverseengineer() dim crctypes(7) crctypes(0) = "crc:16,1021,ffff,0000" ' ccitt crctypes(1) = "crc:16,8005,0000,0000" ' crc-16 crctypes(2) = "crc:16,8005,ffff,0000" ' crc-modbus ' lets try nonstandard variations different init , final xor, stick ' known 2 polynoms. crctypes(3) = "crc:16,1021,ffff,ffff" crctypes(4) = "crc:16,1021,0000,ffff" crctypes(5) = "crc:16,1021,0000,0000" crctypes(6) = "crc:16,8005,ffff,ffff" crctypes(7) = "crc:16,8005,ffff,0000" crcstring = "06 1c 52 45 51 3d 49 4e 49 0d 0a 1e 43 52 43 3d 30 30 30 30 0d 0a 1d" reflectedinorout = 0 3 ctype = 0 7 crcspec = crctypes(ctype) & "," & iif(reflectedinorout mod 2 = 1, "yes", "no") & "," & iif(reflectedinorout > 1, "yes", "no") cstart = 1 3 cend = 9 (len(crcstring) + 1) / 3 subdatastring = mid(crcstring, (cstart - 1) * 3 + 1, (cend - cstart + 1) * 3) result = dl.calcchecksum(crcspec, subdatastring, "h") resultint = clng("&h" + left(result, 2)) * 256 + clng("&h" + right(result, 2)) if resultint = 4255 dl.addcomment "found it!" dl.addcomment "sequence: " & subdatastring dl.addcomment "crc spec: " & crcspec dl.addcomment "crc result: " & result & " (integer = " & resultint & ")" exit sub end if next next next next end sub public function iif(blnexpression, vtrueresult, vfalseresult) if blnexpression iif = vtrueresult else iif = vfalseresult end if end function
hope helps , i'm happy provide information or clarify details.
Comments
Post a Comment