The C-based Firmware Patching Framework for Broadcom/Cypress WiFi Chips that enables Monitor Mode, Frame Injection and much more
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.
Below, you find an overview what is possible with nexmon. This repository mainly focuses on enabling monitor mode and frame injection on many chips. If you want additional features, the following projects might be interesting for you:
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!
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 | 59010041sta | Samsung Galaxy S2 | Cyanogenmod 13.0 | X | X | X | X | O | |
bcm4335b0 | 6.30.171.1sta | Samsung Galaxy S4 | LineageOS 14.1 | X | X | X | X | O | |
bcm4339 | 6373443 | Nexus 5 | Android 6 Stock | X | X | X | X | X | O |
bcm43430a11 | 7454126 | Raspberry Pi 3 and Zero W | Raspbian 8 | X | X | X | X | X | O |
bcm43430a11 | 7454146 | Raspberry Pi 3 and Zero W | Raspbian Stretch | X | X | X | X | X | O |
bcm43451b1 | 763430 | iPhone 6 | iOS 10.1.1 (14B100) | X | X | ||||
bcm43455 | 745770hw | Huawei P9 | Android 7 Stock | X | X | X | X | X | |
bcm43455 | 712051staC0 | Galaxy J7 2017 | ? | X | X | ||||
bcm43455 | 745770hw(8-2017) | Huawei P9 | Android 7 Stock | X | X | X | X | X | |
bcm434555 | 7467711hw | Huawei P9 | Android 8 China Stock | X | X | X | X | X | |
bcm43455 | 7455916 | Sony Xperia Z5 Compact | LineageOS 14.1 | X | X | X | X | X | |
bcm43455c0 | 745154 | Raspberry Pi B3+/B4 | Raspbian Kernel 4.9/14/19 | X | X | X | X | ||
bcm43455c0 | 745189 | Raspberry Pi B3+/B4 | Raspbian Kernel 4.14/19, 5.4 | X | X | X | X | ||
bcm43455c0 | 745206 | Raspberry Pi B3+/B4 | Raspberry Pi OS Kernel 5.4 | X | X | X | X | X | |
bcm4356 | 7351015sta | Nexus 6 | Android 7.1.2 | X | X | X | X | O | |
bcm4358 | 711220017sta | Nexus 6P | Android 7 Stock | X | X | X | X | O | |
bcm4358 | 71122013sta | Nexus 6P | Android 7.1.2 Stock | X | X | X | X | O | |
bcm43582 | 711230014sta | Nexus 6P | Android 8.0.0 Stock | X | X | X | X | X | O |
bcm43596a03 | 97515545stac0 | Samsung Galaxy S7 | Android 7 Stock | X | O | X | |||
bcm43596a03,2 | 9964stac0 | Samsung Galaxy S7 | LineageOS 14.1 | X | X | X | O | X | |
bcm4375b13,5,6 | 183818sta | Samsung Galaxy S10 | Rooted + disabled SELinux | X | X | X | O | X | |
bcm4375b13,5,6 | 184189sta | Samsung Galaxy S20 | Rooted + disabled SELinux | X | X | X | O | X | |
qca95004 | 4-1-055 | TP-Link Talon AD7200 | Custom LEDE Image |
1 bcm43430a1 was wrongly labeled bcm43438 in the past.
2 use LDPRELOAD=libnexmon.so instead of LDPRELOAD=libfakeioctl.so to inject frames through ioctls
3 flash patches need to be 8 bytes long and aligned on an 8 byte boundary
4 802.11ad Wi-Fi chip from first 60 GHz Wi-Fi router Talon AD7200. Patch your firmware using nexmon-arc and run it with our custom LEDE image lede-ad7200
5 Disabled the execution protection (called Execute Never) on region 1, because it interferes with the nexmon code (Permission fault on Section)
6 To use nexutil, you need to deactivate SELinux or set it to permissive
sudo apt-get install git gawk qpdf adb flex bison
sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
git clone https://github.com/seemoo-lab/nexmon.git
cd nexmon
source setup_env.sh
make
cd patches/bcm4339/6_37_34_43/nexmon/
make
make backup-firmware
make install-firmware(make sure your smartphone is connected to your machine beforehand)
makein the utilties folder (Note: you will need the Android NDK properly installed for this).
adb shell
nexutil -m2
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 security 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* Set the security cookie as root:
nexutil -x* Start a UDP connection for example to activate monitor mode:
nexutil -X -m1
Note: We currently support Kernel Version 4.4 (deprecated), 4.9, 4.14, 4.19 and 5.4. Raspbian contains firmware version 7.45.154 for the bcm43455c0. We also support the newer firmware release 7.45.189 from Cypress. Raspberry Pi OS contains firmware version 7.45.206. Please, try which works best for you. * Make sure the following commands are executed as root:
sudo su* Upgrade your Raspbian installation:
apt-get update && apt-get upgrade* Install the kernel headers to build the driver and some dependencies:
sudo apt install raspberrypi-kernel-headers git libgmp3-dev gawk qpdf bison flex make* Clone our repository:
git clone https://github.com/seemoo-lab/nexmon.git* Go into the root directory of our repository:
cd nexmon* Check if
/usr/lib/arm-linux-gnueabihf/libisl.so.10exists, if not, compile it from source: *
cd buildtools/isl-0.10,
./configure,
make,
make install,
ln -s /usr/local/lib/libisl.so /usr/lib/arm-linux-gnueabihf/libisl.so.10* Check if
/usr/lib/arm-linux-gnueabihf/libmpfr.so.4exists, if not, compile it from source: *
cd buildtools/mpfr-3.1.4,
autoreconf -f -i,
./configure,
make,
make install,
ln -s /usr/local/lib/libmpfr.so /usr/lib/arm-linux-gnueabihf/libmpfr.so.4* Then you can setup the build environment for compiling firmware patches * Setup the build environment:
source setup_env.sh* Compile some build tools and extract the ucode and flashpatches from the original firmware files:
make* Go to the patches folder for the bcm43430a1/bcm43455c0 chipset:
cd patches/bcm43430a1/7_45_41_46/nexmon//
patches/bcm43455c0/<7_45_154 or 7_45_189>/nexmon/* Compile a patched firmware:
make* Generate a backup of your original firmware file:
make backup-firmware* Install the patched firmware on your RPI3:
make install-firmware* Install nexutil: from the root directory of our repository switch to the nexutil folder:
cd utilities/nexutil/. Compile and install nexutil:
make && make install. * Optional: remove wpa_supplicant for better control over the WiFi interface:
apt-get remove wpasupplicant* Note: To connect to regular access points you have to execute
nexutil -m0first
iw phy `iw dev wlan0 info | gawk '/wiphy/ {printf "phy" $2}'` interface add mon0 type monitor
ifconfig mon0 up.
tcpdump -i mon0
modinfo brcmfmac#the first line should be the full path
mv "/brcmfmac.ko" "/brcmfmac.ko.orig"
cp /home/pi/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac_kernel49/brcmfmac.ko "/"
cp /home/pi/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac_4.14.y-nexmon/brcmfmac.ko "/"
depmod -a
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
wlan0interface.
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_ROOTpointing to the directory where you extracted the NDK files.
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.
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
For the BCM4339 and BCM4358, we created
rom_extractionprojects 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.binfile 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
buildtools: Contains compilers and other tools to build the firmware
firmwares
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
patches
nexmon
Makefile: Used to build the firmware
patch.ld: Linker file
src
patch.c: General patches to the firmware
injection.c: Code related to frame injection
monitormode.c: Code related to monitor mode with radiotap headers
ioctl.c: Handling of custom IOCTLs
obj(generated by Makefile): Object files created from C files
log(generated by Makefile): Logs written during compilation
gen(generated by Makefile): Files generated during the build process
nexmon.pre(generated by gcc plugin): Extracted at-attributes and targetregion-pragmas
nexmon.ld(generated from nexmon.pre): Linker file use to place patch code at defined addresses in the firmware
nexmon.mk(generated from nexmon.pre): Make file used take code from patch.elf and place it into firmware
flashpatches.ld(generated from nexmon.pre): Linker file that places flashpatches at target locations in firmware ROM
flashpatches.mk(generated from nexmon.pre): Make file used to insert flashpatch config and data structures into firmware
patch.elf(generated from object files and linker scripts): contains the newly compiled code placed at predefined addresses
common
wrapper.c: Wrappers for functions that already exist in the firmware
ucode_compression.c: tinflate based ucode decompression
radiotap.c: RadioTap header parser
helper.c: Helpful utility functions
include: Common include files
firmware_version.h: Definitions of chip and firmware versions
patcher.h: Macros use to perform patching for existing firmware code (e.g., BPatch patches a branch instruction)
capabilities.h: Allows to indicate capabilities (such as, monitor mode and frame injection)
nexioctl.h: Defines custom IOCTL numbers
If you know more projects that use nexmon or perform similar firmware hacks, let us know and we will add a link.
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:
@electronic{nexmon:project, author = {Schulz, Matthias and Wegemer, Daniel and Hollick, Matthias}, title = {Nexmon: The C-based Firmware Patching Framework}, url = {https://nexmon.org}, year = {2017} }