Nexmon: A Cookbook For Firmware Modifications On Smartphones To Enable Monitor Mode
Nexmon: A Cookbook For Firmware Modifications On Smartphones To Enable Monitor Mode
Nexmon: A Cookbook For Firmware Modifications On Smartphones To Enable Monitor Mode
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.
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.