Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f524380672 | |||
| 3261681f2a | |||
| 6acbc2a234 | |||
| b6ccfd66dc | |||
| 441ada02cc | |||
| 4a12aaddd0 | |||
| 75c1784ea8 | |||
| 9a7ddea09e | |||
| 477495ffa0 | |||
| 07c7df3e59 | |||
| 771c7f3d63 | |||
| a4feb59697 | |||
| 878553c450 | |||
| 066bc3cdca | |||
| 210e3949af | |||
| f274c70d74 | |||
| ba6ba0b99f | |||
| 889946a138 |
@@ -67,6 +67,7 @@ Table of Contents
|
||||
* [iOS](doc/ios.md) *12—14 (jailbroken)*
|
||||
* [macOS](doc/macos.md) *High Sierra—Big Sur*
|
||||
* [Linux](doc/linux_bluez.md) with *BlueZ* (default) but __not__ WSL
|
||||
* [User-space macOS, Linux, Windows](doc/btstack.md) with *BTstack*
|
||||
* [Firmware overview](doc/firmware.md)
|
||||
* [SEEMOO talks and publications](doc/publications.md)
|
||||
* [Examples](doc/examples.md)
|
||||
|
||||
+71
-25
@@ -1,4 +1,5 @@
|
||||
# iOS internalblued
|
||||
## Installation of internalblued on iOS
|
||||
|
||||
This project is a proxy that redirects the *iOS* Bluetooth socket and exposes it as a
|
||||
TCP socket which can be used to send HCI commands to the Bluetooth controller of the device.
|
||||
A jailbroken device is required.
|
||||
@@ -19,9 +20,9 @@ PCIe devices:
|
||||
* iPhone 11
|
||||
* iPhone SE2
|
||||
* iPhone 12
|
||||
* iPhone 13 (same as iPhone 12)
|
||||
|
||||
|
||||
## Installing
|
||||
1. Transfer the `.deb` file to your iOS device
|
||||
2. Run `dpkg -i your-deb-file.deb` to install `internalblued` on your device
|
||||
|
||||
@@ -42,32 +43,44 @@ In case the Bluetooth chip stops responding, Bluetooth has to be turned on and o
|
||||
|
||||
There is a Settings App pane for `internalblued` to turn off the daemon and adapt the listening port. However, this is usually not required. As long as `internalblue` is not connected to `internalblued`'s socket, Bluetooth can be used without any restrictions.
|
||||
|
||||
## Building internalblued
|
||||
1. Install [theos](https://github.com/theos/theos)
|
||||
2. Install the correct version of PrivateFramework header files (e.g. from [here](https://github.com/xybp888/iOS-SDKs)) for your build into your SDK
|
||||
3. Run `make package`
|
||||
4. A `.deb` file should be in the `packages` folder now
|
||||
|
||||
## Bypassing WriteRAM Restriction on PCIe iPhones (unc0ver)
|
||||
|
||||
## BlueTool
|
||||
Same principle but the firmware has checksums. Thanks to r0bre we how have
|
||||
[fpibro.py](https://github.com/seemoo-lab/frankenstein/blob/master/projects/BCM4387C2/ios_scripts/fpibro.py),
|
||||
which is capable of fixing these after modification.
|
||||
|
||||
More inconvenient to use, but still an option for unsupported devices, is `BlueTool`.
|
||||
It can even be scripted, but the scripts must be located in `/etc/bluetool`.
|
||||
Instead of overwriting the file, copy it to the `/tmp` folder and load it with `BlueTool`.
|
||||
Everything else will bootloop an A12+ device (see above).
|
||||
|
||||
For example, during our Random Number Generator (RNG) tests, we used the following commands
|
||||
to access the RNG area and execute the `LE_Rand` HCI command. Note that the input must be
|
||||
decimal but the output is hexadecimal. Similar to `internalblued`, `BlueTool` can only
|
||||
run while Bluetooth is turned off.
|
||||
|
||||
```
|
||||
```commandline
|
||||
power off
|
||||
device -D
|
||||
hci cmd 0xfc4d 0 38 96 0 32
|
||||
HCI Command Response: 01 4D FC 00 03 00 00 00 01 00 00 02 DC 70 02 76 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
hci cmd 0x2018
|
||||
HCI Command Response: 01 18 20 00 2A FC 1F 73 67 11 06 F9
|
||||
bcm -w /tmp/firmware.bin
|
||||
```
|
||||
|
||||
## Bypassing the WriteRAM Restriction
|
||||
None of the commands should return an error (e.g., no `bcm returned -1` error etc.).
|
||||
|
||||
***iPhone 12+13***
|
||||
|
||||
Hazelnut firmware with a WriteRAM bypass, compatible with iPhone 12+13:
|
||||
[Hazelnut_iPhone12+13_iOS15.2.bin](../ios-pcie/firmware/Hazelnut_iPhone12+13_iOS15.2.bin),
|
||||
will also work on jailbroken iOS 14.x iPhone 12.
|
||||
|
||||
Firmware modification and writing patches in C is supported as part of Frankenstein.
|
||||
Tooling and symbols for the [BCM4387C2](https://github.com/seemoo-lab/frankenstein/tree/master/projects/BCM4387C2)
|
||||
chip are available to perform research on the iPhone 12 and 13.
|
||||
|
||||
|
||||
***iPhone 11+SE2020***
|
||||
|
||||
Moana (iPhone 11) firmware with a WriteRAM bypass, compatible with iPhone 11+SE2020:
|
||||
[Moana_iPhone11+SE2_iOS15.bin](../ios-pcie/firmware/Moana_iPhone11+SE2_iOS15.bin),
|
||||
will also work with jailbroken iOS 14.x on iPhone SE2020.
|
||||
|
||||
|
||||
|
||||
## Bypassing the WriteRAM Restriction on UART iPhones (checkm8)
|
||||
|
||||
After iOS 13.3, WriteRAM is blocked. This is part of the Spectra mitigation and should prevent
|
||||
an attacker with control over `bluetoothd` to escalate into the Wi-Fi chip (yes, Wi-Fi, not Bluetooth, this is
|
||||
@@ -91,7 +104,8 @@ We can simply replace the `0x4c`, which is the WriteRAM command, with `0x42`, wh
|
||||
Note that `BlueTool` contains multiple copies of these `.hcd` files and you should replace all of them.
|
||||
The accordingly modified `BlueTool` needs to be copied to `/usr/sbin/BlueTool` and `/usr/sbin/BlueTool.sbin`.
|
||||
To get Bluetooth working properly again after replacing `BlueTool`, run:
|
||||
```
|
||||
|
||||
```commandline
|
||||
killall -9 bluetoothd internalblued BlueTool
|
||||
```
|
||||
Then, start a new *InternalBlue* Session.
|
||||
@@ -103,7 +117,39 @@ for `BlueTool` fails. **You can only reboot the device in this state with checkm
|
||||
be bricked if you do this on unthethered jailbreaks like unc0ver!** You can still unbrick it by re-flashing
|
||||
iOS, but if you did not have a blob backup, you'll need to upgrade it to the latest signed iOS version.
|
||||
|
||||
[BlueTool for iOS 13.6 on an iPhone 8](../ios/BlueTool_iPhone8_iOS13.6), might also work on other pre-A12 devices.
|
||||
[BlueTool for iOS 14.3 on an iPhone 7+8](../ios/BlueTool_iPhone7+8_iOS14.3), might also work on other pre-A12 devices.
|
||||
[BlueTool for iOS 14.7 on an iPhone 7+8](../ios/BlueTool_iPhone7+8_iOS14.7), might also work on other pre-A12 devices.
|
||||
[BlueTool for iOS 13.6 on an iPhone 8](../ios/firmware/BlueTool_iPhone8_iOS13.6), might also work on other pre-A12 devices.
|
||||
[BlueTool for iOS 14.3 on an iPhone 7+8](../ios/firmware/BlueTool_iPhone7+8_iOS14.3), might also work on other pre-A12 devices.
|
||||
[BlueTool for iOS 14.7 on an iPhone 7+8](../ios/firmware/BlueTool_iPhone7+8_iOS14.7), might also work on other pre-A12 devices.
|
||||
|
||||
|
||||
## Building internalblued (optional)
|
||||
|
||||
1. Install [theos](https://github.com/theos/theos)
|
||||
2. Install the correct version of PrivateFramework header files (e.g. from [here](https://github.com/xybp888/iOS-SDKs)) for your build into your SDK
|
||||
3. Run `make package`
|
||||
4. A `.deb` file should be in the `packages` folder now
|
||||
|
||||
|
||||
|
||||
## BlueTool
|
||||
|
||||
Instead of using InternalBlue, it is also possible to use Apple's undocumented internal
|
||||
tool `BlueTool`. It is way more inconvenient to use, has a lot of commands that will not show
|
||||
in the help menu, and easily crashes when using it inappropriately. Apple does not consider
|
||||
this to be an issue, since `BlueTool` cannot be called from sandboxed processes.
|
||||
|
||||
If you consider using `BlueTool` instead of InternalBlue, e.g., because your device is not
|
||||
yet supported, you can even script it. All scripts must be located in `/etc/bluetool`.
|
||||
|
||||
For example, during our Random Number Generator (RNG) tests, we used the following commands
|
||||
to access the RNG area and execute the `LE_Rand` HCI command. Note that the input must be
|
||||
decimal but the output is hexadecimal. Similar to `internalblued`, `BlueTool` can only
|
||||
run while Bluetooth is turned off.
|
||||
|
||||
```commandline
|
||||
device -D
|
||||
hci cmd 0xfc4d 0 38 96 0 32
|
||||
HCI Command Response: 01 4D FC 00 03 00 00 00 01 00 00 02 DC 70 02 76 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
hci cmd 0x2018
|
||||
HCI Command Response: 01 18 20 00 2A FC 1F 73 67 11 06 F9
|
||||
```
|
||||
+3
-3
@@ -5,7 +5,7 @@ Linux Setup
|
||||
The following steps are required to use the CYW20735B1/CYW20819A evaluation kit as normal HCI device on Linux with BlueZ.
|
||||
|
||||
|
||||
##1. Setup as HCI device
|
||||
## 1. Setup as HCI device
|
||||
|
||||
|
||||
**CYW20819**: Set up the device with a baud rate of 115200 and the Broadcom driver. The baud rate will be upgraded
|
||||
@@ -39,7 +39,7 @@ You can list your HCI devices:
|
||||
|
||||
hcitool dev
|
||||
|
||||
##3. Command line tools for connections
|
||||
## 3. Command line tools for connections
|
||||
|
||||
Scanning for devices:
|
||||
|
||||
@@ -114,4 +114,4 @@ cd /usr/lib/firmware/brcm/
|
||||
cp BCM4345C0.hcd BCM4345C0_orig.hcd
|
||||
wget https://github.com/RPi-Distro/bluez-firmware/blob/96eefffcccc725425fd83be5e0704a5c32b79e54/broadcom/BCM4345C0.hcd?raw=true
|
||||
mv 'BCM4345C0.hcd?raw=true' BCM4345C0.hcd
|
||||
```
|
||||
```
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ Prerequisites
|
||||
|
||||
*InternalBlue* runs as regular user, no administrator access is required.
|
||||
|
||||
Install `homebrew` (see https://brew.sh/) and then use it to install `python3` and optionally `git`.
|
||||
Install `homebrew` (see https://brew.sh/) and then use it to install `python3`, `cmake`, and optionally `git`.
|
||||
|
||||
Hardware and OS
|
||||
---------------
|
||||
|
||||
@@ -19,18 +19,21 @@ var base = Module.getBaseAddress('bluetoothd');
|
||||
// *** SELECT YOUR IOS VERSION HERE ***
|
||||
// Functions contain function name strings, easy to determine.
|
||||
var OI_HCIIfc_DataReceived = base.add(0xee5a4); // iOS 14.1, iPhone 12
|
||||
//var OI_HCIIfc_DataReceived = base.add(0xed0b8); // iOS 14.4, iPhone 8
|
||||
// var OI_HCIIfc_DataReceived = base.add(0xed9f8); // iOS 14.8, iPhone 8
|
||||
// var OI_HCIIfc_DataReceived = base.add(0xed0b8); // iOS 14.4, iPhone 8
|
||||
// var OI_HCIIfc_DataReceived = base.add(0xee9f0); // iOS 14.3, iPhone 8 (18C66)
|
||||
// var OI_HCIIfc_DataReceived = base.add(0x108e04); // iOS 13.5, iPhone SE2
|
||||
|
||||
var OI_HciIfc_CopyPayload = base.add(0xe3d7c); // iOS 14.1, iPhone 12
|
||||
//var OI_HciIfc_CopyPayload = base.add(0xe2ddc); // iOS 14.4, iPhone 8
|
||||
// var OI_HciIfc_CopyPayload = base.add(0xe3764); // iOS 14.8, iPhone 8
|
||||
// var OI_HciIfc_CopyPayload = base.add(0xe2ddc); // iOS 14.4, iPhone 8
|
||||
// var OI_HciIfc_CopyPayload = base.add(0xFE690); // iOS 13.5, iPhone SE2
|
||||
// var OI_HciIfc_CopyPayload = base.add(0xee9f0); // iOS 14.3, iPhone 8 (18C66)
|
||||
|
||||
var HCIIfc_src_ptr = base.add(0x671388); // iOS 14.1, iPhone 12
|
||||
//var HCIIfc_src_ptr = base.add(0x654318); // iOS 14.4, iPhone 8
|
||||
//var HCIIfc_src_ptr = base.add(0x6118A0); // iOS 13.5, iPhone SE2
|
||||
// var HCIIfc_src_ptr = base.add(0x688518); // iOS 14.8, iPhone 8
|
||||
// var HCIIfc_src_ptr = base.add(0x654318); // iOS 14.4, iPhone 8
|
||||
// var HCIIfc_src_ptr = base.add(0x6118A0); // iOS 13.5, iPhone SE2
|
||||
|
||||
|
||||
// Helper function to print hex
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from future import standard_library
|
||||
|
||||
import datetime
|
||||
import time
|
||||
import socket
|
||||
import struct
|
||||
import queue as queue2k
|
||||
|
||||
from . import hci
|
||||
from .core import InternalBlue
|
||||
standard_library.install_aliases()
|
||||
|
||||
# BTstack Daemon defaults
|
||||
BTSTACK_SERVER_HOST = "localhost"
|
||||
BTSTACK_SERVER_TCP_PORT = 13333
|
||||
|
||||
# BTstack defines
|
||||
OGF_BTSTACK = 0x3d
|
||||
BTSTACK_EVENT_STATE = 0x60
|
||||
BTSTACK_EVENT_POWERON_FAILED = 0x62
|
||||
|
||||
class BTstackCore(InternalBlue):
|
||||
global BTSTACK_SERVER_TCP_PORT
|
||||
global BTSTACK_SERVER_HOST
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
tcp_port=BTSTACK_SERVER_TCP_PORT,
|
||||
tcp_host=BTSTACK_SERVER_HOST,
|
||||
queue_size=1000,
|
||||
btsnooplog_filename=None,
|
||||
log_level='info',
|
||||
data_directory=".",
|
||||
replay=False
|
||||
):
|
||||
|
||||
super(BTstackCore, self).__init__(
|
||||
queue_size,
|
||||
btsnooplog_filename,
|
||||
log_level,
|
||||
data_directory,
|
||||
replay
|
||||
)
|
||||
|
||||
self.tcp_port = tcp_port
|
||||
self.tcp_host = tcp_host
|
||||
self.s_inject = None
|
||||
self.serial = False
|
||||
|
||||
def device_list(self):
|
||||
"""
|
||||
Get a list of the connected devices
|
||||
"""
|
||||
|
||||
if self.exit_requested:
|
||||
self.shutdown()
|
||||
|
||||
if self.running:
|
||||
self.logger.warn("Already running. call shutdown() first!")
|
||||
return []
|
||||
|
||||
return ["BTstack Daemon"]
|
||||
|
||||
def _recvPacket(self):
|
||||
# format: packet type, channel, len, payload
|
||||
header = self.s_inject.recv(6)
|
||||
(packet_type, channel, length) = struct.unpack("<HHH", header)
|
||||
payload = self.s_inject.recv(length)
|
||||
return packet_type, channel, length, payload
|
||||
|
||||
def local_connect(self):
|
||||
# Connect to BTstack Daemon via TCP
|
||||
return self._setupSockets()
|
||||
|
||||
def _recvThreadFunc(self):
|
||||
|
||||
"""
|
||||
This is the run-function of the recvThread. It receives HCI packets from the
|
||||
btstack socket.
|
||||
Received HCI packets are being put into the queues inside registeredHciRecvQueues and
|
||||
passed to the callback functions inside registeredHciCallbacks.
|
||||
The thread stops when exit_requested is set to True. It will do that on its own
|
||||
if it encounters a fatal error or the stackDumpReceiver reports that the chip crashed.
|
||||
"""
|
||||
|
||||
self.logger.debug("Receive Thread started.")
|
||||
|
||||
while not self.exit_requested:
|
||||
|
||||
# receive packet
|
||||
(packet_type, channel, length, payload) = self._recvPacket()
|
||||
received_time = datetime.datetime.now()
|
||||
|
||||
# Put relevant info into a tuple. The HCI packet is parsed with the help of hci.py.
|
||||
orig_len = length
|
||||
inc_len = length
|
||||
# flags
|
||||
# - 1 for incoming
|
||||
# - 2 for command/event
|
||||
flags = 1
|
||||
if packet_type == 4:
|
||||
flags |= 2
|
||||
drops = 0
|
||||
record = (hci.parse_hci_packet(bytes([packet_type]) + payload), orig_len, inc_len, flags, drops, received_time)
|
||||
|
||||
# Put the record into all queues of registeredHciRecvQueues if their
|
||||
# filter function matches.
|
||||
for queue, filter_function in self.registeredHciRecvQueues:
|
||||
if filter_function == None or filter_function(record):
|
||||
try:
|
||||
queue.put(record, block=False)
|
||||
except queue2k.Full:
|
||||
self.logger.warning(
|
||||
"recvThreadFunc: A recv queue is full. dropping packets.."
|
||||
)
|
||||
|
||||
# Call all callback functions inside registeredHciCallbacks and pass the
|
||||
# record as argument.
|
||||
for callback in self.registeredHciCallbacks:
|
||||
callback(record)
|
||||
|
||||
self.logger.debug("Receive Thread terminated.")
|
||||
|
||||
def _setupSockets(self):
|
||||
"""
|
||||
Start the framework by connecting to the BTstack daemon via TCP and tell it to power up
|
||||
"""
|
||||
self.logger.info("Connect to server on %s:%u" % (self.tcp_host, self.tcp_port))
|
||||
self.s_inject = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
timeout = time.time() + 3
|
||||
btstack_state = "OFF"
|
||||
|
||||
try:
|
||||
self.s_inject.connect((self.tcp_host, self.tcp_port))
|
||||
|
||||
# send power on
|
||||
power_on = struct.pack("<HBB", (OGF_BTSTACK << 10) | 2, 1, 1)
|
||||
header = struct.pack("<HHH", 1, 0, len(power_on))
|
||||
out = header + power_on
|
||||
self.s_inject.send(out)
|
||||
|
||||
# wait for state working or failed
|
||||
while (not self.exit_requested) and btstack_state == 'OFF':
|
||||
(packet_type, channel, length, payload) = self._recvPacket()
|
||||
if packet_type == 4:
|
||||
if length > 0:
|
||||
if payload[0] == BTSTACK_EVENT_STATE and length == 3 and payload[2] == 2:
|
||||
btstack_state = "WORKING"
|
||||
self.logger.info("BTstack working")
|
||||
if payload[0] == BTSTACK_EVENT_POWERON_FAILED:
|
||||
btstack_state = "FAILED"
|
||||
self.logger.error("BTstack startup failed")
|
||||
|
||||
except socket.error as e:
|
||||
if time.time() > timeout:
|
||||
self.logger.error("[!] Connection error: %s" % e)
|
||||
return False
|
||||
|
||||
connected = btstack_state == "WORKING"
|
||||
return connected
|
||||
|
||||
def _teardownSockets(self):
|
||||
"""
|
||||
Close s_inject sockets.
|
||||
"""
|
||||
|
||||
if self.s_inject is not None:
|
||||
self.s_inject.close()
|
||||
self.s_inject = None
|
||||
return False
|
||||
+8
-7
@@ -45,7 +45,7 @@ from threading import Timer
|
||||
from functools import wraps
|
||||
|
||||
import cmd2
|
||||
from cmd2 import fg, style
|
||||
from cmd2 import Fg, style
|
||||
|
||||
from . import Address
|
||||
from .hci import HCI_COMND
|
||||
@@ -139,7 +139,7 @@ class InternalBlueCLI(cmd2.Cmd):
|
||||
+ r"/___/_//_/\__/\__/_/ /_//_/\_,_/_/____/_/\_,_/\__/" + "\n" + "\n" \
|
||||
+ "type <help -v> for usage information!"
|
||||
|
||||
self.intro = style(banner, fg=fg.blue)
|
||||
self.intro = style(banner, fg=Fg.BLUE)
|
||||
|
||||
# History file
|
||||
if main_args.data_directory is not None:
|
||||
@@ -242,16 +242,17 @@ class InternalBlueCLI(cmd2.Cmd):
|
||||
self.internalblue = device[0]
|
||||
self.internalblue.interface = device[1]
|
||||
|
||||
self.memory_image_template_filename = (
|
||||
self.internalblue.data_directory + "/memdump__template.bin"
|
||||
)
|
||||
self.memory_image: Optional[bytes] = None
|
||||
|
||||
# Connect to device
|
||||
if not self.internalblue.connect():
|
||||
self.logger.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# now we have firmware info and can set firmware-specific variables
|
||||
self.memory_image_template_filename = (
|
||||
self.internalblue.data_directory + "/memdump_" + self.internalblue.fw.FW_NAME + "_template.bin"
|
||||
)
|
||||
self.memory_image: Optional[bytes] = None
|
||||
|
||||
# Enter command loop (runs until user quits)
|
||||
self.logger.info("Starting commandLoop for self.internalblue {}".format(self.internalblue))
|
||||
|
||||
|
||||
+18
-5
@@ -312,10 +312,11 @@ class InternalBlue(with_metaclass(ABCMeta, object)):
|
||||
self.logger.debug("Failed to unpack queue item.")
|
||||
continue
|
||||
|
||||
# Special handling of ADBCore and HCICore
|
||||
# Special handling of ADBCore, HCICore, BTstack Daemon
|
||||
# ADBCore: adb transport requires to prepend the H4 data with its length
|
||||
# HCICore: need to manually save the data to btsnoop log as it is not
|
||||
# reflected to us as with adb
|
||||
# BTstack: custom header { packet type, channel, payload len }
|
||||
if self.__class__.__name__ == "ADBCore":
|
||||
# prepend with total length for H4 over adb with modified Bluetooth module
|
||||
if not self.serial:
|
||||
@@ -332,6 +333,9 @@ class InternalBlue(with_metaclass(ABCMeta, object)):
|
||||
#
|
||||
# ...and that's how the data is formatted already anyway
|
||||
|
||||
# Prepend UART TYPE and length.
|
||||
out = p8(h4type) + data
|
||||
|
||||
elif self.__class__.__name__ == "HCICore":
|
||||
if self.write_btsnooplog:
|
||||
# btsnoop record header data:
|
||||
@@ -354,8 +358,17 @@ class InternalBlue(with_metaclass(ABCMeta, object)):
|
||||
self.btsnooplog_file.write(btsnoop_data)
|
||||
self.btsnooplog_file.flush()
|
||||
|
||||
# Prepend UART TYPE and length.
|
||||
out = p8(h4type) + data
|
||||
# Prepend UART TYPE and length.
|
||||
out = p8(h4type) + data
|
||||
|
||||
elif self.__class__.__name__ == "BTstackCore":
|
||||
|
||||
# Prepend BTstack network header
|
||||
packet_type = h4type
|
||||
channel = 0
|
||||
length = len(data)
|
||||
header = struct.pack("<HHH", packet_type, channel, length)
|
||||
out = header + data
|
||||
|
||||
# if the caller expects a response: register a queue to receive the response
|
||||
if queue is not None and filter_function is not None:
|
||||
@@ -716,9 +729,9 @@ class InternalBlue(with_metaclass(ABCMeta, object)):
|
||||
)
|
||||
return False
|
||||
|
||||
# Broadcom uses 0x000f as vendor ID, Cypress 0x0131
|
||||
# Broadcom uses 0x000f as vendor ID, Cypress 0x0131, Infineon 0x0009
|
||||
vendor = (version[9] << 8) + version[8]
|
||||
if vendor != 0xF and vendor != 0x131:
|
||||
if vendor != 0xF and vendor != 0x131 and vendor != 0x9:
|
||||
self.logger.critical("Not running on a Broadcom or Cypress chip!")
|
||||
return False
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# fw_0x420e.py
|
||||
#
|
||||
# Generic firmware file in case we do not know something...
|
||||
#
|
||||
# Copyright (c) 2020 The InternalBlue Team. (MIT License)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
# - The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
# - The Software is provided "as is", without warranty of any kind, express or
|
||||
# implied, including but not limited to the warranties of merchantability,
|
||||
# fitness for a particular purpose and noninfringement. In no event shall the
|
||||
# authors or copyright holders be liable for any claim, damages or other
|
||||
# liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
# out of or in connection with the Software or the use or other dealings in the
|
||||
# Software.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from .fw import MemorySection, FirmwareDefinition
|
||||
from .. import Address
|
||||
|
||||
|
||||
class CYW20820A1(FirmwareDefinition):
|
||||
"""
|
||||
CYW20820 is a Cypress evaluation board, the newest one that is currently available.
|
||||
|
||||
Known issues:
|
||||
|
||||
* `Launch_RAM` does not terminate and crashes the board.
|
||||
|
||||
To get this working anyway:
|
||||
The `Launch_RAM` handler HCI callback is at `0xF2884` and it can be overwritten with the
|
||||
address of the memory snippet you want to launch. For example, at `0x219000` there is some
|
||||
free memory. Put the function there. Then:
|
||||
|
||||
`internalblue.patchRom(0xF2884, p32(ASM_LOCATION_RNG+1)): # function table entries are sub+1
|
||||
|
||||
"""
|
||||
|
||||
# Firmware Infos
|
||||
# Evaluation Kit CYW920820
|
||||
FW_NAME = "CYW20820A1"
|
||||
|
||||
|
||||
# Memory Sections
|
||||
# start, end, is_rom? is_ram?
|
||||
SECTIONS = [
|
||||
MemorySection(0x00000000, 0x001FFFFF, True, False), # Internal ROM
|
||||
MemorySection(0x00200000, 0x0024FFFF, False, True), # Internal Memory Cortex M3
|
||||
MemorySection(
|
||||
0x00270000, 0x0027FFFF, False, True
|
||||
), # Internal Memory Patchram Contents
|
||||
MemorySection(0x00310000, 0x00321FFF, False, True), # HW Regs Cortex M3 (readable)
|
||||
]
|
||||
|
||||
# Patchram
|
||||
PATCHRAM_TARGET_TABLE_ADDRESS = 0x310000
|
||||
PATCHRAM_ENABLED_BITMAP_ADDRESS = 0x310404
|
||||
PATCHRAM_VALUE_TABLE_ADDRESS = 0x270000
|
||||
PATCHRAM_NUMBER_OF_SLOTS = 256
|
||||
PATCHRAM_ALIGNED = False
|
||||
# only seems to work 4-byte aligned here ...
|
||||
|
||||
# Launch_RAM is faulty so we need to overwrite it. This is the position of the handler.
|
||||
LAUNCH_RAM = 0xF2884
|
||||
HCI_EVENT_COMPLETE = 0x1179E
|
||||
|
||||
# Enable enhanced advertisement reports (bEnhancedAdvReport)
|
||||
ENHANCED_ADV_REPORT_ADDRESS = Address(0x20294C)
|
||||
|
||||
|
||||
+40
-7
@@ -265,7 +265,7 @@ class HCI_COMND(Enum):
|
||||
LE_Test_End = 0x201F
|
||||
LE_Remote_Connection_Parameter_Request_Reply = 0x2020
|
||||
LE_Remote_Connection_Parameter_Request_Negative_Reply = 0x2021
|
||||
VSC_CustomerExtension = 0xFC00
|
||||
VSC_CustomerExtension_or_GetPowerConsumption = 0xFC00
|
||||
VSC_WriteBdAddr = 0xFC01
|
||||
VSC_DumpSRAM = 0xFC02
|
||||
VSC_ChannelClassConfig = 0xFC03
|
||||
@@ -486,12 +486,16 @@ class HCI_COMND(Enum):
|
||||
VSC_PiconetClockAdjustment = 0xFD29
|
||||
VSC_ReadRetransmissionStatus = 0xFD2A
|
||||
VSC_SetTransmitPowerRange = 0xFD2F
|
||||
VSC_CountryCodeSelect = 0xFD31
|
||||
VSC_CellOnOffDebug = 0xFD32
|
||||
VSC_PageInquiryTxSuppression = 0xFD33
|
||||
VSC_RandomizeNativeClock = 0xFD35
|
||||
VSC_StoreFactoryCalibrationData = 0xFD36
|
||||
VSC_ReadSupportedVSCs = 0xFD3B
|
||||
VSC_LEWriteLocalSupportedFeatures = 0xFD3C
|
||||
VSC_LEReadRemoteSupportedBRCMFeatures = 0xFD3E
|
||||
VSC_LECreateExtendedAdvertiseInstance = 0xFD3A
|
||||
VSC_LERemoveExtendedAdvertiseInstance = 0xFD3B
|
||||
VSC_LEWriteLocalSupportedFeatures = 0xFD3C # or LE Set Extended Advertising Parameters
|
||||
VSC_LEReadRemoteSupportedBRCMFeatures = 0xFD3E # or LE Set Extended Scan Response Data
|
||||
VSC_BcsTimeline = 0xFD40
|
||||
VSC_BcsTimelineBroadcastReceive = 0xFD41
|
||||
VSC_ReadDynamicMemoryPoolStatistics = 0xFD42
|
||||
@@ -518,27 +522,56 @@ class HCI_COMND(Enum):
|
||||
VSC_SetSpecialSniffTransitionEnable = 0xFD71
|
||||
VSC_EnableBTSync = 0xFD73
|
||||
VSC_hciulp_handleBTBLEHighPowerControl = 0xFD79
|
||||
VSC_MaskedTracesDebug = 0xFD7D
|
||||
VSC_HandleCustomerEnableHALinkCommands = 0xFD7C
|
||||
VSC_DWPTestCommands = 0xFD7D
|
||||
VSC_DWPTestCommands = 0xFD7D # or Write Number of Completed Packets
|
||||
VSC_Olympic_LTE_Settings = 0xFD7F
|
||||
VSC_PowerLdoDuringSleep = 0xFD81
|
||||
VSC_WriteLERemotePublicAddress = 0xFD82
|
||||
VSC_1SecondTimerCommands = 0xFD86
|
||||
VSC_ForceWLANChannel = 0xFD88
|
||||
VSC_DisableTPC = 0xFD89
|
||||
VSC_GizmoDetected = 0xFD8A
|
||||
VSC_SVTConfigSetup = 0xFD8B
|
||||
VSC_HandleCustomerReadHADeltaCommands = 0xFD8F
|
||||
VSC_SetupRSSCommands = 0xFD9A
|
||||
VSC_SetUartAutoResume = 0xFD9B
|
||||
VSC_SetupRSSLocalCommands = 0xFD9C
|
||||
VSC_WriteLocalHostStateLE = 0xFDA0
|
||||
VSC_AudioBufferCommands = 0xFDA1
|
||||
VSC_HealthStatusReport = 0xFDA4
|
||||
VSC_ChangeConnectionPriority = 0xFDA8
|
||||
VSC_SamSetupCommand = 0xFDAA
|
||||
VSC_bthci_cmd_ble_enhancedTransmitterTest_hopping = 0xFDAB
|
||||
VSC_Handle_coex_debug_counters = 0xFDAF
|
||||
VSC_Read_Inquiry_Transmit_Power = 0xFDBB
|
||||
VSC_Enable_PADGC_Override = 0xFDBE
|
||||
VSC_CoExDebugCounters = 0xFDAF
|
||||
VSC_LEClearAllMatchingRules = 0xFDB2
|
||||
VSC_HighPowerBluetoothClassic = 0xFDB3
|
||||
VSC_HP_EDRv2 = 0xFCB9
|
||||
VSC_Read_Inquiry_Transmit_Power = 0xFDBB # or LE Remove Zone
|
||||
VSC_LEWriteFilteringFeatureSet = 0xFDBD
|
||||
VSC_Enable_PADGC_Override = 0xFDBE # or LE Enable Asymmetric Latency
|
||||
VSC_WriteTxPowerAFHMode = 0xFDCB
|
||||
VSC_LeConfigureScanParameters = 0xFDC0
|
||||
VSC_LePrioritizationThreshold = 0xFDC1
|
||||
VSC_setMinimumNumberOfUsedChannels = 0xFDCD
|
||||
VSC_HandleBrEdrLinkQualityStats = 0xFDCE
|
||||
VSC_SetHostAssistedAfhMaps = 0xFDD1
|
||||
VSC_SetLighthouseParameters = 0xFDD2
|
||||
VSC_LighthouseControl = 0xFDD3
|
||||
VSC_LighthouseDebugQuery = 0xFDD4
|
||||
VSC_ReadLocalFeatures = 0xFDDA
|
||||
VSC_HdrChangeConnectionPacketType = 0xFDDB
|
||||
VSC_HdrSetupSynchronousConnection = 0xFDDC
|
||||
VSC_EnhancedLinkQuelityStats = 0xFDDD
|
||||
VSC_EnableHostAssistedAfhMapsDiversity = 0xFDDE
|
||||
VSC_Diag = 0xFDEA
|
||||
VSC_EnhancedPowerStats = 0xFDF0
|
||||
VSC_HdrControl = 0xFDFD
|
||||
VSC_HdrConfiguration = 0xFDFE
|
||||
VSC_MagnetStatisticControl = 0xFE00
|
||||
VSC_HdrAcceptSynchronousConnection = 0xFE04
|
||||
VSC_EpaGpioCommand = 0xFE08
|
||||
VSC_ReadProprietaryRemoteFeatures = 0xFE0A
|
||||
VSC_SectorErase = 0xFF5E
|
||||
VSC_Chip_Erase = 0xFFCE
|
||||
VSC_EnterDownloadMode = 0xFFED
|
||||
|
||||
@@ -205,7 +205,8 @@ class iOSCore(InternalBlue):
|
||||
except socket.timeout:
|
||||
continue # this is ok. just try again without error
|
||||
|
||||
self.logger.debug("H4 Data: %s", received_data)
|
||||
if len(received_data) > 0:
|
||||
self.logger.debug("H4 Data: %s", received_data)
|
||||
|
||||
(record_data, is_more) = self._getLatestH4Blob(new_data=received_data)
|
||||
while record_data is not None:
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user