def test_bruteForceInput_xor(self): dataList = [] dataSize = 16 crcSize = 8 inputPoly = 0x185 regInit = 0x0 xorOut = 0x0A reverse = False ## init: 0, xor: 0, rev, poly: 0x18005 self.crcProc.setReversed(reverse) self.crcProc.setXorOutValue(xorOut) self.crcProc.setRegisterInitValue(regInit) data1 = 0xABCD crc1 = self.crcProc.calculate2(data1, dataSize, inputPoly, crcSize) dataList.append((data1, crc1)) data2 = data1 ^ 0x0010 crc2 = self.crcProc.calculate2(data2, dataSize, inputPoly, crcSize) dataList.append((data2, crc2)) dInput = InputData(dataList, dataSize, crcSize) foundCRC = self.crcFinder.bruteForcePairs(dInput, 0) # print "found data:", foundCRC self.assertIn( CRCKey(inputPoly, regInit, xorOut, 0, dataSize, rev=reverse), foundCRC)
def test_findCommon_c16d16_prefix12(self): dataList = [] crcSize = 16 dataSize = 16 inputPoly = 0x18005 ## 0x18005 = 98309 regInit = 0x0 xorOut = 0x0 reverse = False preSize = 12 preamble = (0xFFF << dataSize) ## init: 0, xor: 0, rev, poly: 0x18005 self.crcProc.setReversed(reverse) self.crcProc.setRegisterInitValue(regInit) self.crcProc.setXorOutValue(xorOut) data1 = 0xABCD crc1 = self.crcProc.calculate2(data1, dataSize, inputPoly, crcSize) dataList.append((preamble | data1, crc1)) data2 = data1 ^ 0x0010 crc2 = self.crcProc.calculate2(data2, dataSize, inputPoly, crcSize) dataList.append((preamble | data2, crc2)) foundCRC = self.crcFinder.findCommon(dataList, preSize + dataSize, crcSize, 12) # print "found data:", foundCRC self.assertIn(CRCKey(inputPoly, regInit, 0, 0, dataSize, rev=reverse), foundCRC)
def test_findCommon_crc8b(self): dataList = [] crcFun = crcmod.predefined.mkCrcFun( "crc-8") ## init: 0x0, xor: 0x0, poly: 0x107 data = 0xABCD crc = crcFun(intToASCII(data)) dataList.append((data, crc)) foundCRC = self.crcFinder.findCommon(dataList, 16, 8) foundCRC = list(foundCRC) # print "found:", foundCRC self.assertIn(CRCKey(0x107, 0x0, 0x0, 0, 16, rev=False), foundCRC)
def findBruteForceParams(self, dataCrc1, dataCrc2, polyKey): self.crcProc.setReversed(polyKey.isReversedFully()) # PolyKey crcSize = dataCrc1.crcSize polyMask = NumberMask(polyKey.poly, crcSize) dataMask1 = dataCrc1.dataMask() dataMask2 = dataCrc2.dataMask() paramMax = (0x1 << crcSize) - 1 # 0xFFFF polyList = [] initValStart = 0 initValEnd = paramMax if self.initVal is not None: initValStart = self.initVal initValEnd = initValStart crcMask1 = dataCrc1.crcMask() crcMask2 = dataCrc2.crcMask() inputData = [(dataMask1, crcMask1), (dataMask2, crcMask2)] crc_operator = self.crcProc.createDataOperator(crcSize, inputData) crc_found = crc_operator.verifyRange(polyMask, initValStart, initValEnd, 0, paramMax) for item in crc_found: initReg = item[0] xorVal = item[1] # print "Found CRC - poly: 0x{:X} initVal: 0x{:X} xorVal: 0x{:X}\n".format( polyMask.dataNum, initReg, xorVal ) newKey = CRCKey(polyKey.poly, initReg, xorVal, polyKey.dataPos, polyKey.dataLen, revOrd=polyKey.revOrd, refBits=polyKey.refBits) polyList.append(newKey) if self.progress: sys.stdout.write("\r") sys.stdout.flush() return polyList
def test_findCommon_crc16_d32(self): dataList = [] crcFun = crcmod.predefined.mkCrcFun( "crc-16") ## p:0x18005 r:True i:0x0000 x:0x0000 data1 = 0x1234ABCD crc1 = crcFun(intToASCII(data1)) dataList.append((data1, crc1)) data2 = data1 ^ 0x0010 crc2 = crcFun(intToASCII(data2)) dataList.append((data2, crc2)) foundCRC = self.crcFinder.findCommon(dataList, 32, 16) foundCRC = list(foundCRC) # print "found:", foundCRC self.assertIn(CRCKey(0x18005, 0x0, 0x0, 0, 32, rev=True), foundCRC)
def test_findCommon_crc16buypass_d32(self): dataList = [] crcFun = crcmod.predefined.mkCrcFun( "crc-16-buypass") ## p:0x18005 r:False i:0x0000 x:0x0000 data = 0xDCBA4321 crc = crcFun(intToASCII(data)) dataList.append((data, crc)) data = data ^ 0x0010 crc = crcFun(intToASCII(data)) dataList.append((data, crc)) foundCRC = self.crcFinder.findCommon(dataList, 32, 16) foundCRC = list(foundCRC) # print "found:", foundCRC self.assertIn(CRCKey(0x18005, 0x0, 0x0, 0, 32, rev=False), foundCRC)
def test_findCommon_crc16_d32_subdata(self): dataList = [] crcFun = crcmod.predefined.mkCrcFun( "crc-16") ## p:0x18005 r:True i:0x0000 x:0x0000 data = 0x4B4D crc = crcFun(intToASCII(data)) dataList.append((0x42440000 | data, crc)) data = data ^ 0x0010 crc = crcFun(intToASCII(data)) dataList.append((0x47440000 | data, crc)) foundCRC = self.crcFinder.findCommon(dataList, 32, 16, 16) foundCRC = list(foundCRC) # print "found:", foundCRC self.assertIn(CRCKey(0x18005, 0x0, 0x0, 0, 16, rev=True), foundCRC)
def test_findCommon_crc16dnp(self): dataList = [] crcFun = crcmod.predefined.mkCrcFun( "crc-16-dnp") ## poly: 0x13D65, rev, init: 0xFFFF, xor: 0xFFFF data = 0xABCD crc = crcFun(intToASCII(data)) dataList.append((data, crc)) data = data ^ 0x0010 crc = crcFun(intToASCII(data)) dataList.append((data, crc)) foundCRC = self.crcFinder.findCommon(dataList, 16, 16) foundCRC = list(foundCRC) # print "found:", foundCRC self.assertIn(CRCKey(0x13D65, 0xFFFF, 0xFFFF, 0, 16, rev=True), foundCRC)
def _findBruteForcePoly(self, dataMask, crcMask, reverseMode): self.crcProc.setReversed(reverseMode) crc = crcMask.dataNum poly = 0 polyMax = crcMask.masterBit polyMask = copy.deepcopy(crcMask) retList = [] while poly < polyMax: # if self.progress and (poly % 16384) == 16383: # if self.progress and (poly % 8192) == 8191: # sys.stdout.write("\r{:b}".format(poly | polyMax)) # sys.stdout.flush() polyMask.setNumber(poly) polyCRC = self.crcProc.calculate3(dataMask, polyMask) if polyCRC == crc: # if self.progress: # sys.stdout.write("\r") # print "Found poly: 0b{0:b} 0x{0:X}".format(poly) polyValue = poly | polyMax ## bitwise or -- add master bit polyInit = self.crcProc.registerInit polyXor = self.crcProc.xorOut retList.append( CRCKey(polyValue, polyInit, polyXor, 0, dataMask.dataSize, rev=reverseMode)) # retList.append( PolyKey(polyValue, 0, dataMask.dataSize, rev=reverseMode) ) poly += 1 # if self.progress: # sys.stdout.write("\r") # sys.stdout.flush() return retList
def test_execute_16_rand(self): poly = 0x335D initReg = 0x00 xorVal = 0x02 dataSize = 32 crcSize = 16 inputParams = InputParams() inputParams.data = self.generateInputData(3, dataSize, crcSize, poly, initReg, xorVal) inputParams.crcSize = crcSize inputParams.poly = poly inputParams.xorVal = xorVal results = self.solver.execute(inputParams, None) # print "result:", results, len(results) # print "data: ", inputParams.data.numbersList, len(inputParams.data.numbersList) # print "result:", results.most_common(3), len(results) self.assertEqual(len(results), 1) self.assertIn(CRCKey(poly, initReg, xorVal, 0, dataSize, False, False), results)
def test_execute_8_sample(self): poly = 0x1D initReg = 0x00 xorVal = 0x8F dataSize = 56 crcSize = 8 dataList = [(0x0D00C0F0FFFFFF, 0x90), (0x0000C0F0FFFFFF, 0x76)] inputParams = InputParams() inputParams.data = InputData(dataList, dataSize, crcSize) inputParams.crcSize = crcSize inputParams.poly = poly inputParams.xorVal = xorVal results = self.solver.execute(inputParams, None) # print "result:", results, len(results) # print "data: ", inputParams.data.numbersList, len(inputParams.data.numbersList) # print "result:", results.most_common(3), len(results) self.assertEqual(len(results), 1) self.assertIn(CRCKey(poly, initReg, xorVal, 0, dataSize, False, False), results)
def findCRC(self, subNum, crcMask): dataMask = subNum.toNumberMask() retList = set() if crcMask.dataSize == 8: self.checkCRC(dataMask, crcMask, CRCKey(0x107, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x139, 0x0, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11D, 0xFD, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x107, 0x55, 0x55, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x131, 0x0, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x107, 0xFF, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x19B, 0x0, 0x0, rev=True), retList) elif crcMask.dataSize == 16: self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0x0, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0x800D, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x10589, 0x0001, 0x0001, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x13D65, 0xFFFF, 0xFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x13D65, 0xFFFF, 0xFFFF, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x0, 0xFFFF, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0xFFFF, 0xFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0xFFFF, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x554D, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18BB7, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x1A097, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0x0, 0xFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x0, 0xFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x18005, 0xFFFF, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x0, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0xFFFF, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11021, 0x1D0F, 0x0, rev=False), retList) elif crcMask.dataSize == 24: self.checkCRC(dataMask, crcMask, CRCKey(0x1864CFB, 0xB704CE, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x15D6DCB, 0xFEDCBA, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x15D6DCB, 0xABCDEF, 0x0, rev=False), retList) elif crcMask.dataSize == 32: self.checkCRC(dataMask, crcMask, CRCKey(0x104C11DB7, 0x0, 0xFFFFFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x104C11DB7, 0x0, 0xFFFFFFFF, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x11EDC6F41, 0x0, 0xFFFFFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x1A833982B, 0x0, 0xFFFFFFFF, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x104C11DB7, 0xFFFFFFFF, 0x0, rev=False), retList) self.checkCRC( dataMask, crcMask, CRCKey(0x104C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x1814141AB, 0x0, 0x0, rev=False), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x104C11DB7, 0xFFFFFFFF, 0x0, rev=True), retList) self.checkCRC(dataMask, crcMask, CRCKey(0x1000000AF, 0x0, 0x0, rev=False), retList) elif crcMask.dataSize == 64: self.checkCRC(dataMask, crcMask, CRCKey(0x1000000000000001B, 0x0, 0x0, rev=True), retList) self.checkCRC( dataMask, crcMask, CRCKey(0x142F0E1EBA9EA3693, 0x0, 0xFFFFFFFFFFFFFFFF, rev=False), retList) self.checkCRC( dataMask, crcMask, CRCKey(0x1AD93D23594C935A9, 0xFFFFFFFFFFFFFFFF, 0x0, rev=True), retList) return retList
def execute( self, inputParams, outputFile ): inputData = inputParams.data # InputData crcSize = inputParams.getCRCSize() if crcSize is None: print "\nUnable to determine CRC size: pass poly or crcsize as cmd argument" return None if inputData.crcSize != crcSize: ## deduced CRC size differs from input crc raise ValueError( "inconsistent crc size [%s] with input data crc[%s]" % ( crcSize, inputData.crcSize ) ) if crcSize < 1: raise ValueError( "invalid crc size [%s]" % ( crcSize ) ) inputMasks = InputMaskList( inputData ) if inputMasks.empty(): print "invalid case -- no data" return None _LOGGER.info( "crc size: %s" % crcSize ) # revOrd = inputParams.isReverseOrder() # if revOrd: # inputMasks.reverseOrder() # refBits = inputParams.isReflectBits() # if refBits: # inputMasks.reflectBits() inputList = inputMasks.getInputMasks() # List[ (NumberMask, NumberMask) ] numbersLen = len(inputList) polyListStart, polyListStop = inputParams.getPolySearchRange() polyListSize = polyListStop - polyListStart + 1 xorListStart, xorListStop = inputParams.getXorValSearchRange() xorListSize = xorListStop - xorListStart + 1 subSpaceSize = xorListSize spaceSize = numbersLen * polyListSize * subSpaceSize _LOGGER.info( "search space size: %s %s %s %s", spaceSize, numbersLen, polyListSize, xorListSize ) _LOGGER.info( "poly search range: %s %s" % ( polyListStart, polyListStop ) ) _LOGGER.info( " xor search range: %s %s" % ( xorListStart, xorListStop ) ) spaceCounter = 0 crc_forward = self.procFactory.createForwardProcessor( crcSize ) # CRCProcessor crc_backward = self.procFactory.createInvertProcessor( crcSize ) # CRCInvertProcessor crc_operator = None if numbersLen > 1: subInputList = inputList[1:] ## CRCDataOperator crc_operator = crc_forward.createDataOperator( crcSize, subInputList ) results = Counter() dataSize = inputData.dataSize firstDataItem = inputList[0] firstDataMask = firstDataItem[0] firstCrcMask = firstDataItem[1] firstCrc = firstCrcMask.dataNum # initSum = 0 polyMask = NumberMask( 0, crcSize ) for polyNum in xrange(polyListStart, polyListStop + 1): if polyNum == 0x0: ## value does not make sense and it's heavily computable spaceCounter += numbersLen * subSpaceSize continue polyMask.setNumber( polyNum ) spaceCounter += numbersLen * subSpaceSize if self.progress: value = spaceCounter * 100.0 / spaceSize flush_percent( value, 7 ) ## xorDict: List[ (xor, List[init]) ] xorDict = crc_backward.calculateInitRegRange( firstDataMask, firstCrc, polyMask, xorListStart, xorListStop ) if crc_operator is None: ## there is only single data row for xorOutPair in xorDict: xorOut = xorOutPair[0] init_found = xorOutPair[1] for init_reg in init_found: key = CRCKey( polyNum, init_reg, xorOut, 0, dataSize, revOrd=False, refBits=False ) results[ key ] += 1 continue # callsCounter = 0 for xorOutPair in xorDict: xorOut = xorOutPair[0] init_found = xorOutPair[1] crc_forward.setXorOutValue( xorOut ) # callsCounter += len( init_found ) for init_reg in init_found: crc_forward.setInitValue( init_reg ) valid = crc_operator.verify( polyMask ) if valid: key = CRCKey( polyNum, init_reg, xorOut, 0, dataSize, revOrd=False, refBits=False ) results[ key ] += 1 # print "verify call count:", callsCounter _LOGGER.info( "\n\nFound total results: %s", len(results) ) if self.progress: print "" print_results( results, 1, True ) if outputFile is not None: write_results( results, 1, outputFile, True ) # print "inits per item:", initSum, float(initSum) / (polyListSize*xorListSize*numbersLen) return results
def bruteForce(self, inputParams, searchRange=0): inputData = inputParams.data # InputData crcSize = inputParams.getCRCSize() if crcSize is None: print "\nUnable to determine CRC size: pass poly or crcsize as cmd argument" return [] if inputData.crcSize != crcSize: ## deduced CRC size differs from input crc raise ValueError( "inconsistent crc size [%s] with input data crc[%s]" % (crcSize, inputData.crcSize)) inputMasks = InputMaskList(inputData) if inputMasks.empty(): print "invalid case -- no data" return [] _LOGGER.info("crc size: %s" % crcSize) if inputParams.isReverseOrder(): inputMasks.reverseOrder() if inputParams.isReflectBits(): inputMasks.reflectBits() ## List[ (NumberMask, NumberMask) ] inputList = inputMasks.getInputMasks() polyListStart, polyListStop = inputParams.getPolySearchRange() polyListSize = polyListStop - polyListStart + 1 initListStart, initListStop = inputParams.getInitRegSearchRange() initListSize = initListStop - initListStart + 1 xorListStart, xorListStop = inputParams.getXorValSearchRange() xorListSize = xorListStop - xorListStart + 1 subSpaceSize = initListSize * xorListSize spaceSize = polyListSize * subSpaceSize _LOGGER.info("search space size: %s %s %s %s", spaceSize, polyListSize, initListSize, xorListSize) _LOGGER.info("poly search range: %s %s" % (polyListStart, polyListStop)) _LOGGER.info("init search range: %s %s" % (initListStart, initListStop)) _LOGGER.info(" xor search range: %s %s" % (xorListStart, xorListStop)) crc_forward = self.procFactory.createForwardProcessor(crcSize) crc_operator = crc_forward.createDataOperator(crcSize, inputList) retList = Counter() spaceCounter = 0 polyMask = NumberMask(0, crcSize) for polyNum in xrange(polyListStart, polyListStop + 1): polyMask.setNumber(polyNum) spaceCounter += subSpaceSize if self.progress: value = spaceCounter * 100.0 / spaceSize flush_percent(value, 4) # Counter crc_found = crc_operator.calculateRange(polyMask, initListStart, initListStop, xorListStart, xorListStop) for item in crc_found: initReg = item[0] xorVal = item[1] counted = crc_found[item] # flush_string( "Found CRC - poly: 0x{:X} initVal: 0x{:X} xorVal: 0x{:X}\n".format( polyMask.dataNum, initReg, xorVal ) ) key = CRCKey(polyMask.dataNum, initReg, xorVal, 0, inputData.dataSize, rev=False) retList[key] += counted return retList
def test_size_0x123(self): key1 = CRCKey(0x123) crcsize = key1.size() self.assertEqual(crcsize, 8)
def test_size_0x01(self): key1 = CRCKey(0x01) crcsize = key1.size() self.assertEqual(crcsize, 0)
def execute(self, inputParams, outputFile): inputData = inputParams.data crcSize = inputParams.getCRCSize() if crcSize is None: _LOGGER.error( "Unable to determine CRC size: pass poly or crcsize as cmd argument" ) return if inputData.crcSize != crcSize: ## deduced CRC size differs from input crc raise ValueError( "inconsistent crc size [%s] with input data crc[%s]" % (crcSize, inputData.crcSize)) inputMasks = InputMaskList(inputData) if inputMasks.empty(): _LOGGER.error("invalid case -- no data") return False _LOGGER.info("crc size: %s" % crcSize) revOrd = inputParams.isReverseOrder() if revOrd: inputMasks.reverseOrder() refBits = inputParams.isReflectBits() if refBits: inputMasks.reflectBits() ## List[ (NumberMask, NumberMask) ] inputList = inputMasks.getInputMasks() polyListStart, polyListStop = inputParams.getPolySearchRange() polyListSize = polyListStop - polyListStart + 1 initListStart, initListStop = inputParams.getInitRegSearchRange() initListSize = initListStop - initListStart + 1 xorListStart, xorListStop = inputParams.getXorValSearchRange() xorListSize = xorListStop - xorListStart + 1 subSpaceSize = initListSize * xorListSize spaceSize = polyListSize * subSpaceSize _LOGGER.info("search space size: %s %s %s %s", spaceSize, polyListSize, initListSize, xorListSize) _LOGGER.info("poly search range: %s %s" % (polyListStart, polyListStop)) _LOGGER.info("init search range: %s %s" % (initListStart, initListStop)) _LOGGER.info(" xor search range: %s %s" % (xorListStart, xorListStop)) spaceCounter = 0 crc_forward = self.procFactory.createForwardProcessor(crcSize) crc_operator = crc_forward.createDataOperator(crcSize, inputList) polyMask = NumberMask(0, crcSize) results = Counter() for polyNum in xrange(polyListStart, polyListStop + 1): polyMask.setNumber(polyNum) spaceCounter += subSpaceSize if self.progress: value = spaceCounter * 100.0 / spaceSize flush_percent(value, 4) crc_found = crc_operator.verifyRange(polyMask, initListStart, initListStop, xorListStart, xorListStop) for item in crc_found: initReg = item[0] xorVal = item[1] # flush_string( "Found CRC - poly: 0x{:X} initVal: 0x{:X} xorVal: 0x{:X}\n".format( polyMask.dataNum, initReg, xorVal ) ) key = CRCKey(polyMask.dataNum, initReg, xorVal, 0, inputData.dataSize, revOrd=revOrd, refBits=refBits) results[key] += 1 _LOGGER.info("\n\nFound total results: %s", len(results)) if self.progress: print_results(results, 1) if outputFile is not None: write_results(results, 1, outputFile) return results