def compareFormat(self, value, indice, negative, vocabulary, memory): """compareFormat: Compute if the provided data is "format-compliant" and return the size of the biggest compliant data. @type value: bitarray.bitarray @param value: a bit array a subarray of which we compare to the current variable binray value. @type indice: integer @param indice: the starting point of comparison in value. @type negative: boolean @param negative: tells if we use the variable or a logical not of it. @type vocabulary: netzob.Common.Vocabulary.Vocabulary @param vocabulary: the vocabulary of the current project. @type memory: netzob.Common.MMSTD.Memory.Memory @param memory: a memory which can contain a former value of the variable. @rtype: integer @return: the size of the biggest compliant data, -1 if it does not comply. """ tmp = value[indice:] size = len(tmp) if size <= 8: self.log.debug("Too small, not even 8 bits available (1 number)") return -1 for i in range(size, 8, -1): subValue = value[indice:indice + i - 1] strVal = TypeConvertor.bin2string( TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): if (strVal.isdigit()): self.log.debug("Its a numeric : (" + str(strVal) + ")") return i + indice - 1 self.log.debug("the value " + str( TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(tmp))) + " cannot be parsed as a decimalWord") return -1
def compareFormat(self, value, indice, negative, vocabulary, memory): """compareFormat: Compute if the provided data is "format-compliant" and return the size of the biggest compliant data. @type value: bitarray.bitarray @param value: a bit array a subarray of which we compare to the current variable binray value. @type indice: integer @param indice: the starting point of comparison in value. @type negative: boolean @param negative: tells if we use the variable or a logical not of it. @type vocabulary: netzob.Common.Vocabulary.Vocabulary @param vocabulary: the vocabulary of the current project. @type memory: netzob.Common.MMSTD.Memory.Memory @param memory: a memory which can contain a former value of the variable. @rtype: integer @return: the size of the biggest compliant data, -1 if it does not comply. """ tmp = value[indice:] size = len(tmp) if size <= 16: self.log.debug("Too small, not even 16 bits available (2 letters)") return -1 for i in range(size, 16, -1): subValue = value[indice:indice + i - 1] if (i - 1) % 8 == 0: strVal = TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): self.log.debug("Its an ascii : (" + str(strVal) + ")") if (not ' ' in strVal and not '\n' in strVal and not '\r' in strVal): self.log.debug("Its an ascii without space : (" + str(strVal) + ")") self.log.debug("Binary value of the ascii : %s" % str(TypeConvertor.strBitarray2Bitarray(subValue))) return indice + i - 1 return -1
def loadFromXML(xmlRoot, namespace, version): """loadFromXML: Load a binary variable from an XML definition. """ if version == "0.1": varId = xmlRoot.get("id") varName = xmlRoot.get("name") xmlBinaryVariableOriginalValue = xmlRoot.find("{" + namespace + "}originalValue") if xmlBinaryVariableOriginalValue is not None: originalValue = TypeConvertor.strBitarray2Bitarray( xmlBinaryVariableOriginalValue.text) else: originalValue = None xmlBinaryVariableStartValue = xmlRoot.find("{" + namespace + "}minBits") minBits = int(xmlBinaryVariableStartValue.text) xmlBinaryVariableEndValue = xmlRoot.find("{" + namespace + "}maxBits") maxBits = int(xmlBinaryVariableEndValue.text) return BinaryVariable(varId, varName, originalValue, minBits, maxBits) return None
def compareFormat(self, value, indice, negative, vocabulary, memory): tmp = value[indice:] size = len(tmp) if size <= 8: self.log.debug("Too small, not even 8 bits available (1 number)") return -1 for i in range(size, 8, -1): subValue = value[indice:indice + i - 1] strVal = TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): if (strVal.isdigit()): self.log.debug("Its a numeric : (" + str(strVal) + ")") return i + indice - 1 self.log.debug("the value " + str(TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(tmp))) + " cannot be parsed as a decimalWord") return -1
def compareFormat(self, value, indice, negative, vocabulary, memory): tmp = value[indice:] size = len(tmp) if size <= 16: self.log.debug("Too small, not even 16 bits available (2 letters)") return -1 for i in range(size, 16, -1): subValue = value[indice:indice + i - 1] if (i - 1) % 8 == 0: strVal = TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): self.log.debug("Its an ascii : (" + str(strVal) + ")") if (not ' ' in strVal and not '\n' in strVal and not '\r' in strVal): self.log.debug("Its an ascii without space : (" + str(strVal) + ")") self.log.debug("Binary value of the ascii : %s" % str(TypeConvertor.strBitarray2Bitarray(subValue))) return indice + i - 1 return -1
def abstract(self, message): self.log.debug("We abstract the received message : " + str(message)) # we search in the vocabulary an entry which match the message for symbol in self.vocabulary.getSymbols(): self.log.debug("Try to abstract message through : " + str(symbol.getName())) if symbol.getRoot().compare(TypeConvertor.strBitarray2Bitarray(message), 0, False, self.vocabulary, self.memory) != -1: self.log.info("The message " + str(message) + " match symbol " + symbol.getName()) # It matchs so we learn from it if it's possible self.memory.createMemory() self.log.debug("We memorize the symbol " + str(symbol.getRoot())) symbol.getRoot().learn(TypeConvertor.strBitarray2Bitarray(message), 0, False, self.vocabulary, self.memory) self.memory.persistMemory() return symbol else: self.log.debug("Entry " + str(symbol.getID()) + " doesn't match") # we first restore possibly learnt value self.log.debug("Restore possibly learnt value") symbol.getRoot().restore(self.vocabulary, self.memory) return UnknownSymbol()
def learn(self, value, indice, negative, vocabulary, memory): # First we retrieve the size of the value to memorize size = self.compare(value, indice, negative, vocabulary, memory) if size > 0: # memorize self.log.debug("Memorize : " + str(value[indice:size])) memory.memorize(self, (value[indice:size], TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(value[indice:size])))) return size else: self.log.debug("Incompatible for learning") return -1
def compareFormat(self, value, indice, negative, vocabulary, memory): """compareFormat: Compute if the provided data is "format-compliant" and return the size of the biggest compliant data. @type value: bitarray.bitarray @param value: a bit array a subarray of which we compare to the current variable binray value. @type indice: integer @param indice: the starting point of comparison in value. @type negative: boolean @param negative: tells if we use the variable or a logical not of it. @type vocabulary: netzob.Common.Vocabulary.Vocabulary @param vocabulary: the vocabulary of the current project. @type memory: netzob.Common.MMSTD.Memory.Memory @param memory: a memory which can contain a former value of the variable. @rtype: integer @return: the size of the biggest compliant data, -1 if it does not comply. """ tmp = value[indice:] size = len(tmp) if size <= 16: self.log.debug("Too small, not even 16 bits available (2 letters)") return -1 for i in range(size, 16, -1): subValue = value[indice:indice + i - 1] if (i - 1) % 8 == 0: strVal = TypeConvertor.bin2string( TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): self.log.debug("Its an ascii : (" + str(strVal) + ")") if (not ' ' in strVal and not '\n' in strVal and not '\r' in strVal): self.log.debug("Its an ascii without space : (" + str(strVal) + ")") self.log.debug( "Binary value of the ascii : %s" % str(TypeConvertor.strBitarray2Bitarray(subValue))) return indice + i - 1 return -1
def abstract(self, message): """abstract: Searches in the vocabulary the symbol which abstract the received message. @type message: netzob.Common.Models.AbstractMessage @param message: the message that is being read/compare/learn. @rtype: netzob.Common.Symbol @return: the symbol which content matches the message. """ self.log.debug("We abstract the received message : " + TypeConvertor.bin2strhex(message)) # we search in the vocabulary an entry which match the message for symbol in self.vocabulary.getSymbols(): self.log.debug("Try to abstract message through : {0}.".format( symbol.getName())) readingToken = VariableReadingToken( False, self.vocabulary, self.memory, TypeConvertor.strBitarray2Bitarray(message), 0) symbol.getRoot().read(readingToken) logging.debug( "ReadingToken: isOk: {0}, index: {1}, len(value): {2}".format( str(readingToken.isOk()), str(readingToken.getIndex()), str(len(readingToken.getValue())))) # The message matches if the read is ok and the whole entry was read. if readingToken.isOk() and readingToken.getIndex() == len( readingToken.getValue()): self.log.debug("The message matches symbol {0}.".format( symbol.getName())) # It matches so we learn from it if it's possible return symbol else: self.log.debug("The message doesn't match symbol {0}.".format( symbol.getName())) # This is now managed in the variables modules. #=================================================================== # self.memory.createMemory() # self.log.debug("We memorize the symbol " + str(symbol.getRoot())) # readingToken = VariableReadingToken(False, self.vocabulary, self.memory, TypeConvertor.strBitarray2Bitarray(message), 0) # symbol.getRoot().learn(readingToken) # self.memory.persistMemory() # return symbol # else: # self.log.debug("Entry " + str(symbol.getID()) + " doesn't match") # # we first restore a possibly learned value # self.log.debug("Restore possibly learned value") # processingToken = AbstractVariableProcessingToken(False, self.vocabulary, self.memory) # symbol.getRoot().restore(processingToken) #=================================================================== return UnknownSymbol()
def compareFormat(self, value, indice, negative, vocabulary, memory): """compareFormat: Compute if the provided data is "format-compliant" and return the size of the biggest compliant data. @type value: bitarray.bitarray @param value: a bit array a subarray of which we compare to the current variable binray value. @type indice: integer @param indice: the starting point of comparison in value. @type negative: boolean @param negative: tells if we use the variable or a logical not of it. @type vocabulary: netzob.Common.Vocabulary.Vocabulary @param vocabulary: the vocabulary of the current project. @type memory: netzob.Common.MMSTD.Memory.Memory @param memory: a memory which can contain a former value of the variable. @rtype: integer @return: the size of the biggest compliant data, -1 if it does not comply. """ tmp = value[indice:] size = len(tmp) if size <= 8: self.log.debug("Too small, not even 8 bits available (1 number)") return -1 for i in range(size, 8, -1): subValue = value[indice : indice + i - 1] strVal = TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(subValue)) typeIdentifier = TypeIdentifier() if typeIdentifier.isAscii(strVal): if strVal.isdigit(): self.log.debug("Its a numeric : (" + str(strVal) + ")") return i + indice - 1 self.log.debug( "the value " + str(TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(tmp))) + " cannot be parsed as a decimalWord" ) return -1
def learn(self, value, indice, negative, vocabulary, memory): """learn: Compare the current variable to the end (starting at the "indice"-th character) of value. Moreover it stores learns from the provided message. Return the number of letters that matches, -1 if it does not match. """ # First we retrieve the size of the value to memorize size = self.compare(value, indice, negative, vocabulary, memory) if size > 0: # memorize self.log.debug("Memorize : " + str(value[indice:size])) memory.memorize(self, (value[indice:size], TypeConvertor.bin2string(TypeConvertor.strBitarray2Bitarray(value[indice:size])))) return size else: self.log.debug("Incompatible for learning") return -1
def loadFromXML(xmlRoot, namespace, version): if version == "0.1": varId = xmlRoot.get("id") varName = xmlRoot.get("name") xmlBinaryVariableOriginalValue = xmlRoot.find("{" + namespace + "}originalValue") if xmlBinaryVariableOriginalValue != None: originalValue = TypeConvertor.strBitarray2Bitarray(xmlBinaryVariableOriginalValue.text) else: originalValue = None xmlBinaryVariableStartValue = xmlRoot.find("{" + namespace + "}minBits") minBits = int(xmlBinaryVariableStartValue.text) xmlBinaryVariableEndValue = xmlRoot.find("{" + namespace + "}maxBits") maxBits = int(xmlBinaryVariableEndValue.text) return BinaryVariable(varId, varName, originalValue, minBits, maxBits) return None
def learn(self, value, indice, negative, vocabulary, memory): """learn: Compare the current variable to the end (starting at the "indice"-th character) of value. Moreover it stores learns from the provided message. Return the number of letters that matches, -1 if it does not match. """ # First we retrieve the size of the value to memorize size = self.compare(value, indice, negative, vocabulary, memory) if size > 0: # memorize self.log.debug("Memorize : " + str(value[indice:size])) memory.memorize( self, (value[indice:size], TypeConvertor.bin2string( TypeConvertor.strBitarray2Bitarray(value[indice:size])))) return size else: self.log.debug("Incompatible for learning") return -1
def abstract(self, message): """abstract: Searches in the vocabulary the symbol which abstract the received message. @type message: netzob.Common.Models.AbstractMessage @param message: the message that is being read/compare/learn. @rtype: netzob.Common.Symbol @return: the symbol which content matches the message. """ self.log.debug("We abstract the received message : " + TypeConvertor.bin2strhex(message)) # we search in the vocabulary an entry which match the message for symbol in self.vocabulary.getSymbols(): self.log.debug("Try to abstract message through : {0}.".format(symbol.getName())) readingToken = VariableReadingToken(False, self.vocabulary, self.memory, TypeConvertor.strBitarray2Bitarray(message), 0) symbol.getRoot().read(readingToken) logging.debug("ReadingToken: isOk: {0}, index: {1}, len(value): {2}".format(str(readingToken.isOk()), str(readingToken.getIndex()), str(len(readingToken.getValue())))) # The message matches if the read is ok and the whole entry was read. if readingToken.isOk() and readingToken.getIndex() == len(readingToken.getValue()): self.log.debug("The message matches symbol {0}.".format(symbol.getName())) # It matches so we learn from it if it's possible return symbol else: self.log.debug("The message doesn't match symbol {0}.".format(symbol.getName())) # This is now managed in the variables modules. #=================================================================== # self.memory.createMemory() # self.log.debug("We memorize the symbol " + str(symbol.getRoot())) # readingToken = VariableReadingToken(False, self.vocabulary, self.memory, TypeConvertor.strBitarray2Bitarray(message), 0) # symbol.getRoot().learn(readingToken) # self.memory.persistMemory() # return symbol # else: # self.log.debug("Entry " + str(symbol.getID()) + " doesn't match") # # we first restore a possibly learned value # self.log.debug("Restore possibly learned value") # processingToken = AbstractVariableProcessingToken(False, self.vocabulary, self.memory) # symbol.getRoot().restore(processingToken) #=================================================================== return UnknownSymbol()