Compare commits
13 Commits
python2
...
blacklisting
| Author | SHA1 | Date | |
|---|---|---|---|
| ec9240e620 | |||
| e2fb710f51 | |||
| c84a0cd123 | |||
| 31f6a8d58a | |||
| 7bc7a956ea | |||
| cf51abc428 | |||
| 1bf8c0c132 | |||
| 2d3ed7f734 | |||
| ac1df0b260 | |||
| 053ad32297 | |||
| 8cb4109e81 | |||
| 8e0f099a83 | |||
| c842e4ec7d |
@@ -59,6 +59,11 @@ All steps on a plain Ubuntu 18.04:
|
||||
cmake ..
|
||||
make
|
||||
make install
|
||||
|
||||
Packets required on a current (July 2019) Raspian:
|
||||
|
||||
sudo apt-get --allow-releaseinfo-change update
|
||||
sudo apt-get install git python-setuptools binutils-arm-none-eabi adb python-pip python-dev gcc libffi-dev
|
||||
|
||||
|
||||
|
||||
|
||||
+10
-2
@@ -1,10 +1,18 @@
|
||||
InternalBlue PoCs and Examples
|
||||
==============================
|
||||
|
||||
All examples were tested on a *Nexus 5* (*BCM4339* chip with firmware *BCM4335C0*) on *Android* and *LineageOS*.
|
||||
The following examples were tested on a *Nexus 5* (*BCM4339* chip with firmware *BCM4335C0*) on *Android* and *LineageOS*.
|
||||
|
||||
* [CVE_2018_5383_Invalid_Curve_Attack_PoC](CVE_2018_5383_Invalid_Curve_Attack_PoC.py)
|
||||
provides tries to set the y-coordinate during ECDH key exchange to zero. If the device under test accepts the pairing (50% probability), it is vulnerable.
|
||||
* [LMP_MAC_Address_Filter](LMP_MAC_Address_Filter.py)
|
||||
replies to all LMP packets with `LMP_not_accepted` if their source is not from a MAC address in the whitelist.
|
||||
* [NiNo_PoC](NiNo_PoC.py) sets the IO capabilities of the *Nexus 5* to no input, no output.
|
||||
* [NiNo_PoC](NiNo_PoC.py) sets the IO capabilities of the *Nexus 5* to no input, no output.
|
||||
|
||||
Examples for the Raspberry Pi 3:
|
||||
|
||||
* [raspi3_rxdn](raspi4_rxdn.py) prints the first bytes of the LE connection struct within the `_connTaskRxDone` callback.
|
||||
For debugging purposes, warnings are shown for packet failures. The full logging can be enabled via `log_level debug` on the
|
||||
*InternalBlue* command line. It contains the current channel, RSSI, and event number for each packet. To blacklist channels
|
||||
from hopping, use `sendhcicmd 0x2014 ff00000000` or similar. Use `wireshark` or `btmon`
|
||||
to see the channel blacklisting live within the connection struct.
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
from pwn import *
|
||||
from internalblue.adbcore import ADBCore
|
||||
from internalblue.bluezcore import BluezCore
|
||||
|
||||
"""
|
||||
Script that shows receive statistics from LE connections over HCI on the CYW20735B1 evaluation board.
|
||||
Generated with Nexmon.
|
||||
"""
|
||||
|
||||
internalblue = ADBCore()
|
||||
try:
|
||||
internalblue.interface = internalblue.device_list()[0][1] # just use the first Android device
|
||||
except IndexError:
|
||||
internalblue = BluezCore()
|
||||
try:
|
||||
internalblue.interface = internalblue.device_list()[0][1] # ...or the first local HCI interface
|
||||
except IndexError:
|
||||
log.critical("Adapt the Python script to use an available Broadcom Bluetooth interface.")
|
||||
exit(-1)
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
progress_log = log.info("Connected to first target, installing patches...")
|
||||
|
||||
# GENERATED PATCHES
|
||||
internalblue.patchRom(0x0008ea46, '\x89\xf1\x5b\xbc')
|
||||
internalblue.patchRom(0x0008edc2, '\x89\xf1\x1d\xbc')
|
||||
internalblue.patchRom(0x0008eec0, '\x89\xf1\x1e\xbb')
|
||||
internalblue.writeMem(0x00218200, '\x10\xb5\xcc\x22\xff\x21\xce\x20\x0c\xf6\x43\xfe\x04\x46\x04\x22\x07\x49\x0a\x30\x50\xf6\x53\xfb\x06\x4b\x04\xf1\x0e\x00\x19\x68\xc8\x22\x50\xf6\x4c\xfb\x20\x46\xbd\xe8\x10\x40\x0c\xf6\x03\xbd\x18\x80\x21\x00\x80\x28\x28\x00')
|
||||
internalblue.writeMem(0x00218300, '\x95\xf6\x70\xfc\xff\xf7\x7c\xff\x76\xf6\x9f\xbb\x00\xbf\x00\xbf')
|
||||
internalblue.writeMem(0x00218500, '\x2d\xe9\xf0\x5f\xfe\xb5\x07\x46\xf3\x22\xff\x21\xf5\x20\x0c\xf6\xc0\xfc\x04\x46\x04\xf1\x0a\x03\x04\x22\x0f\x49\x18\x46\x50\xf6\xce\xf9\x04\xf1\x0e\x03\x4f\xf0\xef\x02\x39\x46\x18\x46\x50\xf6\xc6\xf9\x04\xf1\x0e\x03\x4f\xf0\x01\x02\x07\xf5\xe9\x71\x18\x46\x50\xf6\xbd\xf9\x20\x46\x0c\xf6\x76\xfb\x38\x46\xbd\xe8\xfe\x40\x76\xf6\xb8\xbc\x00\xbf\x00\xbf\x00\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218600, '\x70\xb5\x05\x46\xfe\xb5\x05\x46\xf4\x22\xff\x21\xf6\x20\x0c\xf6\x40\xfc\x04\x46\x04\xf1\x0a\x03\x04\x22\x0b\x49\x18\x46\x50\xf6\x4e\xf9\x04\xf1\x0e\x03\x4f\xf0\xf0\x02\x29\x46\x18\x46\x50\xf6\x46\xf9\x20\x46\x0c\xf6\xff\xfa\x00\xf0\xe2\xf8\xbd\xe8\xfe\x40\x76\xf6\xc1\xbb\x00\xbf\x00\xbf\x08\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218800, '\x10\xb5\x08\x22\x82\xb0\xff\x21\x0a\x20\x0c\xf6\x42\xfb\x04\x22\x04\x46\x0b\x49\x0a\x30\x50\xf6\x52\xf8\x00\x20\x9f\xf6\xec\xff\x95\xf6\x3f\xff\x02\xa9\x41\xf8\x04\x0d\x04\x22\x04\xf1\x0e\x00\x50\xf6\x45\xf8\x20\x46\x0c\xf6\xfe\xf9\x02\xb0\x10\xbd\x00\xbf\x10\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218000, '\x52\x58\x44\x4e\x00\x00\x00\x00\x4c\x45\x50\x52\x00\x00\x00\x00\x52\x53\x53\x49\x00\x00\x00\x00\x52\x42\x55\x46\x00')
|
||||
|
||||
|
||||
# shutdown connection
|
||||
internalblue.shutdown()
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Jiska Classen
|
||||
|
||||
# Get receive statistics on a Raspberry Pi 3 for BLE connection events
|
||||
|
||||
from pwn import *
|
||||
from internalblue.hcicore import HCICore
|
||||
|
||||
|
||||
internalblue = HCICore()
|
||||
device_list = internalblue.device_list()
|
||||
if len(device_list) == 0:
|
||||
log.warn("No HCI devices connected!")
|
||||
exit(-1)
|
||||
internalblue.interface = device_list[0][1] # just use the first device
|
||||
|
||||
|
||||
RX_DONE_HOOK_ADDRESS = 0x35fbc # _connTaskRxDone
|
||||
HOOKS_LOCATION = 0x210500
|
||||
ASM_HOOKS = """
|
||||
|
||||
// restore first 4 bytes of _connTaskRxDone
|
||||
push {r4-r6,lr}
|
||||
mov r4, r0
|
||||
|
||||
// fix registers for our own routine
|
||||
push {r1-r7, lr}
|
||||
mov r7, r0
|
||||
|
||||
// allocate vendor specific hci event
|
||||
mov r2, 243
|
||||
mov r1, 0xff
|
||||
mov r0, 245
|
||||
bl 0x3670 // bthci_event_AllocateEventAndFillHeader(4+239+2, 0xff, 4+239);
|
||||
mov r4, r0 // save pointer to the buffer in r4
|
||||
|
||||
// append buffer with "RXDN"
|
||||
add r0, 10 // buffer starts at 10 with data
|
||||
ldr r1, =0x4e445852 // RXDN
|
||||
str r1, [r0]
|
||||
add r0, 4 // advance buffer by 4
|
||||
|
||||
// copy 239 bytes of le_conn to buffer
|
||||
mov r2, #238
|
||||
mov r1, r7 // le_conn[0]
|
||||
bl 0x45824 // __rt_memcpy
|
||||
|
||||
// for debugging purposes, we overwrite the first byte
|
||||
// (which is the connTaskCallback anyway) with RSSI info
|
||||
mov r2, #1 // 1 rssi byte
|
||||
add.w r1, r7, #0x10a // le_conn[0x10a] is position of rssi
|
||||
mov r0, r4
|
||||
add r0, 14
|
||||
bl 0x45824 // __rt_memcpy
|
||||
|
||||
// send hci event
|
||||
mov r0, r4 // back to buffer at offset 0
|
||||
bl 0x358e // send_hci_event
|
||||
|
||||
// undo registers for our own routine
|
||||
mov r0, r7
|
||||
pop {r1-r7, lr}
|
||||
|
||||
// branch back to _connTaskRxDone + 4
|
||||
b 0x35fc0
|
||||
|
||||
"""
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# Install hooks
|
||||
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
|
||||
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
|
||||
if not internalblue.writeMem(HOOKS_LOCATION, code):
|
||||
log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
|
||||
exit(-1)
|
||||
|
||||
log.info("Installing hook patch...")
|
||||
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
|
||||
if not internalblue.patchRom(RX_DONE_HOOK_ADDRESS, patch):
|
||||
log.critical("Installing patch for _connTaskRxDone failed!")
|
||||
exit(-1)
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Jiska Classen
|
||||
|
||||
# Get receive statistics on a Raspberry Pi 3 for BLE connection events
|
||||
|
||||
from pwn import *
|
||||
from internalblue.hcicore import HCICore
|
||||
|
||||
|
||||
internalblue = HCICore()
|
||||
device_list = internalblue.device_list()
|
||||
if len(device_list) == 0:
|
||||
log.warn("No HCI devices connected!")
|
||||
exit(-1)
|
||||
internalblue.interface = device_list[0][1] # just use the first device
|
||||
|
||||
|
||||
RX_DONE_HOOK_ADDRESS = 0x56622 # _connTaskRxDone
|
||||
HOOKS_LOCATION = 0x210500
|
||||
ASM_HOOKS = """
|
||||
|
||||
// restore first 4 bytes of _connTaskRxDone
|
||||
push {r4-r6,lr}
|
||||
mov r4, r0
|
||||
|
||||
// fix registers for our own routine
|
||||
push {r1-r7, lr}
|
||||
mov r7, r0
|
||||
|
||||
// allocate vendor specific hci event
|
||||
mov r2, 243
|
||||
mov r1, 0xff
|
||||
mov r0, 245
|
||||
bl 0x2770 // bthci_event_AllocateEventAndFillHeader(4+239+2, 0xff, 4+239);
|
||||
mov r4, r0 // save pointer to the buffer in r4
|
||||
|
||||
// append buffer with "RXDN"
|
||||
add r0, 10 // buffer starts at 10 with data
|
||||
ldr r1, =0x4e445852 // RXDN
|
||||
str r1, [r0]
|
||||
add r0, 4 // advance buffer by 4
|
||||
|
||||
// copy 239 bytes of le_conn to buffer
|
||||
mov r2, #238
|
||||
mov r1, r7 // le_conn[0]
|
||||
bl 0x775C8 // __rt_memcpy
|
||||
|
||||
// for debugging purposes, we overwrite the first byte
|
||||
// (which is the connTaskCallback anyway) with RSSI info
|
||||
mov r2, #1 // 1 rssi byte
|
||||
add.w r1, r7, #0x10a // le_conn[0x10a] is position of rssi
|
||||
mov r0, r4
|
||||
add r0, 14
|
||||
bl 0x775C8 // __rt_memcpy
|
||||
|
||||
// send hci event
|
||||
mov r0, r4 // back to buffer at offset 0
|
||||
bl 0x268E // send_hci_event
|
||||
|
||||
// undo registers for our own routine
|
||||
mov r0, r7
|
||||
pop {r1-r7, lr}
|
||||
|
||||
// branch back to _connTaskRxDone + 4
|
||||
b 0x56626
|
||||
|
||||
"""
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# Install hooks
|
||||
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
|
||||
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
|
||||
if not internalblue.writeMem(HOOKS_LOCATION, code):
|
||||
log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
|
||||
exit(-1)
|
||||
|
||||
log.info("Installing hook patch...")
|
||||
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
|
||||
if not internalblue.patchRom(RX_DONE_HOOK_ADDRESS, patch):
|
||||
log.critical("Installing patch for _connTaskRxDone failed!")
|
||||
exit(-1)
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
+140
-20
@@ -33,7 +33,8 @@ import datetime
|
||||
import time
|
||||
import Queue
|
||||
import hci
|
||||
|
||||
import collections
|
||||
import struct
|
||||
|
||||
class InternalBlue:
|
||||
__metaclass__ = ABCMeta
|
||||
@@ -46,6 +47,23 @@ class InternalBlue:
|
||||
self.interface = None # holds the context.device / hci interaface which is used to connect, is set in cli
|
||||
self.fw = None # holds the firmware file
|
||||
|
||||
# RXDN statistics callback variables
|
||||
self.last_nesn_sn = None
|
||||
self.last_success_event = None
|
||||
self.last_event_ctr = 0
|
||||
self.last_channel = 0
|
||||
self.last_channel_map = 0
|
||||
self.last_event_timestamp = 0
|
||||
|
||||
# variables for measuring PDR
|
||||
self.pdr_values = {}
|
||||
for i in range(0, 37):
|
||||
self.pdr_values[i] = collections.deque([1, 1, 1, 1, 1, 1, 1, 1, 1], maxlen=10)
|
||||
|
||||
self.PDR_THRESHOLD = 0.9
|
||||
self.CHAN_COUNT_THRESHOLD = 10
|
||||
|
||||
self.pdr_logfile = open("/home/pi/pdr.log", "w")
|
||||
|
||||
self.data_directory = data_directory
|
||||
self.s_inject = None # This is the TCP socket to the HCI inject port
|
||||
@@ -119,6 +137,7 @@ class InternalBlue:
|
||||
# Register callbacks which handle specific HCI Events:
|
||||
self.registerHciCallback(self.connectionStatusCallback)
|
||||
self.registerHciCallback(self.coexStatusCallback)
|
||||
self.registerHciCallback(self.lereceiveStatusCallback)
|
||||
|
||||
def check_binutils(self, fix=True):
|
||||
"""
|
||||
@@ -314,25 +333,6 @@ class InternalBlue:
|
||||
self.tracepoint_memdump_parts = {}
|
||||
|
||||
|
||||
elif hcipkt.data[0:6] == "RAM___": # My custom header (see hook code)
|
||||
dump_address = u32(hcipkt.data[6:10])
|
||||
data = hcipkt.data[10:]
|
||||
|
||||
if self.tracepoint_memdump_address == None:
|
||||
self.tracepoint_memdump_address = dump_address
|
||||
normalized_address = dump_address - self.tracepoint_memdump_address
|
||||
self.tracepoint_memdump_parts[normalized_address] = data
|
||||
|
||||
# Check if this was the last packet
|
||||
if len(self.tracepoint_memdump_parts) == self.fw.TRACEPOINT_RAM_DUMP_PKT_COUNT:
|
||||
dump = fit(self.tracepoint_memdump_parts)
|
||||
#TODO: use this to start qemu
|
||||
filename = self.data_directory + "/" + "internalblue_tracepoint_0x%x_%s.bin" % (self.tracepoint_memdump_address, datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
|
||||
log.info("Captured Ram Dump for Tracepoint 0x%x to %s" % (self.tracepoint_memdump_address, filename))
|
||||
f = open(filename, "wb")
|
||||
f.write(dump)
|
||||
f.close()
|
||||
|
||||
|
||||
def addTracepoint(self, address):
|
||||
# Check if constants are defined in fw.py
|
||||
@@ -1422,6 +1422,126 @@ class InternalBlue:
|
||||
log.info("[Coexistence Statistics: Grant=%d Reject=%d -> Reject Ratio %.4f]" % (coex_grant, coex_reject, coex_reject/float(coex_grant)))
|
||||
return
|
||||
|
||||
def lereceiveStatusCallback(self, record):
|
||||
"""
|
||||
RXDN Callback Function
|
||||
|
||||
Depends on the raspi3_rxdn.py or eval_rxdn.py script,
|
||||
which patches the _connTaskRxDone() function and copies
|
||||
info from the LE connection struct to HCI.
|
||||
"""
|
||||
|
||||
hcipkt = record[0] # get HCI Event packet
|
||||
|
||||
if not issubclass(hcipkt.__class__, hci.HCI_Event):
|
||||
return
|
||||
|
||||
# Only do something when we have the correct firmware
|
||||
if not self.fw:
|
||||
return
|
||||
|
||||
raspi = False
|
||||
eval = False
|
||||
if self.fw.FW_NAME == "BCM43430A1":
|
||||
raspi = True
|
||||
elif self.fw.FW_NAME == "CYW27035B1":
|
||||
eval = True
|
||||
else:
|
||||
return
|
||||
|
||||
if self.fw and hcipkt.data[0:4] == "RXDN":
|
||||
data = hcipkt.data[4:]
|
||||
|
||||
# Raspi 3 gets errors
|
||||
if len(data) < 239:
|
||||
return
|
||||
|
||||
if raspi:
|
||||
packet_curr_nesn_sn = u8(data[0xa0])
|
||||
|
||||
elif eval:
|
||||
packet_curr_nesn_sn = u8(data[0xa4])
|
||||
|
||||
packet_channel_map = data[0x54:0x7b]
|
||||
packet_channel = u8(data[0x83])
|
||||
packet_event_ctr = u16(data[0x8e:0x90])
|
||||
packet_rssi = u8(data[0])
|
||||
|
||||
|
||||
# When looking at the NESN and the SN bit, we check for TX and RX errors
|
||||
# if self.last_nesn_sn and ((self.last_nesn_sn ^ packet_curr_nesn_sn) & 0b1100) !=0b1100:
|
||||
# log.info(" ^----------------------------- ERROR --------------------------------")
|
||||
|
||||
# When looking only at the NESN bit, we check for TX errors -> this is the thing we want in our EWSN paper
|
||||
if self.last_nesn_sn and ((self.last_nesn_sn ^ packet_curr_nesn_sn) & 0b0100) !=0b0100:
|
||||
pdr_current = 0
|
||||
else:
|
||||
pdr_current = 1
|
||||
|
||||
self.pdr_values[packet_channel].appendleft(pdr_current)
|
||||
pdr_avg = sum(self.pdr_values[packet_channel]) / float(len(self.pdr_values[packet_channel]))
|
||||
|
||||
# log.info("%s event: %5d, channel: %2d, channel_map: 0x%010x, PDR: %d, PDR_avg: %f" % (self.last_event_timestamp, self.last_event_ctr, self.last_channel, self.last_channel_map, pdr_current, pdr_avg))
|
||||
self.pdr_logfile.write("%s event: %5d, channel: %2d, channel_map: 0x%010x, PDR: 1\r\n" % (self.last_event_timestamp, self.last_event_ctr, self.last_channel, self.last_channel_map))
|
||||
self.pdr_logfile.flush()
|
||||
|
||||
if pdr_avg < self.PDR_THRESHOLD:
|
||||
active_channels = bin(self.last_channel_map).count('1')
|
||||
if active_channels <= self.CHAN_COUNT_THRESHOLD:
|
||||
# log.info('to few channels active -> whiteliste all')
|
||||
self.pdr_logfile.write('to few channels active -> whiteliste all')
|
||||
self.pdr_logfile.flush()
|
||||
self.sendHciCommand(0x2014, '\xff\xff\xff\xff\xf1', timeout=0)
|
||||
else:
|
||||
self.pdr_logfile.write("going to BLACKLIST channel %2d, %2d channels active" % (self.last_channel, active_channels))
|
||||
new_channel_map = self.last_channel_map & (0x1fffffffff ^ (0b1 << self.last_channel))
|
||||
self.pdr_logfile.write("current_channel_map: 0x%010x, new map: 0x%010x" % (self.last_channel_map, new_channel_map))
|
||||
self.pdr_logfile.flush()
|
||||
|
||||
new_channel_map_bytes = []
|
||||
for i in range (0, 5):
|
||||
new_channel_map_bytes.append(chr(new_channel_map >> (i * 8) & 0xff))
|
||||
|
||||
self.sendHciCommand(0x2014, ''.join(new_channel_map_bytes), timeout=0)
|
||||
|
||||
# currently only supported by eval board: check if we also went into the process payload routine,
|
||||
# which probably corresponds to a correct CRC
|
||||
# if self.last_success_event and (self.last_success_event + 1) != packet_event_ctr:
|
||||
# log.info(" ^----------------------------- MISSED -------------------------------")
|
||||
|
||||
# TODO example for setting the channel map
|
||||
# timeout needs to be zero, because we are already in an event reception routine!
|
||||
# self.sendHciCommand(0x2014, '\x00\x00\xff\x00\x00', timeout=0)
|
||||
|
||||
self.last_nesn_sn = packet_curr_nesn_sn
|
||||
|
||||
# draw channel with rssi color
|
||||
color = '\033[92m' # green
|
||||
if 0xc8 > packet_rssi >= 0xc0:
|
||||
color = '\033[93m' # yellow
|
||||
elif packet_rssi < 0xc0:
|
||||
color = '\033[91m' # red
|
||||
|
||||
channels_total = u8(packet_channel_map[37])
|
||||
channel_map = 0x0000000000
|
||||
if channels_total <=37: # raspi 3 messes up with this during blacklisting
|
||||
for channel in range(0, channels_total):
|
||||
# channel_map |= (0b1 << 39) >> u8(packet_channel_map[channel]) # Use the flipped representation of the channel map to be consistent in my code
|
||||
channel_map |= (0b1 << u8(packet_channel_map[channel]))
|
||||
|
||||
# log.debug("LE event %5d, map %10x, RSSI %d: %s%s*\033[0m " % (packet_event_ctr, channel_map,
|
||||
# (packet_rssi & 0x7f) - (128*(packet_rssi >>7)), color, ' '*packet_channel))
|
||||
|
||||
# Store the following information for the next connection event, because we will know only by then, if the event was successful
|
||||
self.last_event_ctr = packet_event_ctr
|
||||
self.last_channel = packet_channel
|
||||
self.last_channel_map = channel_map
|
||||
self.last_event_timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||
|
||||
if self.fw and hcipkt.data[0:4] == "LEPR":
|
||||
data = hcipkt.data[4:]
|
||||
self.last_success_event = u16(data[0x8e:0x90])
|
||||
|
||||
def readHeapInformation(self):
|
||||
"""
|
||||
Traverses the double-linked list of BLOC structs and returns them as a
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# fw_0x6119.py
|
||||
#
|
||||
# All firmware specific data such as address offsets are collected
|
||||
# in the fw.py file. Later versions of the framework will provide
|
||||
# multiple copies of this file in order to target different firmware
|
||||
# and chip versions.
|
||||
#
|
||||
# Copyright (c) 2019 Jiska Classen. (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.
|
||||
|
||||
# Firmware Infos
|
||||
# This runs on Rasperry Pi 3
|
||||
FW_NAME = "BCM43430A1"
|
||||
|
||||
# Device Infos
|
||||
DEVICE_NAME = 0x20401C
|
||||
BD_ADDR = 0x201C64
|
||||
|
||||
# Memory Sections
|
||||
class MemorySection:
|
||||
def __init__(self, start_addr, end_addr, is_rom, is_ram):
|
||||
self.start_addr = start_addr
|
||||
self.end_addr = end_addr
|
||||
self.is_rom = is_rom
|
||||
self.is_ram = is_ram
|
||||
|
||||
def size(self):
|
||||
return self.end_addr - self.start_addr
|
||||
|
||||
# Memory Sections
|
||||
# start, end, is_rom? is_ram?
|
||||
SECTIONS = [ MemorySection(0x0, 0x90000, True , False),
|
||||
MemorySection(0xd0000, 0xd8000, False, True ),
|
||||
#MemorySection(0xe0000, 0x1f0000, True , False),
|
||||
MemorySection(0x200000, 0x228000, False, True ),
|
||||
MemorySection(0x260000, 0x268000, True , False),
|
||||
#MemorySection(0x280000, 0x2a0000, True , False),
|
||||
MemorySection(0x318000, 0x320000, False, False),
|
||||
MemorySection(0x324000, 0x360000, False, False),
|
||||
MemorySection(0x362000, 0x362100, False, False),
|
||||
MemorySection(0x363000, 0x363100, False, False),
|
||||
MemorySection(0x600000, 0x600800, False, False),
|
||||
MemorySection(0x640000, 0x640800, False, False),
|
||||
MemorySection(0x650000, 0x650800, False, False),
|
||||
#MemorySection(0x680000, 0x800000, False, False)
|
||||
]
|
||||
|
||||
# Connection Structure and Table
|
||||
#CONNECTION_ARRAY_ADDRESS = 0x204ba8
|
||||
#CONNECTION_MAX = 11
|
||||
#CONNECTION_STRUCT_LENGTH = 0x150
|
||||
|
||||
# Patchram
|
||||
PATCHRAM_ENABLED_BITMAP_ADDRESS = 0x310204
|
||||
PATCHRAM_TARGET_TABLE_ADDRESS = 0x310000
|
||||
PATCHRAM_VALUE_TABLE_ADDRESS = 0xd0000
|
||||
PATCHRAM_NUMBER_OF_SLOTS = 128
|
||||
PATCHRAM_ALIGNED = False
|
||||
@@ -149,8 +149,8 @@ FUZZLMP_ASM_CODE = """
|
||||
|
||||
# Assembler snippet for tracepoints
|
||||
# In contrast to the Nexus 5 patch, we uninstall ourselves automatically and use internal debug functions
|
||||
TRACEPOINT_BODY_ASM_LOCATION = 0x00218500
|
||||
TRACEPOINT_HOOKS_LOCATION = 0x00218700
|
||||
TRACEPOINT_BODY_ASM_LOCATION = 0x00218950
|
||||
TRACEPOINT_HOOKS_LOCATION = 0x00218900
|
||||
TRACEPOINT_HOOK_SIZE = 40
|
||||
TRACEPOINT_HOOK_ASM = """
|
||||
push {r0-r12, lr} // save all registers on the stack (except sp and pc)
|
||||
|
||||
@@ -194,7 +194,7 @@ class HCICore(InternalBlue):
|
||||
record = (hci.parse_hci_packet(record_data), btsnoop_orig_len, btsnoop_inc_len,
|
||||
btsnoop_flags, btsnoop_drops, btsnoop_time)
|
||||
|
||||
log.debug("_recvThreadFunc Recv: [" + str(btsnoop_time) + "] " + str(record[0]))
|
||||
#log.debug("_recvThreadFunc Recv: [" + str(btsnoop_time) + "] " + str(record[0]))
|
||||
|
||||
# Write to btsnoop file:
|
||||
if self.write_btsnooplog:
|
||||
|
||||
Reference in New Issue
Block a user