13 Commits

Author SHA1 Message Date
Michael ec9240e620 First implementation of PDR-based blacklisting 2019-08-14 09:23:04 +01:00
Michael e2fb710f51 Merge branch 'blacklisting' of https://dev.seemoo.tu-darmstadt.de/bcm/internalblue into blacklisting 2019-08-13 18:19:59 +01:00
Michael c84a0cd123 Add file logging for measuring baseline PDR 2019-08-13 18:14:21 +01:00
Jiska Classen 31f6a8d58a rpi3+ blacklisting (todo: test) 2019-07-17 21:55:44 +02:00
Jiska Classen 7bc7a956ea logical color error 2019-07-12 15:20:17 +02:00
Jiska Classen cf51abc428 red/green fix 2019-07-12 15:15:09 +02:00
Michael 1bf8c0c132 checks for channel map blacklisting / length in rpi3 2019-07-12 13:28:52 +01:00
Jiska Classen 2d3ed7f734 raspi len check 2019-07-12 13:58:54 +02:00
Jiska Classen ac1df0b260 some colorful drawings for the blacklisting 2019-07-12 13:40:51 +02:00
Jiska Classen 053ad32297 documentation on how blacklisting debugging works 2019-07-10 17:51:40 +02:00
Jiska 8cb4109e81 raspi3 output: rssi, event counter, transmission fails, current channel. channel map via btmon. 2019-07-10 16:40:24 +01:00
Jiska Classen 8e0f099a83 rpi3 fw 2019-07-10 16:41:47 +02:00
Jiska Classen c842e4ec7d basic blacklisting debug output 2019-07-10 15:35:26 +02:00
9 changed files with 460 additions and 25 deletions
+5
View File
@@ -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
View File
@@ -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.
+47
View File
@@ -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'.")
+90
View File
@@ -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'.")
+90
View File
@@ -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
View File
@@ -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
+75
View File
@@ -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
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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: