def _finalizeScript(script, delayStopRecording): """ Inserts a stop-recording marker after the first send/recv after the start-recording marker. @param The script to finalize @return The finalized script """ unpackedScript = Compiler._unpackScript(script) # find start-recording marker iStartRecording = tools.findFirst(unpackedScript, itemType=atom.START_RECORDING) assert iStartRecording >= 0 # find next send iSend = tools.findFirst(unpackedScript, itemType=atom.SEND, offset=iStartRecording) assert iSend >= 0 # find next recv iRecv = tools.findFirst(unpackedScript, itemType=atom.RECV, offset=iSend) assert iRecv >= 0 # insert stop-recording marker if delayStopRecording is not None: # insert wait before stop-recording marker unpackedScript = unpackedScript[:iRecv + 1] + [atom.WAIT(timeout=delayStopRecording), atom.STOP_RECORDING()] + unpackedScript[iRecv + 1:] else: # do not wait, but tell the stop-recording marker to close the protocol-socket unpackedScript = unpackedScript[:iRecv + 1] + [atom.STOP_RECORDING()] + unpackedScript[iRecv + 1:] return unpackedScript """
def getTracesBetween(self, start, end): traces = [] iCallStart = findFirst(self.eventStack, start, Call) while iCallStart in range(len(self.eventStack)): iCallEnd = findFirst(self.eventStack, end, Call, iCallStart+1) if iCallEnd not in range(len(self.eventStack)): break # now walk the event-stack, looking for the corresponding ret event i = iCallEnd+1 openCalls = 1 while i in range(len(self.eventStack)) and openCalls > 0: event = self.eventStack[i] if isinstance(event, Call): openCalls += 1 else: openCalls -= 1 i += 1 iRetEnd = i-1 newTrace = self.getSubTrace(iCallStart, iRetEnd) traces.append(newTrace) iCallStart = findFirst(self.eventStack, start, Call, iCallStart+1) return traces
def getTracesWithCallStack(self, callstack): start = callstack[0] end = callstack[-1] subTraces = [] iStart = findFirst(self.eventStack, start, Call, 0) while iStart in range(len(self.eventStack)): iEnd = findFirst(self.eventStack, end, Call, iStart) while iEnd in range(len(self.eventStack)): way = [] wayValid = True for i in range(iStart, iEnd+1): event = self.eventStack[i] if isinstance(event, Call): way.append(event.addr) else: way.pop() if len(way) == 0: wayValid = False break # compare given callstack with current callstack if wayValid and len(callstack) == len(way): equal = True for i in range(len(callstack)): if callstack[i] != way[i]: equal = False break if equal: # create subtrace iEndRet = findFirst(self.eventStack, end, Return, iEnd) subTraces.append(self.getSubTrace(iEnd, iEndRet)) iEnd = findFirst(self.eventStack, end, Call, iEnd+1) iStart = findFirst(self.eventStack, start, Call, iStart+1) return subTraces
def getWaysBetween(self, start, end): """ Gets all direct call-stacks from one function to another (including both ends) @param start: The function to start at; If None, then the virtual starting node of the trace is used. @param end: The function to end at @return: A list of call-stacks """ start = start or self.startingNode ways = [] iStart = findFirst(self.eventStack, start, Call, 0) while iStart in range(len(self.eventStack)): iEnd = findFirst(self.eventStack, end, Call, iStart) while iEnd in range(len(self.eventStack)): way = [] wayValid = True for i in range(iStart, iEnd+1): event = self.eventStack[i] if isinstance(event, Call): way.append(event.addr) else: # check if ret and last call belong together if len(way) == 0: raise Exception("Invalid state: Encountered a ret (call: %x, ret-addr: %x) without any open calls. iStart: %d (%x), iEnd: %d (%x), i: %d" % (event.call.addr, event.call.retAddr, iStart, start, iEnd, end, i)) if event.call.addr != way[-1]: raise Exception("Invalid state: Latest call (%x) and ret (%x) events do not match." % (way[-1], event.call.addr)) way.pop() # Did we hit the end of the start function? if len(way) == 0: wayValid = False break if wayValid: ways.append(way) if len(way) >= 2: lastCaller = way[-2] iEndLasterCaller = findFirst(self.eventStack, lastCaller, Return, iEnd+1) if iEndLasterCaller == -1: return ways iEnd = findFirst(self.eventStack, end, Call, iEndLasterCaller) else: iEnd = findFirst(self.eventStack, end, Call, iEnd+1) iStart = findFirst(self.eventStack, start, Call, iStart+1) return ways