README.md

What is nexmon?

Nexmon is our C-based firmware patching framework for Broadcom/Cypress WiFi chips
that enables you to write your own firmware patches, for example, to enable monitor
mode with radiotap headers and frame injection.

Before we started to work on this repository, we developed patches for the Nexus 5 (with bcm4339 WiFi chip) in the bcm-public repository and those for the Raspberry Pi 3 (with bcm43430a1 WiFi chip) in the bcm-rpi3 repository. To remove the development overhead of maintaining multiple separate repositories, we decided to merge them in this repository and add support for some additional devices. In contrast to the former repositories, here, you can only build the firmware patch without drivers and kernels. The Raspberry Pi 3 makes an exception, as here it is always required to also build the driver.

Give Feedback

We setup a survey to learn about who uses Nexmon to which purpose and how we could improve Nexmon. We would be happy if every Nexmon user filled out this survey: https://nexmon.org/survey

WARNING

Our software may damage your hardware and may void your hardware’s warranty! You use our tools at your own risk and responsibility! If you don't like these terms, don't use nexmon!

Important changes

We started to collect usage statistics. In the file STATISTICS.md, you can find information on which data we collect and how you can opt-out of the statistics collection

Starting with commit 4f8697743dc46ffc37d87d960825367531baeef9 the brcmfmac driver for the RPi3 can now be used as a regular interface. You need to use nexutil to activate monitor mode (nexutil -m2 for monitor mode with radiotap headers), which will automtically adjust the interface type.

Starting with commit 184480edd6696392aae5f818f305f244606f2d17 you can choose different monitor mode options using nexutil. Use nexutil -m1 to activate monitor mode without radiotap headers, nexutil -m2 to activate it with radiotap headers. The numbers were chosen as non-Nexmon firmwares also support native monitor mode without radiotap headers by activating monitor mode with nexutil -m1.

Starting with commit 1bcfdc95b4395c2e8bdd962791ae20c4ba602f5b we changed the nexutil interface. Instead of calling nexutil -m true to activate monitor mode, you should now write nexutil -m1. To get the current monitor mode state execute nexutil -m instead of nexutil -n.

Supported Devices

The following devices are currently supported by our nexmon firmware patch.

WiFi Chip

Firmware Version

Used in

Operating System

M

RT

I

FP

UC

CT

bcm4330

5_90_100_41_sta

Samsung Galaxy S2

Cyanogenmod 13.0

X

X

X

X

O

bcm4335b0

6.30.171.1_sta

Samsung Galaxy S4

LineageOS 14.1

X

X

X

X

O

bcm4339

6_37_34_43

Nexus 5

Android 6 Stock

X

X

X

X

X

O

bcm43430a11

7_45_41_26

Raspberry Pi 3 and Zero W

Raspbian 8

X

X

X

X

X

O

bcm43430a11

7_45_41_46

Raspberry Pi 3 and Zero W

Raspbian Stretch

X

X

X

X

X

O

bcm43451b1

7_63_43_0

iPhone 6

iOS 10.1.1 (14B100)

X

X

bcm43455

7_45_77_0_hw

Huawei P9

Android 7 Stock

X

X

X

X

X

bcm43455

7_120_5_1_sta_C0

Galaxy J7 2017

?

X

X

bcm43455

7_45_77_0_hw(8-2017)

Huawei P9

Android 7 Stock

X

X

X

X

X

bcm43455c0

7_45_154

Raspberry Pi B3+

Raspbian Kernel 4.9/4.14

X

X

X

X

bcm4356

7_35_101_5_sta

Nexus 6

Android 7.1.2

X

X

X

X

O

bcm4358

7_112_200_17_sta

Nexus 6P

Android 7 Stock

X

X

X

X

O

bcm4358

7_112_201_3_sta

Nexus 6P

Android 7.1.2 Stock

X

X

X

X

O

bcm43582

7_112_300_14_sta

Nexus 6P

Android 8.0.0 Stock

X

X

X

X

X

O

bcm43596a03

9_75_155_45_sta_c0

Samsung Galaxy S7

Android 7 Stock

X

O

X

bcm43596a03,2

9_96_4_sta_c0

Samsung Galaxy S7

LineageOS 14.1

X

X

X

O

X

qca95004

4-1-0_55

TP-Link Talon AD7200

Custom LEDE Image

1 bcm43430a1 was wrongly labeled bcm43438 in the past.

2 use LD_PRELOAD=libnexmon.so instead of LD_PRELOAD=libfakeioctl.so to inject frames through ioctls

3 flash patches need to be 8 bytes long and aligned on an 8 byte boundary

Using the Monitor Mode patch

Install at least nexutil and libfakeioctl from our utilities. The easiest way to do this is by using this app: https://nexmon.org/app. But you can also build it from the source by executing make in the utilties folder (Note: you will need the Android NDK properly installed for this).

Connect to your Android phone using the ADB tools: adb shell

Make sure you are not connected to an access point

Use nexutil to enable monitor mode: nexutil -m2

At this point the monitor mode is active. There is no need to call airmon-ng.

Important: Most tools need a Radiotap interface to work properly. libfakeioctl emulates this type of interface for you, therefore, use LD_PRELOAD to load this library when you call the favourite tool (e.g. tcpdump or airodump-ng): LD_PRELOAD=libfakeioctl.so tcpdump -i wlan0

Using nexutil over UDP on Nexus 5

To be able to communicate with the firmware without root priviledges, we created a UDP interface accessible through the libnexio, which is also used by nexutil. You first have to prove to the firmware that you generally have root priviledges by setting a securtiy cookie. Then you can use it for UDP based connections. Your wlan0 interface also needs an IP address in the 192.168.222.0/24 range or you have to change the default nexutil broadcast-ip:

Set the IP address of the wlan0 interface: ifconfig wlan0 192.168.222.1 netmask 255.255.255.0

The new driver should be loaded by default after reboot: reboot
* Note: It is possible to connect to an access point or run your own access point in parallel to the monitor mode interface on the wlan0 interface.

How to build the utilities

To build the utilities such as nexmon or dhdutil for Android, you need to download the old NDK version 11c,
extract it and export the environment variable NDK_ROOT pointing to the directory where you extracted the NDK
files.

How to extract the ROM

The Wi-Fi firmware consists of a read-only part stored in the ROM of every Wi-Fi chip and another part that is
loaded by the driver into the RAM. To analyze the whole firmware, one needs to extract the ROM. There are two
options to do this. Either you write a firmware patch that simply copies the contents of the ROM to RAM and then
you dump the RAM, or you directly dump the ROM after loading the regular firmware into the RAM. Even though,
the second option is easier, it only works, if the ROM can be directly accessed by the driver, which is not always
the case. Additionally, the firmware loaded into RAM can contain ROM patches that overlay the data stored in ROM.
By dumping the ROM after loading the original RAM firmware, it contains flash patches. Hence, the ROM needs to be
dumped again for every RAM firmware update to be consistent. As a conclusion, we prefer to dump the clean ROM after
copying it to RAM.

Dumping the ROM directly

To dump the ROM directly, you need to know, where to find it and how large it is. On chips with Cortex-M3 it is
usually at upper addresses such as 0x800000, while on chips with Cortex-R4 it is likely at 0x0. Run dhdutil to
perform the dump:

dhdutil membytes -r 0x0 0xA0000 > rom.bin

Dumping a clean ROM after copying to RAM

For the BCM4339 and BCM4358, we created rom_extraction projects that load a firmware patch that copies ROM to
RAM and them dumps it using dhdutil. To dump the ROM simply execute the following in the project directory:

make dump-rom

After ROM extraction, the rom.bin file will be copies to the corresponding firmwares subdirectory. To apply the
flash patches of a specific RAM firmware version, enter its directory and execute:

make rom.bin

Structure of this repository

buildtools: Contains compilers and other tools to build the firmware

firmwares

<chip version>

<firmware version>

<firmware file>: The original firmware that will be loaded into the RAM of the WiFi Chip

definitions.mk: Contains mainly firmware specific addresses

structs.h: Structures only valid for this firmware version

Makefile: Used to extract flashpatches and ucode

flashpatches.c (generated by Makefile): Contains flashpatches

ucode.bin (extracted by Makefile): Contains uncompressed Ucode

structs.common.h: Structures that are common between firmware versions

Reference our project

Any use of this project which results in an academic publication or other publication which includes a bibliography should include a citation to the Nexmon project and probably one of our papers depending on the code you use. Find all references in our bibtex file. Here is the reference for the project only: