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

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -