Ejemplo n.º 1
0
    def handleNexus5StackDump(self, hcipkt):
        checksum_correct = self.verifyChecksum(hcipkt.data[5:])
        packet_type = u8(hcipkt.data[4])

        if packet_type == 0x2C:
            data = hcipkt.data[6:]
            values = [u32(data[i:i + 4]) for i in range(0, 64, 4)]
            log.debug("Stack Dump (%s):\n%s" % (
                "checksum correct"
                if checksum_correct else "checksum NOT correct",
                "\n".join([hex(x) for x in values]),
            ))
            if data[0] == "\x02":
                # This is the second stack dump event (contains register values)
                log.warn("Received Stack-Dump Event (contains %d registers):" %
                         (u8(data[1])))
                registers = (
                    "pc: 0x%08x   lr: 0x%08x   sp: 0x%08x   r0: 0x%08x   r1: 0x%08x\n"
                    % (values[2], values[3], values[1], values[4], values[5]))
                registers += (
                    "r2: 0x%08x   r3: 0x%08x   r4: 0x%08x   r5: 0x%08x   r6: 0x%08x\n"
                    % tuple(values[6:11]))
                log.warn(registers)
                return True

        elif packet_type == 0xF0:  # RAM dump
            self.handleRamDump(hcipkt.data[10:])

        elif packet_type == 0x4C:  # RAM dump (last frame)
            self.handleRamDump(hcipkt.data[10:])
            # This is the last pkt ouput:
            self.finishStackDump()
            return True
        return False
    def from_connection_buffer(connection):

        # Possible TODO: Convert this to a Katai Struct parser with a proper .ksy grammar.
        return ConnectionInformation(
            u32(connection[:4]),
            connection[0x28:0x2E][::-1],
            u32(connection[0x4C:0x50]),
            u32(connection[0x1C:0x20]) & 1 << 15 == 0,
            u16(connection[0x64:0x66]),
            connection[0x78:0x88],
            u8(connection[0xA7:0xA8]),
            connection[0x68:0x68 + u8(connection[0xA7:0xA8])],
            u8(connection[0x9C:0x9D]) - 127,
            connection[0x30:0x38],
            connection[0x38:0x40],
            connection[0x0C:0x0D],
        )
Ejemplo n.º 3
0
 def handleRamDump(self, data):
     """ Data should be a byte string containing the address (4 byte)
     followed by the actual ram dump (at this address)
     """
     addr = u32(data[:4])
     if self.memdump_addr == None:
         self.memdump_addr = addr
     self.memdumps[addr - self.memdump_addr] = data[4:]
     log.debug("Stack dump handling addr %08x", addr - self.memdump_addr)
Ejemplo n.º 4
0
    def _read_btsnoop_hdr(self):
        """
        Read the btsnoop header (see RFC 1761) from the snoop socket (s_snoop).
        """

        data = self.s_snoop.recv(16)
        if len(data) < 16:
            return None
        if (self.write_btsnooplog) and self.btsnooplog_file.tell() == 0:
            self.btsnooplog_file.write(data)
            self.btsnooplog_file.flush()

        btsnoop_hdr = (
            data[:8],
            u32(data[8:12], endian="big"),
            u32(data[12:16], endian="big"),
        )
        log.debug("BT Snoop Header: %s, version: %d, data link type: %d" % btsnoop_hdr)
        return btsnoop_hdr
Ejemplo n.º 5
0
    def handleS10StackDump(self, hcipkt):
        """
        Packets in stack dump:
            1b 03 90: contains pc and r0
            1b 03 9c
            1b 03 00 (x3)
            1b 03 f0 (whole ram)
            
        """

        checksum_correct = self.verifyChecksum(hcipkt.data[3:])
        packet_type = u8(hcipkt.data[2])

        if packet_type == 0x90:
            data = hcipkt.data[4:]
            values = [u32(data[i:i + 4]) for i in range(0, 64 * 2, 4)]
            log.debug("Stack Dump (%s):\n%s" % (
                "checksum correct"
                if checksum_correct else "checksum NOT correct",
                "\n".join([hex(x) for x in values]),
            ))
            # Values different than in other stack dump formats, experimental output!
            log.warn("Received S10 Stack-Dump Event (contains %d registers):" %
                     (u8(data[1])))
            registers = (
                "pc: 0x%08x   lr: 0x%08x   sp: 0x%08x   r0: 0x%08x   r1: 0x%08x\n"
                % (values[16], values[17], values[23], values[19], values[20]))
            registers += (
                "r2: 0x%08x   r3: 0x%08x   r4: 0x%08x   r5: 0x%08x   r6: 0x%08x\n"
                % (values[21], values[22], values[23], values[24], values[25]))
            log.warn(registers)
            return True

        # log.info("%x" % u32(hcipkt.data[8:12]))
        # no last packet for S10e, just the size counts here... also is sometimes longer and sometimes shorter
        if packet_type == 0xF0 and u32(hcipkt.data[8:12]) == 0x230080:
            # This is the last pkt ouput:
            self.finishStackDump()
            return True

        return False
