Spoofing the MAC address on Airport Extreme cards (dynamic method)

Posted by Stefan on Tue 19 Apr 2005 at 16:00 (updated: Mon 1 Aug 2005 at 13:00)

NOTE:The dynamic method cannot work on the Tiger patch versions because the gWLC struct changed

Recently I bought my first Apple Macintosh. a small 12" iBook which comes with an Airport Extreme wireless lan card, which is based on the Broadcom Airforce (BCM4306) chipset. Unfortunately there is not much information about this chipset in the open source world and the drivers from Broadcom neither support MAC address changing nor passive mode.

Because of this problem I decided to patch the original Broadcom binary driver and add the functionality it misses, or simply does not export to the outside world. My first step, adding the possibility for MAC address spoofing to the driver is described here. Unfortunately some things still don't work, but I am convinced that these problems can be solved within the next weeks.

I am new in the whole Mac and PPC world, so please forgive me my strange PPC assembly language and don't hesitate to contact me if you find a problem.

If you want to use a method that has for now less problems have a look at Spoofing the MAC address on Airport Extreme cards (static method)

If you are looking for a way to use passive RFMON mode on your Apple AirPort Extreme card please note that my work on this project is stalled until july for personal reasons.

Setting up...

I strongly suggest not to experiment with the original drivers in /System/Library/Extensions/AppleAirPort2.kext atleast until you made sure that everything works as you want. Therefore you should first create a copy of the driver into a test environment and create a copy of the driver file that you specially prepare.

base:/Users/spoofer root# cp -pR /System/Library/Extensions/AppleAirPort2.kext .
base:/Users/spoofer root# cp AppleAirPort2.kext/Contents/MacOS/AppleAirPort2 AppleAirPort2-prepared

Preparing the binary driver

For now there is no automatic installation tool and therefore you have to patch the driver binary with a hex editor of your choice. The following values are specific to the mentioned versions of the driver:

AppleAirPort2-prepared
----------------------
 - version: 3.4.4f5 (3.50.37.p4)
 - size:    640352 bytes
 - md5:     3860545266b554d2955664db55452f5a

 - version: 3.4.2b1 (3.50.37.p4)
 - size:    638472 bytes
 - md5:     1739c357ade1d04c9be47e8604afb1c2
 
 - version: 3.5f1 (3.50.37.p6)
 - size:    642668 bytes
 - md5:     b6f3d2437c40277c197f0afcf12208e9
 
 - version: 400.17 (3.90.34.0.p11)
 - size:    732244 bytes
 - md5:     06c01eaad557bbb9386f93369ec0ee6e

Now all you need todo is to rename one symbol, so that we can replace it's functionality with our own implementation in setHardwareAddress.s and patch the original binary in a way that three symbols get exported.

Open the file in a hex editor and search for __ZN20IOEthernetController18setHardwareAddressEPK17IOEthernetAddress. Replace this string with __ZN10AirPortPCI18setHardwareAddressEPK17IOEthernetAddress and pad the end with zero bytes.

Now export the following three symbols by searching for the byte pattern and replacing it with the patched one. If you have a different binary driver this will not work for you and you must either use some mach-o information tool to find the correct positions or wait until I release an automatic installer (haha).

Version: 3.4.4f5 (3.50.37.p4)
Symbol         Pattern        Replace
_gWLC:         AF 33 0E 07 -> AF 33 0F 07
_wlc_set_mac:  9A 7A 0E 01 -> 9A 7A 0F 01
_myMacAddr:    B2 00 0E 07 -> B2 00 0F 07

Version: 3.4.2b1 (3.50.37.p4)
Symbol         Pattern        Replace
_gWLC:         AF 22 0E 07 -> AF 22 0F 07
_wlc_set_mac:  9A 69 0E 01 -> 9A 69 0F 01
_myMacAddr:    B1 67 0E 07 -> B1 67 0F 07

Version: 3.5f1 (3.50.37.p6)
Symbol         Pattern        Replace
_gWLC:         AF AB 0E 07 -> AF AB 0F 07
_wlc_set_mac:  9A FE 0E 01 -> 9A FE 0F 01
_myMacAddr:    B2 A8 0E 07 -> B2 A8 0F 07

Compiling/Linking

After you have prepared the binary driver in the way described above you can link the new functionality into the driver by executing the following commands.

base:/Users/spoofer root# gcc -c setHardwareAddress.s
base:/Users/spoofer root# ld -r AppleAirPort2-prepared setHardwareAddress.o -o AppleAirPort2.kext/Contents/MacOS/AppleAirPort2

Testing

After having patched and linked everything together you can now test if everything works by

base:/Users/spoofer root# kextunload AppleAirPort2.kext
kextunload: unload kext AppleAirPort2.kext succeeded
...
base:/Users/spoofer root# kextload AppleAirPort2.kext
kextload: AppleAirPort2.kext loaded successfully
...
...
base:/Users/spoofer root# ifconfig en1 up
base:/Users/spoofer root# ifconfig en1 lladdr 00:11:22:33:44:55
base:/Users/spoofer root# ifconfig en1 down
base:/Users/spoofer root# ifconfig en1 up

For now it seems that WEP 64/128 and open authentification modes work with the spoofed MAC, with the only known limitation, that the DHCP requests leak the original MAC.

Known Problems/Limitations

Download

Because this whole is a more or less ugly hack of the original binary driver I cannot give you a download of the full package. You have to do the whole patching process on your own. I can only give you a download link of the added code:

alternatively you can copy the file from here:

setHardwareAddress.s

.text

.globl __ZN10AirPortPCI18setHardwareAddressEPK17IOEthernetAddress

__ZN10AirPortPCI18setHardwareAddressEPK17IOEthernetAddress:

	; on entry r3=this, r4=pointer to mac_addr
	mflr    r0
	stw     r0, 8(r1)
	stw     r28, -4(r1)
	stwu    r1, -0x80(r1)

	mr      r28, r3
	mr      r3, r4

	; Copy the MAC Address into the gWLC struct
	lis     r4, ha16(_gWLC)
	lwz     r4, lo16(_gWLC)(r4)
	lwz     r5, 0(r3)
	stw     r5, 12(r4)
	lwz     r5, 2(r3)
	stw     r5, 14(r4)
	; and into another place (not needed?)
	lis     r4, ha16(_myMacAddr)
	ori     r4, r4, lo16(_myMacAddr)
	lwz     r5, 0(r3)
	stw     r5, 0(r4)
	lwz     r5, 2(r3)
	stw     r5, 2(r4)

	; Prepare the string 'IOMACAddress' on stack
	; for setting the Property of the AirPort
	; Extreme driver. This is responsible for
	; showing the correct Airport ID in the
	; network configuration dialogs
	lis     r5, 0x494F
	ori     r5, r5, 0x4D41
	stw     r5, 80(r1)
	lis     r5, 0x4341
	ori     r5, r5, 0x6464
	stw     r5, 84(r1)
	lis     r5, 0x7265
	ori     r5, r5, 0x7373
	stw     r5, 88(r1)
	li      r5, 0
	stw     r5, 92(r1)
	addi    r4, r1, 80

	; and call the setProperty function from the
	; objects vtable
	li      r6, 6
	mr      r5, r3
	mr      r3, r28
	lwz     r12, 0(r28)
	lwz     r12, 0x170(r12)
	mtctr   r12
	bctrl

	; Clean stack and return with kIOReturnSuccess
	lwz     r0, 0x88(r1)
	li      r3, 0
	addi    r1, r1, 0x80
	lwz     r28, -4(r1)
	mtlr    r0
	blr

Related Articles

If you find this article interesting you should also have a look at:

Related Sites

If you find this site interesting you should also have a look at: