Nexmon: A Cookbook For Firmware Modifications On Smartphones To Enable Monitor Mode

Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

NexMon: A Cookbook for Firmware Modifications

on Smartphones to Enable Monitor Mode

Matthias Schulz, Daniel Wegemer and Matthias Hollick


Secure Mobile Networking Lab, TU Darmstadt, Germany
Email:{mschulz, dwegemer, mhollick}@seemoo.tu-darmstadt.de

Abstract—Full control over a Wi-Fi chip for research purposes


is often limited by its firmware, which makes it hard to evolve dhdutil BCMDHD cfg80211 driver
arXiv:1601.07077v1 [cs.OH] 24 Dec 2015

communication protocols and test schemes in practical environ-


ments. Monitor mode, which allows eavesdropping on all frames
on a wireless communication channel, is a first step to lower Android MMC driver to interface SDIO
this barrier. Use cases include, but are not limited to, network user space Android kernel space
packet analyses, security research and testing of new medium
access control layer protocols. Monitor mode is generally offered BCM4339 Wi-Fi system on chip
by SoftMAC drivers that implement the media access control 802.11ac D11 SDIO ROM ARM Cortex R4
sublayer management entity (MLME) in the driver rather than PHY core core RAM microcontroller
in the Wi-Fi chip. On smartphones, however, mostly FullMAC
chips are used to reduce power consumption, as MLME tasks do
not need to wake up the main processor. Even though, monitor Backplane Bus
mode is also possible in FullMAC scenarios, it is generally not im-
plemented in today’s Wi-Fi firmwares used in smartphones. This
Fig. 1. The BCM4339 system on chip is interfaced by the BCMDHD driver
work focuses on bringing monitor mode to Nexus 5 smartphones
through SDIO. The driver itself can be controlled using the dhdutil.
to enhance the interoperability between applications that require
monitor mode and BCM4339 Wi-Fi chips. The implementation
is based on our new C-based programming framework to extend
existing Wi-Fi firmwares. • Reverse engineering of the BCM4339 chip and its
firmware.
• Design and implementation of a C-based firmware
I. I NTRODUCTION
extension framework, usable on firmwares for ARM
The use cases for open Wi-Fi firmwares or simply some processors.
firmware extensions like monitor mode on a smartphone • Firmware modification to support monitor mode on
are numerous. Besides security research, it also includes the BCM4339 chips.
implementation and testing of new medium access control
(MAC) layer protocols. Currently, either SoftMAC drivers This work is structured as follows, in Section II, we
are required, that give access to the media access control describe the reverse engineering process. In Section III, we
sublayer management entity (MLME) or solutions such as describe our C-based framework for firmware modifications.
the Wireless MAC processor [5] that even allow to modify In Section IV, we describe how frame reception is handled
the real time behaviour of a Wi-Fi chip. More flexibility in the chip. In Section V, we document our monitor mode
is given by connecting software-defined radios (SDRs) to a implementation. In Section VI, we explain how you use our
smartphones to even give access to the 802.11 physical layer. project on your phone. In Section VII, we list bugs and future
Schulz et al. use this setup in [3] to enhance wireless video work and conclude with Section VIII. The source code of our
transmissions by assigning physical modulation schemes to implementation can be downloaded from [4].
different quality layers in a scalable video coding (SVC)
scenario. Nevertheless, SDR-based solutions are unlikely to II. R EVERSE E NGINEERING
be seen in mobile consumer devices in the near future, as Before extending the existing Wi-Fi firmware, we had to
the energy consumption of field-programmable gate arrays analyze how the original firmware works internally and how
(FPGAs) used in SDRs is much higher than an energy-efficient the system on chip in the Wi-Fi chip looks like. We performed
single purpose implementation. the analysis analogous to [1] and [2]. In Figure 1, we illustrate
Hence, in this work, we focus on extending the firmware of the parts of the system on chip relevant for this work. Our
Wi-Fi chips used in widely available consumer devices. Similar analysis is based on firmware version 6.37.32.RC23.34.40
work to introduce monitor mode or even frame injection has (r581243) being delivered with Android 6.0 build MRA58K
already been done for older chip generations in the bcmon and Android 6.0.1 build MMB29K for Nexus 5 smartphones.
[2] (BCM4329 and BCM4330), as well as the monmob [1]
A. Explaining the system on chip
(BCM4325 and BCM4329) projects. In this work, we focus on
BCM4339 chips used, for example, in the Nexus 5 smartphone. On the Android side, the main component is the BCMDHD
The contributions of our work are as follows: FullMAC driver that interfaces the BCM4339 system on chip
through the secure digital input output (SDIO) interface. In As illustrated in Figure 1 and described in [2] and [1],
general, it exchanges Ethernet frames with the Wi-Fi chip, the firmware consists of a part that resides in ROM (size:
and the ARM microcontroller in the BCM4339 handles the 640 KB, starting at 0x0) and another one that is loaded by
re-framing into Wi-Fi frames as well as the management of the BCMDHD driver into RAM (size: 768 KB, starting at
access point or device-to-device connections. The real-time 0x180000). The firmware file for the RAM is found as a binary
parts, like transmitting acknowledgement frames after a fixed file on the smartphone. The firmware that resides in ROM can
delay, are handled by the D11 core, that interfaces the 802.11ac simply be extracted using the dhdutil9 that is distributed as
physical layer. Data between the different cores is exchanged part of the Android platform and allows to send specific ioctls
over the backplane bus. One can either write into registers to the BCMDHD driver in case the driver was compiled with
or shared memory areas of the connected cores or use direct active DHD DEBUG flag. Using the membytes command, one
memory access (DMA) controllers to exchange chunks of data can read at arbitrary memory locations in ROM and RAM and
without involving the microcontroller. The SDIO core has a dump the output to a binary file.
DMA controller that is generally configured to exchange SDIO
To analyse the extracted firmware, we load it into the
frames between RAM and the SDIO controller. Whenever a
Interactive Disassembler (IDA) and use Hex-Rays Decompiler
new frame is copied to RAM, the DMA controller triggers the
for ARM to be able to convert assembler code into more
external interrupt at the microcontroller, which then handles
readable C-like code which we can compare to the brcmsmac’s
the received frame. The microcontroller can also trigger the
source code to find similarities. To identify functions, we first
SDIO DMA to copy SDIO frames from RAM to the SDIO
go through the list of detected strings and can identify function
core for transmission to the BCMDHD driver. The D11 core
names from the brcmsmac driver. Cross referencing code that
operates similarly: it has four first in first out (FIFO) queues
uses these strings leads to constructions that look like printf
that can be accessed by DMA controllers to exchange Wi-Fi
function calls resulting in an output in the console that can be
frames. One FIFO is used for received and transmitted frames
read using dhdutil’s consoledump command. The printf calls
and three additional FIFOs are used for the transmission of
look as follows:
frames at different quality levels (RX data and background
data packets1 , best-effort data packets2 , video data packets3 printf("%s: some error...", __FUNCTION__);
and voice data and transmit-status packets4 ). First the name of the surrounding function is printed then an
error message. Analysing all function name strings, we are
B. The D11 core able to name many functions. To name even more functions,
we look for functions in the brcmsmac source code that call
The D11 core consists of a programmable state machine already named functions or that are called by already named
(PSM) that is optimized for real-time processing and can functions. To better understand the code, it is very helpful
quickly change its program flow after checking conditions in to classify variable types and create structs in IDA. This
registers. This core is the first stage to decide, which frames made us discover the wlc->pub->_cnt struct that contains
should be received or dropped. To allow monitor mode, the counters for various statistics, which help up to classify the
maccontrol5 register needs to be set to activate promiscuous surrounding code. Before continuing to describe how we found
mode6 . The activation can be performed by the microcontroller the path from an interrupt triggering a new frame reception and
by calling the wlc bmac mctrl7 function. How, we identified the transmission to the BCMDHD driver, we introduce our
such a function in the existing firmware is described in the framework that allows to write firmware patches in C instead
following. of Assembler.

