Example #1
0
    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)
Example #2
0
    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"))