initial commit of our channel state information extractor

This commit is contained in:
Matthias Schulz 2018-03-12 23:55:57 +01:00
commit 74552bd857
12 changed files with 1389 additions and 0 deletions

61
LICENSE Normal file
View File

@ -0,0 +1,61 @@
########### ########### ########## ##########
############ ############ ############ ############
## ## ## ## ## ## ##
## ## ## ## ## ## ##
########### #### ###### ## ## ## ## ######
########### #### # ## ## ## ## # #
## ## ###### ## ## ## ## # #
## ## # ## ## ## ## # #
############ ##### ###### ## ## ## ##### ######
########### ########### ## ## ## ##########
S E C U R E M O B I L E N E T W O R K I N G
License:
Copyright (c) 2018 Matthias Schulz, Jakob Link, Francesco Gringoli
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:
1. The above copyright notice and this permission notice shall be
include in all copies or substantial portions of the Software.
2. Any use of the Software which results in an academic publication or
other publication which includes a bibliography must include
citations to the nexmon project a) and the paper cited under b) or
the thesis cited under c):
a) "Matthias Schulz, Daniel Wegemer and Matthias Hollick. Nexmon:
The C-based Firmware Patching Framework. https://nexmon.org"
b) "Matthias Schulz, Jakob Link, Francesco Gringoli, and Matthias
Hollick. Shadow Wi-Fi: Teaching Smart- phones to Transmit Raw
Signals and to Extract Channel State Information to Implement
Practical Covert Channels over Wi-Fi. Accepted to appear in
Proceedings of the 16th ACM International Conference on Mobile
Systems, Applications, and Services (MobiSys 2018), June 2018."
c) "Matthias Schulz. Teaching Your Wireless Card New Tricks:
Smartphone Performance and Security Enhancements through Wi-Fi
Firmware Modifications. Dr.-Ing. thesis, Technische Universität
Darmstadt, Germany, February 2018."
3. The Software is not used by, in cooperation with, or on behalf of
any armed forces, intelligence agencies, reconnaissance agencies,
defense agencies, offense agencies or any supplier, contractor, or
research associated.
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.

219
Makefile Normal file
View File

@ -0,0 +1,219 @@
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
include ../version.mk
include $(FW_PATH)/definitions.mk
LOCAL_SRCS=$(wildcard src/*.c) src/ucode_compressed.c src/templateram.c
COMMON_SRCS=$(wildcard $(NEXMON_ROOT)/patches/common/*.c)
FW_SRCS=$(wildcard $(FW_PATH)/*.c)
ifdef UCODEFILE
ifeq ($(wildcard src/$(UCODEFILE)), )
$(error selected src/$(UCODEFILE) does not exist)
endif
endif
ADBSERIAL :=
ADBFLAGS := $(ADBSERIAL)
UCODEFILE=ucode.asm
OBJS=$(addprefix obj/,$(notdir $(LOCAL_SRCS:.c=.o)) $(notdir $(COMMON_SRCS:.c=.o)) $(notdir $(FW_SRCS:.c=.o)))
CFLAGS= \
-fplugin=$(CCPLUGIN) \
-fplugin-arg-nexmon-objfile=$@ \
-fplugin-arg-nexmon-prefile=gen/nexmon.pre \
-fplugin-arg-nexmon-chipver=$(NEXMON_CHIP_NUM) \
-fplugin-arg-nexmon-fwver=$(NEXMON_FW_VERSION_NUM) \
-fno-strict-aliasing \
-DNEXMON_CHIP=$(NEXMON_CHIP) \
-DNEXMON_FW_VERSION=$(NEXMON_FW_VERSION) \
-DPATCHSTART=$(PATCHSTART) \
-DUCODESIZE=$(UCODESIZE) \
-DGIT_VERSION=\"$(GIT_VERSION)\" \
-DBUILD_NUMBER=\"$$(cat BUILD_NUMBER)\" \
-Wall -Werror -Wno-unused-function -Wno-unused-variable \
-O2 -nostdlib -nostartfiles -ffreestanding -mthumb -march=$(NEXMON_ARCH) \
-ffunction-sections -fdata-sections \
-I$(NEXMON_ROOT)/patches/include \
-Iinclude \
-I$(FW_PATH)
all: fw_bcmdhd.bin
init: FORCE
$(Q)if ! test -f BUILD_NUMBER; then echo 0 > BUILD_NUMBER; fi
$(Q)echo $$(($$(cat BUILD_NUMBER) + 1)) > BUILD_NUMBER
$(Q)touch src/version.c
$(Q)make -s -f $(NEXMON_ROOT)/patches/common/header.mk
$(Q)mkdir -p obj gen log
obj/%.o: src/%.c
@printf "\033[0;31m COMPILING\033[0m %s => %s (details: log/compiler.log)\n" $< $@
$(Q)cat gen/nexmon.pre 2>>log/error.log | gawk '{ if ($$3 != "$@") print; }' > tmp && mv tmp gen/nexmon.pre
$(Q)$(CC)gcc $(CFLAGS) -c $< -o $@ >>log/compiler.log
obj/%.o: $(NEXMON_ROOT)/patches/common/%.c
@printf "\033[0;31m COMPILING\033[0m %s => %s (details: log/compiler.log)\n" $< $@
$(Q)cat gen/nexmon.pre 2>>log/error.log | gawk '{ if ($$3 != "$@") print; }' > tmp && mv tmp gen/nexmon.pre
$(Q)$(CC)gcc $(CFLAGS) -c $< -o $@ >>log/compiler.log
obj/%.o: $(FW_PATH)/%.c
@printf "\033[0;31m COMPILING\033[0m %s => %s (details: log/compiler.log)\n" $< $@
$(Q)cat gen/nexmon.pre 2>>log/error.log | gawk '{ if ($$3 != "$@") print; }' > tmp && mv tmp gen/nexmon.pre
$(Q)$(CC)gcc $(CFLAGS) -c $< -o $@ >>log/compiler.log
gen/nexmon2.pre: $(OBJS)
@printf "\033[0;31m PREPARING\033[0m %s => %s\n" "gen/nexmon.pre" $@
$(Q)cat gen/nexmon.pre | awk '{ if ($$3 != "obj/flashpatches.o" && $$3 != "obj/wrapper.o") { print $$0; } }' > tmp
$(Q)cat gen/nexmon.pre | awk '{ if ($$3 == "obj/flashpatches.o" || $$3 == "obj/wrapper.o") { print $$0; } }' >> tmp
$(Q)cat tmp | awk '{ if ($$1 ~ /^0x/) { if ($$3 != "obj/flashpatches.o" && $$3 != "obj/wrapper.o") { if (!x[$$1]++) { print $$0; } } else { if (!x[$$1]) { print $$0; } } } else { print $$0; } }' > gen/nexmon2.pre
gen/nexmon.ld: gen/nexmon2.pre $(OBJS)
@printf "\033[0;31m GENERATING LINKER FILE\033[0m gen/nexmon.pre => %s\n" $@
$(Q)sort gen/nexmon2.pre | gawk -f $(NEXMON_ROOT)/buildtools/scripts/nexmon.ld.awk > $@
gen/nexmon.mk: gen/nexmon2.pre $(OBJS) $(FW_PATH)/definitions.mk
@printf "\033[0;31m GENERATING MAKE FILE\033[0m gen/nexmon.pre => %s\n" $@
$(Q)printf "fw_bcmdhd.bin: gen/patch.elf FORCE\n" > $@
$(Q)sort gen/nexmon2.pre | \
gawk -v src_file=gen/patch.elf -f $(NEXMON_ROOT)/buildtools/scripts/nexmon.mk.1.awk | \
gawk -v ramstart=$(RAMSTART) -f $(NEXMON_ROOT)/buildtools/scripts/nexmon.mk.2.awk >> $@
$(Q)printf "\nFORCE:\n" >> $@
$(Q)gawk '!a[$$0]++' $@ > tmp && mv tmp $@
gen/flashpatches.ld: gen/nexmon2.pre $(OBJS)
@printf "\033[0;31m GENERATING LINKER FILE\033[0m gen/nexmon.pre => %s\n" $@
$(Q)sort gen/nexmon2.pre | \
gawk -f $(NEXMON_ROOT)/buildtools/scripts/flashpatches.ld.awk > $@
gen/flashpatches.mk: gen/nexmon2.pre $(OBJS) $(FW_PATH)/definitions.mk
@printf "\033[0;31m GENERATING MAKE FILE\033[0m gen/nexmon.pre => %s\n" $@
$(Q)cat gen/nexmon2.pre | gawk \
-v fp_data_base=$(FP_DATA_BASE) \
-v fp_config_base=$(FP_CONFIG_BASE) \
-v fp_data_end_ptr=$(FP_DATA_END_PTR) \
-v fp_config_base_ptr_1=$(FP_CONFIG_BASE_PTR_1) \
-v fp_config_end_ptr_1=$(FP_CONFIG_END_PTR_1) \
-v fp_config_base_ptr_2=$(FP_CONFIG_BASE_PTR_2) \
-v fp_config_end_ptr_2=$(FP_CONFIG_END_PTR_2) \
-v ramstart=$(RAMSTART) \
-v out_file=fw_bcmdhd.bin \
-v src_file=gen/patch.elf \
-f $(NEXMON_ROOT)/buildtools/scripts/flashpatches.mk.awk > $@
gen/memory.ld: $(FW_PATH)/definitions.mk
@printf "\033[0;31m GENERATING LINKER FILE\033[0m %s\n" $@
$(Q)printf "rom : ORIGIN = 0x%08x, LENGTH = 0x%08x\n" $(ROMSTART) $(ROMSIZE) > $@
$(Q)printf "ram : ORIGIN = 0x%08x, LENGTH = 0x%08x\n" $(RAMSTART) $(RAMSIZE) >> $@
$(Q)printf "patch : ORIGIN = 0x%08x, LENGTH = 0x%08x\n" $(PATCHSTART) $(PATCHSIZE) >> $@
$(Q)printf "ucode : ORIGIN = 0x%08x, LENGTH = 0x%08x\n" $(UCODESTART) $$(($(FP_CONFIG_BASE) - $(UCODESTART))) >> $@
$(Q)printf "fpconfig : ORIGIN = 0x%08x, LENGTH = 0x%08x\n" $(FP_CONFIG_BASE) $(FP_CONFIG_SIZE) >> $@
gen/patch.elf: patch.ld gen/nexmon.ld gen/flashpatches.ld gen/memory.ld $(OBJS)
@printf "\033[0;31m LINKING OBJECTS\033[0m => %s (details: log/linker.log, log/linker.err)\n" $@
$(Q)$(CC)ld -T $< -o $@ --gc-sections --print-gc-sections -M >>log/linker.log 2>>log/linker.err
fw_bcmdhd.bin: init gen/patch.elf $(FW_PATH)/$(RAM_FILE) gen/nexmon.mk gen/flashpatches.mk
$(Q)cp $(FW_PATH)/$(RAM_FILE) $@
@printf "\033[0;31m APPLYING FLASHPATCHES\033[0m gen/flashpatches.mk => %s (details: log/flashpatches.log)\n" $@
$(Q)make -f gen/flashpatches.mk >>log/flashpatches.log 2>>log/flashpatches.log
@printf "\033[0;31m APPLYING PATCHES\033[0m gen/nexmon.mk => %s (details: log/patches.log)\n" $@
$(Q)make -f gen/nexmon.mk >>log/patches.log 2>>log/flashpatches.log
###################################################################
# ucode compression related
###################################################################
gen/ucode.asm: $(FW_PATH)/ucode.bin
@printf "\033[0;31m DISASSEMBLING UCODE\033[0m %s => %s\n" $< $@
$(Q)$(NEXMON_ROOT)/buildtools/b43/disassembler/b43-dasm $< $@ --arch 15 --format raw-le32
$(Q)$(NEXMON_ROOT)/buildtools/b43/debug/b43-beautifier --asmfile $@ --defs $(NEXMON_ROOT)/buildtools/b43/debug/include > tmp && mv tmp $@
$(Q)cat $@ | gcc -fpreprocessed -dD -E - > tmp && mv tmp $@
$(Q)sed -i '/^$$/d' $@
$(Q)sed -i '/"<stdin>"/d' $@
$(Q)sed -i -r 's|(mov )(0x48)(, SPR_TME_VAL12)|\1MAC_SUBTYPE_DATA_NULL\3|' gen/ucode.asm
$(Q)sed -i -r 's|(mov )(0xC4)(, SPR_TME_VAL12)|\1MAC_SUBTYPE_CONTROL_CTS\3|' gen/ucode.asm
$(Q)sed -i -r 's|(mov )(0xD4)(, SPR_TME_VAL12)|\1MAC_SUBTYPE_CONTROL_ACK\3|' gen/ucode.asm
$(Q)sed -i -r 's|\[0x848\]|\[RX_HDR_RxStatus1\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x84B\]|\[RX_HDR_RxChan\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x849\]|\[RX_HDR_RxStatus2\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x84A\]|\[RX_HDR_RxTSFTime\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x842\]|\[RX_HDR_PhyRxStatus_0\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x843\]|\[RX_HDR_PhyRxStatus_1\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x844\]|\[RX_HDR_PhyRxStatus_2\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x845\]|\[RX_HDR_PhyRxStatus_3\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x846\]|\[RX_HDR_PhyRxStatus_4\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x847\]|\[RX_HDR_PhyRxStatus_5\]|g' gen/ucode.asm
$(Q)sed -i -r 's|\[0x840\]|\[RX_HDR_RxFrameSize\]|g' gen/ucode.asm
src/%.asm: src/%.patch gen/ucode.asm
@printf "\033[0;31m PATCHING UCODE\033[0m %s => %s\n" $< $@
$(Q)cp gen/ucode.asm $@
$(Q)patch -p1 $@ $< >log/patch.log || true
ifneq ($(wildcard src/$(UCODEFILE) src/$(UCODEFILE:.asm=.patch)), )
gen/ucode.bin: src/$(UCODEFILE)
@printf "\033[0;31m ASSEMBLING UCODE\033[0m %s => %s\n" $< $@
ifneq ($(wildcard $(NEXMON_ROOT)/buildtools/b43/assembler/b43-asm.bin), )
$(Q)PATH=$(PATH):$(NEXMON_ROOT)/buildtools/b43/assembler $(NEXMON_ROOT)/buildtools/b43/assembler/b43-asm $< $@ --format raw-le32
else
$(error Warning: please compile b43-asm.bin first)
endif
else
gen/ucode.bin: $(FW_PATH)/ucode.bin
@printf "\033[0;31m COPYING UCODE\033[0m %s => %s\n" $< $@
$(Q)cp $< $@
endif
gen/ucode_compressed.bin: gen/ucode.bin
@printf "\033[0;31m COMPRESSING UCODE\033[0m %s => %s\n" $< $@
$(Q)cat $< | $(ZLIBFLATE) > $@
src/ucode_compressed.c: gen/ucode_compressed.bin
@printf "\033[0;31m GENERATING C FILE\033[0m %s => %s\n" $< $@
$(Q)printf "#pragma NEXMON targetregion \"ucode\"\n\n" > $@
$(Q)cd $(dir $<) && xxd -i $(notdir $<) >> $(shell pwd)/$@
src/templateram.c: $(FW_PATH)/templateram.bin
@printf "\033[0;31m GENERATING C FILE\033[0m %s => %s\n" $< $@
$(Q)printf "#pragma NEXMON targetregion \"ucode\"\n\n" > $@
$(Q)cd $(dir $<) && xxd -i $(notdir $<) >> $(shell pwd)/$@
###################################################################
check-nexmon-setup-env:
ifndef NEXMON_SETUP_ENV
$(error run 'source setup_env.sh' first in the repository\'s root directory)
endif
install-firmware: fw_bcmdhd.bin
@printf "\033[0;31m REMOUNTING /system\033[0m\n"
$(Q)adb $(ADBFLAGS) shell 'su -c "mount -o rw,remount /system"'
@printf "\033[0;31m COPYING TO PHONE\033[0m %s => /sdcard/%s\n" $< $<
$(Q)adb $(ADBFLAGS) push $< /sdcard/ >> log/adb.log 2>> log/adb.log
@printf "\033[0;31m COPYING\033[0m /sdcard/fw_bcmdhd.bin => /vendor/firmware/fw_bcmdhd.bin\n"
$(Q)adb $(ADBFLAGS) shell 'su -c "rm /vendor/firmware/fw_bcmdhd.bin && cp /sdcard/fw_bcmdhd.bin /vendor/firmware/fw_bcmdhd.bin"'
@printf "\033[0;31m RELOADING FIRMWARE\033[0m\n"
$(Q)adb $(ADBFLAGS) shell 'su -c "ifconfig wlan0 down && ifconfig wlan0 up"'
backup-firmware: FORCE
adb $(ADBFLAGS) shell 'su -c "cp /vendor/firmware/fw_bcmdhd.bin /sdcard/fw_bcmdhd.orig.bin"'
adb $(ADBFLAGS) pull /sdcard/fw_bcmdhd.orig.bin
install-backup: fw_bcmdhd.orig.bin
adb $(ADBFLAGS) shell 'su -c "mount -o rw,remount /system"' && \
adb $(ADBFLAGS) push $< /sdcard/ && \
adb $(ADBFLAGS) shell 'su -c "cp /sdcard/fw_bcmdhd.bin /vendor/firmware/fw_bcmdhd.bin"'
adb $(ADBFLAGS) shell 'su -c "ifconfig wlan0 down && ifconfig wlan0 up"'
clean-firmware: FORCE
@printf "\033[0;31m CLEANING\033[0m\n"
$(Q)rm -fr fw_bcmdhd.bin obj gen log src/ucode_compressed.c src/templateram.c
clean: clean-firmware
$(Q)rm -f BUILD_NUMBER
FORCE:

96
README.md Normal file
View File

@ -0,0 +1,96 @@
![NexMon logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/nexmon.png)
# Nexmon Channel State Information Extractor
This projects allows you to extract channel state information (CSI) of OFDM-modulated
Wi-Fi frames (802.11a/(g)/n/ac) on a per frame basis with up to 80 MHz bandwidth
using BCM4339 Wi-Fi chips installed, for example, in Nexus 5 smartphones.
```
echo "64d0010080000000ffffffffffff001122334455" | xxd -r -p | base64
```
# Extract from our License
Any use of the Software which results in an academic publication or
other publication which includes a bibliography must include
citations to the nexmon project a) and the paper cited under b) or
the thesis cited under c):
a) "Matthias Schulz, Daniel Wegemer and Matthias Hollick. Nexmon:
The C-based Firmware Patching Framework. https://nexmon.org"
b) "Matthias Schulz, Jakob Link, Francesco Gringoli, and Matthias
Hollick. Shadow Wi-Fi: Teaching Smartphones to Transmit Raw
Signals and to Extract Channel State Information to Implement
Practical Covert Channels over Wi-Fi. Accepted to appear in
Proceedings of the 16th ACM International Conference on Mobile
Systems, Applications, and Services (MobiSys 2018), June 2018."
c) "Matthias Schulz. Teaching Your Wireless Card New Tricks:
Smartphone Performance and Security Enhancements through Wi-Fi
Firmware Modifications. Dr.-Ing. thesis, Technische Universität
Darmstadt, Germany, February 2018."
# Getting Started
To compile the source code, you are required to first clone the original nexmon repository
that contains our C-based patching framework for Wi-Fi firmwares. Than you clone this
repository as one of the sub-projects in the corresponding patches sub-directory. This
allows you to build and compile all the firmware patches required to repeat our experiments.
The following steps will get you started on Xubuntu 16.04 LTS:
1. Install some dependencies: `sudo apt-get install git gawk qpdf adb`
2. **Only necessary for x86_64 systems**, install i386 libs:
```
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
```
3. Clone the nexmon base repository: `git clone https://github.com/seemoo-lab/nexmon.git`.
4. Download and extract Android NDK r11c (use exactly this version!).
5. Export the NDK_ROOT environment variable pointing to the location where you extracted the
ndk so that it can be found by our build environment.
6. Navigate to the previously cloned nexmon directory and execute `source setup_env.sh` to set
a couple of environment variables.
7. Run `make` to extract ucode, templateram and flashpatches from the original firmwares.
8. Navigate to utilities and run `make` to build all utilities such as nexmon.
9. Attach your rooted Nexus 5 smartphone running stock firmware version 6.0.1 (M4B30Z, Dec 2016).
10. Run `make install` to install all the built utilities on your phone.
11. Navigate to patches/bcm4339/6_37_34_43/ and clone this repository:
`git clone https://github.com/seemoo-lab/mobisys2018_nexmon_channel_state_information_extractor.git`
12. Enter the created subdirectory mobisys2018_nexmon_channel_state_information_extractor and run
`make install-firmware` to compile our firmware patch and install it on the attached Nexus 5
smartphone.
# References
* Matthias Schulz, Daniel Wegemer and Matthias Hollick. **Nexmon: The C-based Firmware Patching
Framework**. https://nexmon.org
* Matthias Schulz, Jakob Link, Francesco Gringoli, and Matthias Hollick. **Shadow Wi-Fi: Teaching
Smartphones to Transmit Raw Signals and to Extract Channel State Information to Implement
Practical Covert Channels over Wi-Fi. Accepted to appear in *Proceedings of the 16th ACM
International Conference on Mobile Systems, Applications, and Services*, MobiSys 2018, June 2018.
* Matthias Schulz. **Teaching Your Wireless Card New Tricks: Smartphone Performance and Security
Enhancements through Wi-Fi Firmware Modifications**. Dr.-Ing. thesis, Technische Universität
Darmstadt, Germany, February 2018.
[Get references as bibtex file](https://nexmon.org/bib)
# Contact
* [Matthias Schulz](https://seemoo.tu-darmstadt.de/mschulz) <mschulz@seemoo.tu-darmstadt.de>
# Powered By
## Secure Mobile Networking Lab (SEEMOO)
<a href="https://www.seemoo.tu-darmstadt.de">![SEEMOO logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/seemoo.png)</a>
## Networked Infrastructureless Cooperation for Emergency Response (NICER)
<a href="https://www.nicer.tu-darmstadt.de">![NICER logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/nicer.png)</a>
## Multi-Mechanisms Adaptation for the Future Internet (MAKI)
<a href="http://www.maki.tu-darmstadt.de/">![MAKI logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/maki.png)</a>
## Technische Universität Darmstadt
<a href="https://www.tu-darmstadt.de/index.en.jsp">![TU Darmstadt logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/tudarmstadt.png)</a>
## University of Brescia
<a href="http://netweb.ing.unibs.it/">![University of Brescia logo](https://github.com/seemoo-lab/nexmon/raw/master/gfx/brescia.png)</a>

43
include/macros.inc Normal file
View File

@ -0,0 +1,43 @@
#ifndef MACROS_INC_
#define MACROS_INC_
#define phy_reg_read(addr, target) \
mov addr, r33 \
calls L52 \
or SPR_Ext_IHR_Data, 0x0, target
#define phy_reg_read_to_shm(addr, target) \
mov addr, r33 \
calls L52 \
or SPR_Ext_IHR_Data, 0x0, [target]
#define phy_reg_read_to_shm_off(addr, base, offset) \
mov addr, r33 \
calls L52 \
or SPR_Ext_IHR_Data, 0x0, [base, offset]
#define phy_reg_write(addr, value) \
mov addr, r33 \
mov value, r34 \
calls L54
#define phy_reg_or(addr, value) \
mov addr, r33 \
calls L52 \
mov value, r34 \
or SPR_Ext_IHR_Data, r34, r34 \
calls L54
#define phy_reg_and(addr, value) \
mov addr, r33 \
calls L52 \
mov value, r34 \
and SPR_Ext_IHR_Data, r34, r34 \
calls L54
#define phy_table_write_word(id, offset, data) \
phy_reg_write(ACPHY_TableID(rev), id) \
phy_reg_write(ACPHY_TableOffset(rev), offset) \
phy_reg_write(ACPHY_TableDataLo(rev), data)
#endif /* MACROS_INC_ */

38
include/rxhdrlen.h Normal file
View File

@ -0,0 +1,38 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/
// rx header length in words
#define RX_HDR_LEN 32
// additional words used for wlc_d11rxhdr that is not contained in d11rxhdr
#define RX_HDR_EXTRA 8

10
patch.ld Normal file
View File

@ -0,0 +1,10 @@
MEMORY
{
INCLUDE gen/memory.ld
}
SECTIONS
{
INCLUDE gen/flashpatches.ld
INCLUDE gen/nexmon.ld
}

234
src/csi_extraction.c Normal file
View File

@ -0,0 +1,234 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* Warning: *
* *
* Our software may damage your hardware and may void your hardwares *
* warranty! You use our tools at your own risk and responsibility! *
* *
* License: *
* Copyright (c) 2015 NexMon Team *
* *
* 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 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. *
* *
* Any use of the Software which results in an academic publication or *
* other publication which includes a bibliography must include a citation *
* to the author's publication "M. Schulz, D. Wegemer and M. Hollick. *
* NexMon: A Cookbook for Firmware Modifications on Smartphones to Enable *
* Monitor Mode.". *
* *
* 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. *
* *
**************************************************************************/
#pragma NEXMON targetregion "patch"
#include <firmware_version.h> // definition of firmware version macros
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <helper.h> // useful helper functions
#include <patcher.h> // macros used to craete patches such as BLPatch, BPatch, ...
#include <rxhdrlen.h> // contains RX_HDR_LEN and RX_HDR_EXTRA
#include <sendframe.h>
#include <nexioctls.h> // ioctls added in the nexmon patch
#include <rates.h>
extern void prepend_ethernet_ipv4_udp_header(struct sk_buff *p);
#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
// header of csi frame coming from ucode
struct d11csihdr {
uint16 RxFrameSize; /* 0x000 Set to 0x2 for CSI frames */
uint16 NexmonExt; /* 0x002 */
uint32 csi[]; /* 0x004 Array of CSI data */
} __attribute__((packed));
// original hardware header
struct d11rxhdr {
uint16 RxFrameSize; /* 0x000 Set to 0x2 for CSI frames */
uint16 NexmonExt; /* 0x002 */
uint16 PhyRxStatus_0; /* 0x004 PhyRxStatus 15:0 */
uint16 PhyRxStatus_1; /* 0x006 PhyRxStatus 31:16 */
uint16 PhyRxStatus_2; /* 0x008 PhyRxStatus 47:32 */
uint16 PhyRxStatus_3; /* 0x00a PhyRxStatus 63:48 */
uint16 PhyRxStatus_4; /* 0x00c PhyRxStatus 79:64 */
uint16 PhyRxStatus_5; /* 0x00e PhyRxStatus 95:80 */
uint16 RxStatus1; /* 0x010 MAC Rx Status */
uint16 RxStatus2; /* 0x012 extended MAC Rx status */
uint16 RxTSFTime; /* 0x014 RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
uint16 RxChan; /* 0x016 gain code, channel radio code, and phy type */
} __attribute__((packed));
// header or regular frame coming from ucode
struct nexmon_d11rxhdr {
struct d11rxhdr rxhdr; /* 0x000 d11rxhdr */
uint8 SrcMac[6]; /* 0x018 source mac address */
} __attribute__((packed));
// header after process_frame_hook
struct wlc_d11rxhdr {
struct d11rxhdr rxhdr; /* 0x000 d11rxhdr */
uint32 tsf_l; /* 0x018 TSF_L reading */
int8 rssi; /* 0x01c computed instantaneous rssi in BMAC */
int8 rxpwr0; /* 0x01d obsoleted, place holder for legacy ROM code. use rxpwr[] */
int8 rxpwr1; /* 0x01e obsoleted, place holder for legacy ROM code. use rxpwr[] */
int8 do_rssi_ma; /* 0x01f do per-pkt sampling for per-antenna ma in HIGH */
int8 rxpwr[WL_RSSI_ANT_MAX]; /* 0x020 rssi for supported antennas */
int8 rssi_qdb; /* 0x024 qdB portion of the computed rssi */
uint8 PAD[2]; /* 0x025 extra padding to fill up RX_HDR_EXTRA */
} __attribute__((packed));
struct csi_value_i16 {
int16 i;
int16 q;
} __attribute__((packed));
struct csi_udp_frame {
struct ethernet_ip_udp_header hdrs;
uint32 kk1;
uint8 SrcMac[6];
uint32 kk2;
struct csi_value_i16 csi_values[];
} __attribute__((packed));
uint16 missing_csi_frames = 0;
uint16 inserted_csi_values = 0;
struct sk_buff *p_csi = 0;
struct int14 {signed int val:14;} __attribute__((packed));
void
create_new_csi_frame(struct wl_info *wl, struct sk_buff *p, struct wlc_d11rxhdr *wlc_rxhdr)
{
struct osl_info *osh = wl->wlc->osh;
missing_csi_frames = wlc_rxhdr->rxhdr.NexmonExt;
// create new csi frame
p_csi = pkt_buf_get_skb(osh, sizeof(struct csi_udp_frame) + missing_csi_frames * (RX_HDR_LEN * 2));
inserted_csi_values = 0;
struct csi_udp_frame *udpfrm = (struct csi_udp_frame *) p_csi->data;
struct nexmon_d11rxhdr *ucodefrm = (struct nexmon_d11rxhdr *) p->data;
udpfrm->kk1 = 0x11111111;
udpfrm->kk2 = wlc_recv_compute_rspec(&wlc_rxhdr->rxhdr, p->data);
// copy mac address to new udp frame
memcpy(udpfrm->SrcMac, ucodefrm->SrcMac, sizeof(udpfrm->SrcMac));
}
void
process_frame_hook(struct sk_buff *p, struct wlc_d11rxhdr *wlc_rxhdr, struct wlc_hw_info *wlc_hw, int tsf_l)
{
struct osl_info *osh = wlc_hw->wlc->osh;
struct wl_info *wl = wlc_hw->wlc->wl;
if (p_csi == 0) {
if (wlc_rxhdr->rxhdr.RxFrameSize == 2) {
printf("csi out of order\n");
pkt_buf_free_skb(osh, p, 0); // drop incoming csi frame
return; // drop all csi frames, if no csi information required
} else if (wlc_rxhdr->rxhdr.NexmonExt > 0) {
create_new_csi_frame(wl, p, wlc_rxhdr);
}
} else {
struct csi_udp_frame *udpfrm = (struct csi_udp_frame *) p_csi->data;
if (wlc_rxhdr->rxhdr.RxFrameSize == 2) {
struct d11csihdr *ucodecsifrm = (struct d11csihdr *) p->data;
missing_csi_frames--;
struct int14 sint14;
int i;
for (i = 0; i < wlc_rxhdr->rxhdr.NexmonExt; i++) {
struct csi_value_i16 *val = &udpfrm->csi_values[inserted_csi_values];
val->i = sint14.val = (ucodecsifrm->csi[i] >> 14) & 0x3fff;
val->q = sint14.val = ucodecsifrm->csi[i] & 0x3fff;
inserted_csi_values++;
}
if (missing_csi_frames == 0) {
// as prepend_ethernet_ipv4_udp_header pushes, we need to pull first
p_csi->len = sizeof(struct csi_udp_frame) + inserted_csi_values * sizeof(struct csi_value_i16);
skb_pull(p_csi, sizeof(struct ethernet_ip_udp_header));
prepend_ethernet_ipv4_udp_header(p_csi);
wl->dev->chained->funcs->xmit(wl->dev, wl->dev->chained, p_csi);
p_csi = 0;
}
pkt_buf_free_skb(osh, p, 0); // drop incoming csi frame
return;
} else {
printf("csi missing, size: %d\n", wlc_rxhdr->rxhdr.RxFrameSize);
pkt_buf_free_skb(osh, p_csi, 0);
if (wlc_rxhdr->rxhdr.NexmonExt > 0) {
create_new_csi_frame(wl, p, wlc_rxhdr);
}
}
}
// only continue processing this frame, if it is not a csi frame
wlc_rxhdr->tsf_l = tsf_l;
wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
wlc_recv(wlc_hw->wlc, p);
}
// hook to allow handling the wlc_d11rxhdr on our own to avoid overwriting of additional information in d11rxhdr passed from the ucode
__attribute__((at(0x1AAFCC, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
__attribute__((naked))
void
process_frame_prehook(void)
{
asm(
"mov r2, r4\n" // 2 bytes: move wlc_hw pointer to r2
"ldr r0, [sp,0xC]\n" // 4 bytes: load reference to p into r0
"bl process_frame_hook\n" // 4 bytes
"nop\n" // 2 bytes: to overwrite existing instruction
"nop\n" // 2 bytes: to overwrite existing instruction
"nop\n" // 2 bytes: to overwrite existing instruction
"nop\n" // 2 bytes: to overwrite existing instruction
"nop\n" // 2 bytes: to overwrite existing instruction
);
}

125
src/ioctl.c Normal file
View File

@ -0,0 +1,125 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/
#pragma NEXMON targetregion "patch"
#include <firmware_version.h> // definition of firmware version macros
#include <debug.h> // contains macros to access the debug hardware
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <helper.h> // useful helper functions
#include <patcher.h> // macros used to craete patches such as BLPatch, BPatch, ...
#include <rates.h> // rates used to build the ratespec for frame injection
#include <nexioctls.h> // ioctls added in the nexmon patch
#include <version.h> // version information
#include <argprintf.h> // allows to execute argprintf to print into the arg buffer
#include <channels.h>
#define SHM_CSI_COLLECT 0x8b0
#define SHM_CSI_COPIED 0x8b1
#define CMP_FRM_CTRL_FLD 0x8b2
#define CMP_DURATION 0x8b3
#define CMP_DST_MAC_0 0x8b4
#define CMP_DST_MAC_1 0x8b5
#define CMP_DST_MAC_2 0x8b6
#define CMP_SRC_MAC_0 0x8b7
#define CMP_SRC_MAC_1 0x8b8
#define CMP_SRC_MAC_2 0x8b9
int
wlc_ioctl_hook(struct wlc_info *wlc, int cmd, char *arg, int len, void *wlc_if)
{
int ret = IOCTL_ERROR;
argprintf_init(arg, len);
switch(cmd) {
case 500: // set csi_collect
{
struct params {
uint16 chanspec;
uint16 csi_collect;
uint16 cmp_frm_ctrl_fld;
uint16 cmp_duration;
uint16 cmp_dst_mac_0;
uint16 cmp_dst_mac_1;
uint16 cmp_dst_mac_2;
uint16 cmp_src_mac_0;
uint16 cmp_src_mac_1;
uint16 cmp_src_mac_2;
};
struct params *params = (struct params *) arg;
// deactivate scanning
set_scansuppress(wlc, 1);
// deactivate minimum power consumption
set_mpc(wlc, 0);
// set the channel
set_chanspec(wlc, params->chanspec);
if (wlc->hw->up && len > 1) {
wlc_bmac_write_shm(wlc->hw, SHM_CSI_COLLECT * 2, params->csi_collect);
wlc_bmac_write_shm(wlc->hw, CMP_FRM_CTRL_FLD * 2, params->cmp_frm_ctrl_fld);
wlc_bmac_write_shm(wlc->hw, CMP_DURATION * 2, params->cmp_duration);
wlc_bmac_write_shm(wlc->hw, CMP_DST_MAC_0 * 2, params->cmp_dst_mac_0);
wlc_bmac_write_shm(wlc->hw, CMP_DST_MAC_1 * 2, params->cmp_dst_mac_1);
wlc_bmac_write_shm(wlc->hw, CMP_DST_MAC_2 * 2, params->cmp_dst_mac_2);
wlc_bmac_write_shm(wlc->hw, CMP_SRC_MAC_0 * 2, params->cmp_src_mac_0);
wlc_bmac_write_shm(wlc->hw, CMP_SRC_MAC_1 * 2, params->cmp_src_mac_1);
wlc_bmac_write_shm(wlc->hw, CMP_SRC_MAC_2 * 2, params->cmp_src_mac_2);
ret = IOCTL_SUCCESS;
}
break;
}
case 501: // get csi_collect
{
if (wlc->hw->up && len > 1) {
*(uint16 *) arg = wlc_bmac_read_shm(wlc->hw, SHM_CSI_COLLECT * 2);
ret = IOCTL_SUCCESS;
}
break;
}
default:
ret = wlc_ioctl(wlc, cmd, arg, len, wlc_if);
}
return ret;
}
__attribute__((at(0x1F3488, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(wlc_ioctl_hook, wlc_ioctl_hook + 1);

61
src/patch.c Normal file
View File

@ -0,0 +1,61 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/
#pragma NEXMON targetregion "patch"
#include <firmware_version.h> // definition of firmware version macros
#include <debug.h> // contains macros to access the debug hardware
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <helper.h> // useful helper functions
#include <patcher.h> // macros used to craete patches such as BLPatch, BPatch, ...
#include <rates.h> // rates used to build the ratespec for frame injection
#include <capabilities.h> // capabilities included in a nexmon patch
int capabilities = NEX_CAP_MONITOR_MODE | NEX_CAP_MONITOR_MODE_RADIOTAP | NEX_CAP_FRAME_INJECTION;
// Hook the call to wlc_ucode_write in wlc_ucode_download
__attribute__((at(0x1F4F08, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_40_r581243)))
__attribute__((at(0x1F4F14, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
BLPatch(wlc_ucode_write_compressed, wlc_ucode_write_compressed);
// reduce the amount of ucode memory freed to become part of the heap
__attribute__((at(0x1816E0, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(hndrte_reclaim_0_end, PATCHSTART);
extern unsigned char templateram_bin[];
// Moving template ram to another place in the ucode region
__attribute__((at(0x185544, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(templateram_bin, templateram_bin);

117
src/regulations.c Normal file
View File

@ -0,0 +1,117 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* Warning: *
* *
* Our software may damage your hardware and may void your hardwares *
* warranty! You use our tools at your own risk and responsibility! *
* *
* License: *
* Copyright (c) 2015 NexMon Team *
* *
* 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 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. *
* *
* Any use of the Software which results in an academic publication or *
* other publication which includes a bibliography must include a citation *
* to the author's publication "M. Schulz, D. Wegemer and M. Hollick. *
* NexMon: A Cookbook for Firmware Modifications on Smartphones to Enable *
* Monitor Mode.". *
* *
* 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. *
* *
**************************************************************************/
#pragma NEXMON targetregion "patch"
#include <firmware_version.h>
#include <channels.h>
#include <patcher.h>
#include <wrapper.h>
#include <channels.h>
// Nop the following call to keep user tx power targets
// Choose least of user and now combined regulatory/hw targets
// ppr_compare_min(tx_pwr_target, srom_max_txpwr);
__attribute__((at(0x1C50B8, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(nop_ppr_compare_min, 0);
// This allows 80 MHz channels in the 2 GHz band
int
wf_chspec_malformed_hook(unsigned short chanspec)
{
return 0;
}
__attribute__((at(0x13778, "flashpatch", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
BPatch(wf_chspec_malformed_hook, wf_chspec_malformed_hook);
unsigned short additional_valid_chanspecs[] = {
CH20MHZ_CHSPEC(1),
CH20MHZ_CHSPEC(2),
CH20MHZ_CHSPEC(3),
CH20MHZ_CHSPEC(4),
CH20MHZ_CHSPEC(5),
CH20MHZ_CHSPEC(6),
CH20MHZ_CHSPEC(7),
CH20MHZ_CHSPEC(8),
CH20MHZ_CHSPEC(9),
CH20MHZ_CHSPEC(10),
CH20MHZ_CHSPEC(11),
CH20MHZ_CHSPEC(12),
CH20MHZ_CHSPEC(13),
CH20MHZ_CHSPEC(14),
CH80MHZ_CHSPEC(6, WL_CHANSPEC_CTL_SB_L),
CH20MHZ_CHSPEC(7),
CH40MHZ_CHSPEC(7, WL_CHANSPEC_CTL_SB_L),
CH80MHZ_CHSPEC(7, WL_CHANSPEC_CTL_SB_L),
CH20MHZ_CHSPEC(44),
CH40MHZ_CHSPEC(44, WL_CHANSPEC_CTL_SB_L),
CH20MHZ_CHSPEC(100),
CH20MHZ_CHSPEC(106),
CH40MHZ_CHSPEC(106, WL_CHANSPEC_CTL_SB_L),
CH80MHZ_CHSPEC(106, WL_CHANSPEC_CTL_SB_L),
CH20MHZ_CHSPEC(120),
CH20MHZ_CHSPEC(140),
};
int
wlc_valid_chanspec_ext_hook(void *wlc_cm, unsigned short chanspec, int dualband)
{
int valid = wlc_valid_chanspec_ext(wlc_cm, chanspec, dualband);
int i;
if (!valid && dualband == 1)
for (i = 0; i < sizeof(additional_valid_chanspecs)/sizeof(additional_valid_chanspecs[0]); i++)
valid |= additional_valid_chanspecs[i] == chanspec;
return valid;
}
__attribute__((at(0x5BA28, "flashpatch", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
BPatch(wlc_valid_chanspec_ext, wlc_valid_chanspec_ext_hook)

67
src/rxhdrlen.c Normal file
View File

@ -0,0 +1,67 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* Warning: *
* *
* Our software may damage your hardware and may void your hardwares *
* warranty! You use our tools at your own risk and responsibility! *
* *
* License: *
* Copyright (c) 2015 NexMon Team *
* *
* 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 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. *
* *
* Any use of the Software which results in an academic publication or *
* other publication which includes a bibliography must include a citation *
* to the author's publication "M. Schulz, D. Wegemer and M. Hollick. *
* NexMon: A Cookbook for Firmware Modifications on Smartphones to Enable *
* Monitor Mode.". *
* *
* 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. *
* *
**************************************************************************/
#pragma NEXMON targetregion "patch"
#include <firmware_version.h> // definition of firmware version macros
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <helper.h> // useful helper functions
#include <patcher.h> // macros used to craete patches such as BLPatch, BPatch, ...
#include <rxhdrlen.h> // contains RX_HDR_LEN and RX_HDR_EXTRA
__attribute__((at(0x1F580C, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch2(hwrxoff, 0x2300 + 2 * (RX_HDR_LEN + RX_HDR_EXTRA));
// Change the rxhdr_len in the initvals
__attribute__((at(0x1D4370, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(initvals_rxhdr_len0, 2 * RX_HDR_LEN);
__attribute__((at(0x1D4388, "", CHIP_VER_BCM4339, FW_VER_6_37_32_RC23_34_43_r639704)))
GenericPatch4(initvals_rxhdr_len1, 2 * RX_HDR_LEN);

318
src/ucode.patch Normal file
View File

@ -0,0 +1,318 @@
--- ../gen/ucode.asm 2018-03-12 23:32:43.152016700 +0100
+++ ucode.asm 2018-03-12 23:32:50.777878856 +0100
@@ -3,0 +4,37 @@
+#include "../include/macros.inc"
+#define phy_reg_read_to_shm(addr,target) \
+ mov addr, r33 \
+ calls L52 \
+ or SPR_Ext_IHR_Data, 0x0, [target]
+#define phy_reg_write(addr,value) \
+ mov addr, r33 \
+ mov value, r34 \
+ calls L54
+#define RX_HDR_LEN 32
+#define RX_HDR_BASE 0x8c0
+#define RX_HDR_OFFSET(off) (RX_HDR_BASE + off)
+#define RX_HDR_RxFrameSize RX_HDR_OFFSET(0)
+#define RX_HDR_NexmonExt RX_HDR_OFFSET(1)
+#define RX_HDR_PhyRxStatus_0 RX_HDR_OFFSET(2)
+#define RX_HDR_PhyRxStatus_1 RX_HDR_OFFSET(3)
+#define RX_HDR_PhyRxStatus_2 RX_HDR_OFFSET(4)
+#define RX_HDR_PhyRxStatus_3 RX_HDR_OFFSET(5)
+#define RX_HDR_PhyRxStatus_4 RX_HDR_OFFSET(6)
+#define RX_HDR_PhyRxStatus_5 RX_HDR_OFFSET(7)
+#define RX_HDR_RxStatus1 RX_HDR_OFFSET(8)
+#define RX_HDR_RxStatus2 RX_HDR_OFFSET(9)
+#define RX_HDR_RxTSFTime RX_HDR_OFFSET(10)
+#define RX_HDR_RxChan RX_HDR_OFFSET(11)
+#define RX_HDR_NEXMON_SrcMac0 RX_HDR_OFFSET(12)
+#define RX_HDR_NEXMON_SrcMac1 RX_HDR_OFFSET(13)
+#define RX_HDR_NEXMON_SrcMac2 RX_HDR_OFFSET(14)
+#define SHM_CSI_COLLECT 0x8b0
+#define SHM_CSI_COPIED 0x8b1
+#define CMP_FRM_CTRL_FLD 0x8b2
+#define CMP_DURATION 0x8b3
+#define CMP_DST_MAC_0 0x8b4
+#define CMP_DST_MAC_1 0x8b5
+#define CMP_DST_MAC_2 0x8b6
+#define CMP_SRC_MAC_0 0x8b7
+#define CMP_SRC_MAC_1 0x8b8
+#define CMP_SRC_MAC_2 0x8b9
@@ -2708,0 +2746 @@
+ mov 0, [SHM_CSI_COPIED]
@@ -2853,0 +2892,222 @@
+#define SPIN_LENGTH (6 + 16)
+#define SPARE1 r54
+spin_rx_header:
+ jext COND_RX_COMPLETE, spin_rx_end
+ jl SPR_RXE_FRAMELEN, SPIN_LENGTH, spin_rx_header
+spin_rx_end:
+ jl SPR_RXE_FRAMELEN, SPIN_LENGTH, skip+
+ mov 0, r55
+ mov [CMP_FRM_CTRL_FLD], SPARE1
+ jne [3,off1], SPARE1, skip+
+ mov [CMP_DURATION], SPARE1
+ jne [4,off1], SPARE1, skip+
+ mov [CMP_DST_MAC_0], SPARE1
+ jne [5,off1], SPARE1, skip+
+ mov [CMP_DST_MAC_1], SPARE1
+ jne [6,off1], SPARE1, skip+
+ mov [CMP_DST_MAC_2], SPARE1
+ jne [7,off1], SPARE1, skip+
+ mov [CMP_SRC_MAC_0], SPARE1
+ jne [8,off1], SPARE1, skip+
+ mov [CMP_SRC_MAC_1], SPARE1
+ jne [9,off1], SPARE1, skip+
+ mov [CMP_SRC_MAC_2], SPARE1
+ jne [10,off1], SPARE1, skip+
+ mov 1, r55
+ jext COND_RX_COMPLETE, skip+
+ jne [SHM_CSI_COLLECT], 1, skip+
+ and SPR_RXE_PHYRXSTAT0, 0x3, SPARE1
+ jne r23, 0x0, localskip+
+ add [0x8bd], 1, [0x8bd]
+localskip:
+ jne r23, 0x1, localskip+
+ add [0x8be], 1, [0x8be]
+localskip:
+ jne r23, 0x2, localskip+
+ add [0x8bf], 1, [0x8bf]
+localskip:
+ or [8,off1], 0x0, [RX_HDR_NEXMON_SrcMac0]
+ or [9,off1], 0x0, [RX_HDR_NEXMON_SrcMac1]
+ or [10,off1], 0x0, [RX_HDR_NEXMON_SrcMac2]
+ je r23, 0x0, skip+
+ mov RX_HDR_BASE + RX_HDR_LEN, SPARE1
+ mov RX_HDR_BASE + (17 * RX_HDR_LEN), SPR_BASE5
+erase_hdr:
+ mov 0x0, [0x00,off5]
+ sub SPR_BASE5, 0x1, SPR_BASE5
+ jges SPR_BASE5, SPARE1, erase_hdr-
+ phy_reg_write(0x00d,73)
+ mov 0, SPARE1
+ mov (RX_HDR_BASE + RX_HDR_LEN), SPR_BASE5
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 15, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 30, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 45, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 60, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 75, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 90, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 105, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 120, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 135, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 150, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 165, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 180, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 195, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 210, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 225, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 240, repeat-
+ or 2, 0x0, [0, off5]
+ or 15, 0x0, [1, off5]
+ add SPR_BASE5, 2, SPR_BASE5
+repeat:
+ phy_reg_write(0x00e, SPARE1)
+ phy_reg_read_to_shm_off(0x00f, 0, off5)
+ phy_reg_read_to_shm_off(0x010, 1, off5)
+ add SPR_BASE5, 2, SPR_BASE5
+ add SPARE1, 1, SPARE1
+ jl SPARE1, 255, repeat-
+ mov 1, [SHM_CSI_COPIED]
+skip:
@@ -3491,0 +3752 @@
+ je r55, 1, skip+
@@ -3492,0 +3754,3 @@
+ jne [SHM_CSI_COLLECT], 1, skip+
+ jmp L720
+skip:
@@ -3530,0 +3795,40 @@
+ mov RX_HDR_BASE, SPR_RXE_RXHDR_OFFSET
+ or 0, 0x0, [SHM(0x1182)]
+ jne [SHM_CSI_COPIED], 1, skip+
+ or 17, 0x0, [SHM(0x1182)]
+skip:
+ calls L798
+ jne [SHM_CSI_COPIED], 1, skip+
+ mov RX_HDR_BASE + RX_HDR_LEN, SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (2 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (3 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (4 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (5 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (6 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (7 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (8 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (9 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (10 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (11 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (12 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (13 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (14 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (15 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (16 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
+ calls L798
+ mov RX_HDR_BASE + (17 * RX_HDR_LEN), SPR_RXE_RXHDR_OFFSET
@@ -3531,0 +3836 @@
+skip:
@@ -4474,2 +4779 @@
- mov 0x840, SPR_RXE_RXHDR_OFFSET
- mov 0xE, SPR_RXE_RXHDR_LEN
+ mov RX_HDR_LEN, SPR_RXE_RXHDR_LEN