III. C- BASED F IRMWARE M ODIFICATION F RAMEWORK


C. The microcontroller firmware analysis
After creating the first patches for the firmware to output
The microcontroller is used to act as an interface between debug information and to get a first monitor mode prototype
the different cores in the system on chip and the BCMDHD running in Assembler, we decided that programming in C is
driver in the Linux kernel. It implements a SoftMAC driver less error prone, hence, we developed a C-based programming
similar to brcmsmac which is part of Broadcom’s brcm802118 framework. We intended to generate functions that can replace
driver. Our code references in the footnotes, hence, often refer already existing functions in the firmware or that can be
to this driver source code. Besides the SoftMAC implementa- called before calling an existing function by redirecting branch
tion, the microcontroller’s firmware also performs re-framing, instructions to our own functions. Additionally, we wanted to
as well as additional tasks to unburden the main smartphone directly call existing functions in the firmware.
processor and enhance energy efficiency. To implement mon-
itor mode, we intend to bypass these additional features, but In our implementation, we define external function proto-
first we need to start analysing the firmware itself. types of firmware functions we like to call and use a linker
to insert correct branch instructions and place global variables
1 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 545 in memory. Unfortunately, the simple definition of symbols
2 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 560 with addresses of functions in memory leads to the creation of
3 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 574 trampoline stubs to switch from Thumb to ARM instruction
4 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 585
set, even though the existing firmware code needs to be
5 brcmsmac source file: d11.h, kernel version: 2.6.39, line: 134
executed in Thumb mode. To work around this problem, we
6 brcmsmac source file: d11.h, kernel version: 2.6.39, line: 466
7 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 1483 9 https://android.googlesource.com/platform/hardware/broadcom/wlan/+/
8 http://lxr.free-electrons.com/source/drivers/staging/brcm80211/?v=2.6.39 master/bcmdhd/dhdutil/

2
created an object file with dummy functions for all firmware Listing 1. Hello world program hooking to the dma rx function.
functions, we wanted to call. Each of those functions is placed
in a separate section and—using the linker—can be placed at #include "wrapper.h"
the appropriate position where the code resides in the firmware.
struct sk_buff *dma_rx_hook(struct dma_info *di) {
Using this approach, the generated machine code is posi- printf("hello world");
tion dependent and uses branch with link instructions relative return dma_rx(di);
}
to the current program counter. This allows small binaries
and calls to functions like printf, which can take an arbitrary
number of parameters. It consists of three parts. At the beginning it calls the dma rx13
The hello world program in Listing 1 serves as an example. function in a loop to collect pointers to the received frames
It is implemented as a hook to the dma rx10 function and prints in a list of linked sk buffs. Then it calls dma rxfill14 to
“hello world” to the console, which can be read using dhdutil’s allocate new receive buffers and post them to the DMA ring
consoledump command. The resulting assembler code after buffer so that they can be filled with new frames. In the
disassembling in IDA is illustrated in Listing 2. Using our last part, wlc bmac recv handles the frames stored in the
framework, we can rewrite any firmware function we like, previously created linked list. The main frame processing starts
which we do to activate monitor more. Before that, we first in the wlc recv15 function at 0x19afe8. The processing result
need to understand which functions are called when receiving is a call to dngl sendpkt (named according to the bcmon
a frame. project presentation) following for example the path 0x19955f
⇒ 0x198cdd ⇒ 0x1981f5 ⇒ 0x1893b5 ⇒ 0x183771 ⇒
0x182C84 ⇒ 0x182750. This function takes an sk buff and
IV. F RAME RECEPTION
an SDIO channel number, prepends the buffer’s data payload
In this section, we describe how a Wi-Fi frame reception with an SDIO frame header and passes the buffer on to a
is handled by the microcontroller. As mentioned above, the dma txfast16 call (0x18256c ⇒ 0x182450 ⇒ 0x1844b2) that
DMA controller of the D11 core transfers received frames uses the SDIO’s DMA to transfer the frame to the BCMDHD
into RAM and then triggers the external interrupt of the driver. How this processing pass can be bended to bypass
microcontroller. The microcontroller handles this interrupt by the frame processing and directly pass raw frames to the
settings its program counter to execute the fast interrupt (FIQ) BCMDHD driver is explained in the next section.
instruction in the exception vector that is located at address
0x0 in the ROM. In the BCM4339 ROM this instruction is a V. M ONITOR M ODE
branch to an exception handler located in RAM at 0x180fee,
which branches to a common exception handler at 0x181032, Our approach to enable monitor mode is twofold. First,
which calls the callback function referenced at 0x181100, we replace the wlc bmac recv function to bypass frame pro-
which points to 0x181e48. In case of a fast interrupt it calls the cessing and directly forward the received raw frames to the
function at 0x181a88, which calls each function of a linked list BCMDHD driver. Second, we correctly set the maccontrol
of functions. The reference to the list is placed at 0x180e5c. register during the initialization of the interface to work in
The first function pointer in this list is a path to wlc dpc11 promiscuous mode.
(0x27550 ⇒ 0x2733c ⇒ 0x61eb4), which checks if new frame
receptions from the D11 core need to be handled using the A. Rewriting the wlc bmac recv function
wlc bmac recv12 function (0x1aad98), which is called through
its wrapper at 0x4f7a4. Our rewritten wlc bmac recv function from Listing 2 can
be compiled with our C-based framework to get a replacement
The wlc bmac recv function is mentioned in the bcmon for the existing wlc bmac recv function in the firmware.
project as a good starting point to implement monitor mode.
13 util source file: hnddma.c, kernel version: 2.6.39, line: 732
10 utilsource file: hnddma.c, kernel version: 2.6.39, line: 732 14 util source file: hnddma.c, kernel version: 2.6.39, line: 809
11 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 313 15 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 6993
12 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 257 16 util source file: hnddma.c, kernel version: 2.6.39, line: 1426

Listing 2. Disassembly of the dma rx hooking hello world program. The binary was created using our C-based programming framework.

ROM:00180000 PUSH {R4,LR}


ROM:00180002 MOVS R4, R0
ROM:00180004 LDR R0, =aHelloWorld ; "hello world"
ROM:00180006 BL 0x126F0 ; printf
ROM:0018000A MOVS R0, R4
ROM:0018000C BL 0x8C69C ; dma_rx
ROM:00180010 POP {R4,PC}
ROM:00180010 ; ---------------------------------------------------------------------------
ROM:00180012 ALIGN 4
ROM:00180014 off_180014 DCD aHelloWorld ; DATA XREF: ROM:00180004r
ROM:00180014 ; "hello world"
ROM:00180018 aHelloWorld DCB "hello world",0 ; DATA XREF: ROM:00180004o
ROM:00180018 ; ROM:off_180014o

3
Compared to the wlc bmac recv function of the brcmsmac Listing 2. Rewritten wlc bmac recv function to directly send raw Wi-Fi
source code, our function has an additional parameter cnt that frames to the BCMDHD driver.
saves the number of loop iterations with calls to dma rx.
#include "bcm4339.h"
Instead of first calling dma rx in a loop to build a linked list #include "wrapper.h"
of sk buffs, we decided to fetch frames from the D11 DMA
and directly transmit them over the SDIO interface using the int wlc_bmac_recv(struct wlc_hw_info *wlc_hw,
dngl sendpkt function. The constant SDIO INFO ADDR is unsigned int fifo, int bound, int *cnt) {
void *p;
the address of a struct that holds information on the SDIO core. int n = 0;
To avoid stalling the interrupt handling for too long, if many int bound_limit = wlc_hw->wlc->pub->tunables->
Wi-Fi frames are received, we limit the number of processed rxbnd;
frames to bound limit and return whether we stayed below
that limit. do {
if((p = dma_rx(wlc_hw->di[fifo]))) {
dngl_sendpkt(SDIO_INFO_ADDR, p, 0xF);
B. Setting the correct maccontrol registers }
n++;
As mentioned above, the maccontrol registers in the D11 } while(n < bound_limit);
core need to be set appropriately to receive all frames. The *cnt += n;
monmob developers already identified the wlc bmac mctrl17
(0x4f080) function to perform this task. To activate the recep- dma_rxfill(wlc_hw->di[fifo]);
tion of all frames at the initialization of the wireless interface, wlc_bmac_mctrl(wlc_hw, (MCTL_PROMISC |
we set the registers in the wlc coreinit18 (0x1ab66c) function, MCTL_KEEPCONTROL | MCTL_BCNS_PROMISC |
which calls wlc bmac mctrl with the parameters mask at MCTL_KEEPBADFCS), (MCTL_PROMISC |
0x1ab82c and value at 0x1ab828. We extend mask and value MCTL_KEEPCONTROL | MCTL_BCNS_PROMISC |
MCTL_KEEPBADFCS));
with the appropriate bits that are also set by bcmon. Somehow,
the original firmware resets those bits during operation, hence, if(n < bound_limit) {
we set them again during each execution of the wlc bmac recv return 0;
function (see Listing 2). } else {
return 1;
}
VI. T RY IT YOURSELF }
To let you try our monitor mode implementation on your
Nexus 5 smartphone, we provide a boot.img that contains a
custom kernel based on the android-msm-hammerhead-3.4-
marshmallow-mr119 branch with modules enabled and the
BCMDHD driver compiled as a module. Our driver modifi-
cation is based on the bcmon project. The module is located
in /nexmon/bcmdhd.ko and can be loaded with insmod and
unloaded with rmmod. It is not automatically loaded during
startup. Additionally, we disabled the wpa supplicant and
p2p supplicant services in the init.hammerhead.rc file, hence,
regular Wi-Fi does not work with our provied boot image.
The monitor interface is broad up by executing ifconfig
wlan0 up. The received frames contain a radiotap header that
can be processed by programs that rely on monitor mode
enabled interfaces. To test the monitor capabilities and change
channels, we included pre-compiled binaries of iwconfig and Fig. 2. Running airodump-ng on the Nexus 5 in monitor mode.
tcpdump under /nexmon/bin/. The result of running another
tool called airodump-ng on the phone is shown in Figure 2.
Be advised that using our boot.img may damage your repository. If you intend to modify the firmware on your own,
phone and may void your phone’s warranty! You use our you can compile everything from source using the Makefile in
tools at your own risk and responsibility! To run the boot.img our git repository [4].
on your own Nexus 5, you should have Android 6.0.1 build
MMB29K installed and an unlocked bootloader. Be aware
that unlocking the bootloader generally wipes your phone! To
play with monitor mode we advise you to boot our image VII. K NOWN B UGS AND F UTURE W ORK
instead of flashing it, as it disables regular Wi-Fi capabilities. Currently not all received frames contain valid Wi-Fi
Simply execute adb reboot bootloader && fastboot boot frames and the radiotap headers are set to default values.
boot.img or run make boot, in case you cloned our git Additionally, the Wi-Fi firmware crashes under unknown cir-
17 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 1483
cumstances, which requires a chip reset by running ifconfig
18 brcmsmac source file: wlc bmac.c, kernel version: 2.6.39, line: 2300 wlan0 down && ifconfig wlan0 up. In future releases we
19 https://android.googlesource.com/kernel/msm/+/android-msm- intend to fix those bugs and implement frame injection to be
hammerhead-3.4-marshmallow-mr1 able to transmit arbitrary Wi-Fi frames.