Ejemplo n.º 6
0
    def handleEvalStackDump(self, hcipkt):
        """
        Handles a core dump from the evaluation board. To trigger a dump execute:
            sendhcicmd 0xfc4e e81e2000
        This executes some memory set to ffff which is an invalid command.
        Many events like executing address 0x0 will only crash the chip but not
        trigger a proper stack dump.

        The evaluation board has quite a lot of memory, RAM dump takes ages...

        dbfw_coredump_exception_cm3() generates the following dumps:
            2c: CoreDumpInfo
            2c: CoreDumpCPURegs
            90: CoreDumpCPURegsExtend
            f0: CoreDumpRAMImage
            78: CoreDumpRAMImage EOF
            9c: CoreDumpHWRegs
            01: CoreDumpEnd

        :param hcipkt: stack dump packet
        :return: returns True if dump could be decoded.
        """
        checksum_correct = self.verifyChecksum(hcipkt.data[3:])
        packet_type = u8(hcipkt.data[2])

        log.debug("packet type %x", packet_type)

        # TODO CoreDumpInfo (shows LMP/HCI version, memory dumps)

        # CoreDumpCPURegs
        if packet_type == 0x2C:
            data = hcipkt.data[4:]
            values = [u32(data[i:i + 4]) for i in range(0, 64, 4)]
            log.debug("Stack Dump (%s):\n%s" % (
                "checksum correct"
                if checksum_correct else "checksum NOT correct",
                "\n".join([hex(x) for x in values]),
            ))
            if data[0] == "\x02":
                # This is the second stack dump event (contains register values)
                log.warn(
                    "Received Evaluation Stack-Dump Event (contains %d registers):"
                    % (u8(data[1])))
                registers = (
                    "pc: 0x%08x   lr: 0x%08x   sp: 0x%08x   r0: 0x%08x   r1: 0x%08x\n"
                    % (values[2], values[3], values[1], values[4], values[5]))
                registers += (
                    "r2: 0x%08x   r3: 0x%08x   r4: 0x%08x   r5: 0x%08x   r6: 0x%08x\n"
                    % tuple(values[6:11]))
                log.warn(registers)
                return True

        # CoreDumpRAMImage
        # TODO: Eval board produces this twice:
        #  for 0x200000+0x50000 and 0x270000+0x10000
        elif packet_type == 0xF0:
            self.handleRamDump(hcipkt.data[8:])
            return True

        # Last packet produced by CoreDumpRAMImage
        elif packet_type == 0x78:  # RAM dump (last frame), TODO not sure if this works
            # This is the last pkt ouput:
            log.info("End of stackdump block...")
            self.finishStackDump()
            return True

        # On a Raspberry Pi 3, the last packet of a stack dump is '1b0340df0338'.... so it's 0x40
        elif packet_type == 0xE8:
            # FIXME Raspi memdump is divided in two parts!
            # address change from 0001fe38 to packet type e8 and then it's computing addr -0130000
            # negative addr does not work with finishStackDump()
            # so even though the last packet is 0x40, let's just finish on 0xe8
            log.info(
                "End of first stackdump block, writing to file and skipping second..."
            )
            self.finishStackDump()
            return True

        return False
Ejemplo n.º 7
0
    def getHciDeviceList(self):
        # type: () -> List[Device]
        """
        Get a list of available HCI devices. The list is obtained by executing
        ioctl syscalls HCIGETDEVLIST and HCIGETDEVINFO. The returned list 
        contains dictionaries with the following fields:
            dev_id          : Internal ID of the device (e.g. 0)
            dev_name        : Name of the device (e.g. "hci0")
            dev_bdaddr      : MAC address (e.g. "00:11:22:33:44:55")
            dev_flags       : Device flags as decimal number
            dev_flags_str   : Device flags as String (e.g. "UP RUNNING" or "DOWN")
        """

        # Open Bluetooth socket to execute ioctl's:
        try:
            s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
                              socket.BTPROTO_HCI)
        # Ticket 6: does not run on Windows with Kali subsystem
        except socket.error:
            log.warn(
                "Opening a local Bluetooth socket failed. Not running on native Linux?"
            )
            return []

        # Do ioctl(s,HCIGETDEVLIST,arg) to get the number of available devices:
        # arg is struct hci_dev_list_req (/usr/include/bluetooth/hci.h)
        arg = p32(16)  # dl->dev_num = HCI_MAX_DEV which is 16 (little endian)
        arg += b"\x00" * (8 * 16)
        devices_raw = fcntl.ioctl(s.fileno(), HCIGETDEVLIST, arg)
        num_devices = u16(devices_raw[:2])
        log.debug("Found %d HCI devices via ioctl(HCIGETDEVLIST)!" %
                  num_devices)

        device_list = []
        for dev_nr in range(num_devices):
            dev_struct_start = 4 + 8 * dev_nr
            dev_id = u16(devices_raw[dev_struct_start:dev_struct_start + 2])
            # arg is struct hci_dev_info (/usr/include/bluetooth/hci.h)
            arg = p16(dev_id)  # di->dev_id = <device_id>
            arg += b"\x00" * 20  # Enough space for name, bdaddr and flags
            dev_info_raw = bytearray(
                fcntl.ioctl(s.fileno(), HCIGETDEVINFO, arg))
            dev_name = dev_info_raw[2:10].replace(b"\x00", b"").decode()
            dev_bdaddr = ":".join(
                ["%02X" % x for x in dev_info_raw[10:16][::-1]])
            dev_flags = u32(dev_info_raw[16:20])
            if dev_flags == 0:
                dev_flags_str = "DOWN"
            else:
                dev_flags_str = " ".join([
                    name for flag, name in zip(
                        bin(dev_flags)[2:][::-1],
                        [
                            "UP",
                            "INIT",
                            "RUNNING",
                            "PSCAN",
                            "ISCAN",
                            "AUTH",
                            "ENCRYPT",
                            "INQUIRY",
                            "RAW",
                            "RESET",
                        ],
                    ) if flag == "1"
                ])

            device_list.append({
                "dev_id": dev_id,
                "dev_name": dev_name,
                "dev_bdaddr": dev_bdaddr,
                "dev_flags": dev_flags,
                "dev_flags_str": dev_flags_str,
            })
        s.close()
        return cast("List[Device]", device_list)