def handleTCP(self, event, data, datalen): """Decode an IPPROTO_TCP packet header, and log the payload.""" datalen -= 0x14 tcpHeader = Struct.Group(None, Struct.UInt16BEHex("source"), Struct.UInt16BEHex("dest"), Struct.UInt32BE("seq"), Struct.UInt32BE("ack_seq"), Struct.UInt16BEHex("flags"), Struct.UInt16BE("window"), Struct.UInt16BEHex("checksum"), Struct.UInt16BEHex("urg_ptr")) data = tcpHeader.decode(data) event.pushDecoded("iPhone TCP [%s -> %s] len=0x%04x" % ( self.portNumbers[tcpHeader.source], self.portNumbers[tcpHeader.dest], datalen, )) event.appendDecoded("\nTCP Header:\n%s" % str(tcpHeader)) event.appendDecoded("\nTCP Payload:\n%s" % Types.hexDump(data)) # Look for a protocol-specific handler for port in tcpHeader.source, tcpHeader.dest: fn = getattr(self, "port_%s" % self.portNumbers[port], None) if fn: fn(event, data, datalen)
def port_lockdownd(self, event, data, datalen): """Handle lockdownd packets. These form a stream, which may or may not line up with the underlying USB packets. Each lockdownd packet is an XML plist, prefixed with a 32-bit length. """ summary = [] self.lockdownBuffer += data if datalen == 0: # Leave the TCP decoder at the top of the stac return elif datalen != len(data): # Nothing we can reliably do without the whole log. self.lockdownBuffer = "" summary.append("ERROR, incomplete log!") elif (len(self.lockdownBuffer) >= 10 and self.lockdownBuffer[0] == '\0' and isascii(self.lockdownBuffer[1:])): # I haven't seen this documented, but sometimes lockdownd sends # ASCII error messages that are prefixed with one NUL byte. summary.append("Message, %r" % self.lockdownBuffer[1:]) elif len(self.lockdownBuffer) >= 10 and self.lockdownBuffer[4:9] != "<?xml": # Something else that isn't a plist? self.lockdownBuffer = "" summary.append("UNRECOGNIZED (SSL encrypted?)") else: # Decode all the packets we can while len(self.lockdownBuffer) >= 4: length = struct.unpack(">I", self.lockdownBuffer[:4])[0] if len(self.lockdownBuffer) < length + 4: break packet = self.lockdownBuffer[4:length + 4] self.lockdownBuffer = self.lockdownBuffer[length + 4:] event.appendDecoded("\nComplete lockdownd packet:\n%s" % Types.hexDump(packet)) kvFull = [] kvAbbrev = [] for k, v in plistlib.readPlistFromString(packet).items(): kvFull.append(" %s = %s" % (k, v)) if isinstance(v, plistlib.Data): v = "(data)" elif isinstance(v, dict): v = "(dict)" kvAbbrev.append("%s=%s" % (k, v)) event.appendDecoded("\nDecoded plist:\n%s" % "\n".join(kvFull)) summary.append("{%s}" % " ".join(kvAbbrev)) event.pushDecoded("lockdownd: %s" % (" ".join(summary) or "fragment"))