def generateChainedStatesAutomata(abstractSession, symbolList): """Generate an automata that contains as many states and transitions as the number of request-response couples in the abstract session. This automata has thus the shape of a uniq chain. >>> from netzob.all import * >>> symbolSYN = Symbol([Field(ASCII("SYN"))], name="Symbol_SYN") >>> symbolSYNACK = Symbol([Field(ASCII("SYN/ACK"))], name="Symbol_SYNACK") >>> symbolACK = Symbol([Field(ASCII("ACK"))], name="Symbol_ACK") >>> symbolPUSH = Symbol([Field(ASCII("PUSH"))], name="Symbol_PUSH") >>> symbolList = [symbolSYN, symbolSYNACK, symbolACK, symbolPUSH] >>> msg1 = RawMessage("SYN", source="A", destination="B") >>> msg2 = RawMessage("SYN/ACK", source="B", destination="A") >>> msg3 = RawMessage("ACK", source="A", destination="B") >>> msg4 = RawMessage("PUSH", source="B", destination="A") >>> session = Session([msg1, msg2, msg3, msg4]) >>> abstractSession = session.abstract(symbolList) >>> automata = Automata.generateChainedStatesAutomata(abstractSession, symbolList) >>> dotcode = automata.generateDotCode() >>> print(len(dotcode)) 1024 >>> print(dotcode) #doctest: +ELLIPSIS digraph G { "Start state" [shape=doubleoctagon, style=filled, fillcolor=white, URL="..."]; "State 1" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "State 2" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "State 3" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "End state" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "Start state" ... "State 1" [fontsize=5, label="OpenChannelTransition", URL="..."]; "State 1" ... "State 2" [fontsize=5, label="Transition (Symbol_SYN;{Symbol_SYNACK})", URL="..."]; "State 2" ... "State 3" [fontsize=5, label="Transition (Symbol_ACK;{Symbol_PUSH})", URL="..."]; "State 3" ... "End state" [fontsize=5, label="CloseChannelTransition", URL="..."]; } :return: an automata with one sequence of chained states. :rtype: a :class:`netzob.Model.Grammar.Automata.Automata` """ return ChainedStatesAutomataFactory.generate(abstractSession, symbolList)
def generateChainedStatesAutomata(abstractSession, symbolList): """Generate an automata that contains as many states and transitions as the number of request-response couples in the abstract session. This automata has thus the shape of a uniq chain. >>> from netzob.all import * >>> symbolSYN = Symbol([Field(ASCII("SYN"))], name="Symbol_SYN") >>> symbolSYNACK = Symbol([Field(ASCII("SYN/ACK"))], name="Symbol_SYNACK") >>> symbolACK = Symbol([Field(ASCII("ACK"))], name="Symbol_ACK") >>> symbolPUSH = Symbol([Field(ASCII("PUSH"))], name="Symbol_PUSH") >>> symbolList = [symbolSYN, symbolSYNACK, symbolACK, symbolPUSH] >>> msg1 = RawMessage("SYN", source="A", destination="B") >>> msg2 = RawMessage("SYN/ACK", source="B", destination="A") >>> msg3 = RawMessage("ACK", source="A", destination="B") >>> msg4 = RawMessage("PUSH", source="B", destination="A") >>> session = Session([msg1, msg2, msg3, msg4]) >>> abstractSession = session.abstract(symbolList) >>> automata = Automata.generateChainedStatesAutomata(abstractSession, symbolList) >>> dotcode = automata.generateDotCode() >>> print(len(dotcode)) 1024 >>> print(dotcode) #doctest: +ELLIPSIS digraph G { "Start state" [shape=doubleoctagon, style=filled, fillcolor=white, URL="..."]; "State 1" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "State 2" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "State 3" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "End state" [shape=ellipse, style=filled, fillcolor=white, URL="..."]; "Start state" ... "State 1" [fontsize=5, label="OpenChannelTransition", URL="..."]; "State 1" ... "State 2" [fontsize=5, label="Transition (Symbol_SYN;{Symbol_SYNACK})", URL="..."]; "State 2" ... "State 3" [fontsize=5, label="Transition (Symbol_ACK;{Symbol_PUSH})", URL="..."]; "State 3" ... "End state" [fontsize=5, label="CloseChannelTransition", URL="..."]; } :return: an automata with one sequence of chained states. :rtype: a :class:`netzob.Model.Grammar.Automata.Automata` """ return ChainedStatesAutomataFactory.generate(abstractSession, symbolList)
def generate(abstractSessions, symbolList): """Generate an automata by merging different abstract sessions in a Prefix Tree Acceptor (PTA). """ # Generate chained automatons from the provided list of abstract sessions from netzob.Inference.Grammar.AutomataFactories.ChainedStatesAutomataFactory import ChainedStatesAutomataFactory chainedAutomatons = [] for abstractSession in abstractSessions: chainedAutomaton = ChainedStatesAutomataFactory.generate( abstractSession, symbolList) chainedAutomatons.append(chainedAutomaton) if len(chainedAutomatons) <= 1: return chainedAutomatons[0] # Create an initial state/transition for the PTA automaton ptaInitialState = State("Start state") idx_state = 0 ptaStateA = State("State " + str(idx_state)) ptaStateA_saved = ptaStateA ptaTransition = OpenChannelTransition(startState=ptaInitialState, endState=ptaStateA, name="Open transition") # Merge the other automatons in the PTA automaton for automaton in chainedAutomatons: # Restore the first main state of the PTA ptaStateA = ptaStateA_saved # We go through the first transition (which should be an OpenChannelTransition) initialState = automaton.initialState if initialState is not None and len(initialState.transitions) > 0: transition = initialState.transitions[0] if isinstance(transition, OpenChannelTransition): transition = PTAAutomataFactory._getNextChainedTransition( transition) if transition is None: break # We loop over each state to compare inputSymbol/outputSymbols with the states of the PTA automaton while True: # We handle the closing state if isinstance(transition, CloseChannelTransition): if len(ptaStateA.transitions) > 0 and isinstance( ptaStateA.transitions[0], CloseChannelTransition): # The transition is equivalent in the PTA break else: # This is a new transition idx_state += 1 ptaStateB = State("End state " + str(idx_state)) ptaTransition = CloseChannelTransition( startState=ptaStateA, endState=ptaStateB, name="Close transition") break inputSymbol = transition.inputSymbol outputSymbols = transition.outputSymbols # We do the comparison with the PTA automaton at the transition level newTransition = True if len(ptaStateA.transitions) > 0 and isinstance( ptaStateA.transitions[0], Transition): if ptaStateA.transitions[0].inputSymbol == inputSymbol: if len(ptaStateA.transitions[0].outputSymbols ) > 0 and ptaStateA.transitions[ 0].outputSymbols[0] == outputSymbols[0]: # The transition is equivalent in the PTA newTransition = False ptaStateA = ptaStateA.transitions[0].endState if newTransition == True: idx_state += 1 ptaStateB = State("State " + str(idx_state)) ptaTransition = Transition( startState=ptaStateA, endState=ptaStateB, inputSymbol=inputSymbol, outputSymbols=[outputSymbols[0]], name="Transition") ptaStateA = ptaStateB transition = PTAAutomataFactory._getNextChainedTransition( transition) if transition is None: break from netzob.Model.Grammar.Automata import Automata return Automata(ptaInitialState, symbolList)
def generate(abstractSessions, symbolList): """Generate an automata by merging different abstract sessions in a Prefix Tree Acceptor (PTA). """ # Generate chained automatons from the provided list of abstract sessions from netzob.Inference.Grammar.AutomataFactories.ChainedStatesAutomataFactory import ChainedStatesAutomataFactory chainedAutomatons = [] for abstractSession in abstractSessions: chainedAutomaton = ChainedStatesAutomataFactory.generate(abstractSession, symbolList) chainedAutomatons.append(chainedAutomaton) if len(chainedAutomatons) <= 1: return chainedAutomatons[0] # Create an initial state/transition for the PTA automaton ptaInitialState = State("Start state") idx_state = 0 ptaStateA = State("State " + str(idx_state)) ptaStateA_saved = ptaStateA ptaTransition = OpenChannelTransition(startState=ptaInitialState, endState=ptaStateA, name="Open transition") # Merge the other automatons in the PTA automaton for automaton in chainedAutomatons: # Restore the first main state of the PTA ptaStateA = ptaStateA_saved # We go through the first transition (which should be an OpenChannelTransition) initialState = automaton.initialState if initialState is not None and len(initialState.transitions) > 0: transition = initialState.transitions[0] if isinstance(transition, OpenChannelTransition): transition = PTAAutomataFactory._getNextChainedTransition(transition) if transition is None: break # We loop over each state to compare inputSymbol/outputSymbols with the states of the PTA automaton while True: # We handle the closing state if isinstance(transition, CloseChannelTransition): if len(ptaStateA.transitions) > 0 and isinstance(ptaStateA.transitions[0], CloseChannelTransition): # The transition is equivalent in the PTA break else: # This is a new transition idx_state += 1 ptaStateB = State("End state " + str(idx_state)) ptaTransition = CloseChannelTransition(startState=ptaStateA, endState=ptaStateB, name="Close transition") break inputSymbol = transition.inputSymbol outputSymbols = transition.outputSymbols # We do the comparison with the PTA automaton at the transition level newTransition = True if len(ptaStateA.transitions) > 0 and isinstance(ptaStateA.transitions[0], Transition): if ptaStateA.transitions[0].inputSymbol == inputSymbol: if len(ptaStateA.transitions[0].outputSymbols) > 0 and ptaStateA.transitions[0].outputSymbols[0] == outputSymbols[0]: # The transition is equivalent in the PTA newTransition = False ptaStateA = ptaStateA.transitions[0].endState if newTransition == True: idx_state += 1 ptaStateB = State("State " + str(idx_state)) ptaTransition = Transition(startState=ptaStateA, endState=ptaStateB, inputSymbol=inputSymbol, outputSymbols=[outputSymbols[0]], name="Transition") ptaStateA = ptaStateB transition = PTAAutomataFactory._getNextChainedTransition(transition) if transition is None: break from netzob.Common.Models.Grammar.Automata import Automata return Automata(ptaInitialState, symbolList)