4
VIII. C ONCLUSION
This work describes how to analyse and successfully extend
Wi-Fi firmwares to enable monitor mode on a BCM4339
FullMAC Wi-Fi chip. To simplify firmware modifications, we
present a C-based firmware extension framework and use it
in our implementation. The functionality of our approach is
demonstrated by running airodump-ng on a Nexus 5 smart-
phone.

ACKNOWLEDGMENT
This work has been funded by the German Research
Foundation (DFG) in the Collaborative Research Center (SFB)
1053 “MAKI – Multi-Mechanism-Adaptation for the Future
Internet” and by LOEWE CASED, which provided the IDA
Pro and HexRays Decompiler licenses. Many thanks go to
Andrés Blanco who supported us in our reverse engineering
phase.

R EFERENCES
[1] A. Blanco and M. Eissler. (2012) One firmware to monitor ’em
all. [Online]. Available: http://www.coresecurity.com/corelabs-research/
publications/one-firmware-monitor-em-all-hacklu2012
[2] O. Ildis, Y. Ofir, and R. Feinstein. (2013) Wardriving from your pocket
– Using wireshark to reverse engineer broadcom wifi chipsets. [Online].
Available: http://bcmon.blogspot.de/
[3] M. Schulz, D. Stohr, S. Wilk, B. Rudolph, W. Effelsberg, and M. Hollick,
“APP and PHY in harmony: A framework enabling flexible physical
layer processing to address application requirements,” in International
Conference on Networked Systems, NetSys 2015, 2015.
[4] M. Schulz, D. Wegemer, and M. Hollick. (2015) NexMon project:
The Wi-Fi firmware modification framework. [Online]. Available:
https://seemoo.tu-darmstadt.de/nexmon
[5] I. Tinnirello, G. Bianchi, P. Gallo, D. Garlisi, F. Giuliano, and F. Gringoli,
“Wireless MAC processors: Programming MAC protocols on commodity
hardware,” in Proc. of the 31st Annual IEEE International Conference
on Computer Communications (INFOCOM), 2012.

You might also like