I've googled quite a bit and did not find an answer to the problem. You'll get a lot of
hits on the subject though and most people tell it cannot be done. In Tiger the following one liner worked like a charm:
ifconfig en0 ether AA:BB:CC:DD:EE:FF
But in Leopard not anymore. Or at least not for the wired (Ethernet) network adapter. The above method still
works for the Wi-Fi interface though, but that's not much of a solace to most of us.
The solution is quite easy to guess and pretty easy to do: simply replace the network driver of Leopard with the one of Tiger.
Now this is not for the faint of heart, so make sure you know what you're doing. You know the drill: I'll not take any responsibility for any harm that you might cause yourself (or your Mac) by following the instructions below ... In case you're in doubt whether you could recover your OS if something goes wrong: don't even start messing around. You've been warned.
It's not that hard to crash your Mac by messing around with kernel extensions, so be careful.
I should also tell in advance that I'm sharing here a lot more information than what is absolutely necessary to replace the Leopard ethernet driver with the one from Tiger. I'm doing so to share all the knowledge that is needed to understand what we're doing. Creating a set of instructions (ie. a list of commands) that would work for all possible instances of Mac OS X is beyond my scope. It'd be almost impossible to achieve (since Mac OS X is a "closed" system, I mean a lot of information about the OS was not made public by Apple) and providing you with the know-how benefits you a lot more in the long term.
I should mention that I've an Intel-based MacBook Pro (Model number: A1211) and I've Leopard v10.5.6 running (at the moment). The former is important, because the NIC depends on the Mac's type and model (ie. version). I've a Marvell 88E8053 PCI-E Gigabit Ethernet Controller (also called "Yukon-2") with a PCI ID of 11ab:4362. You can determine your NIC's model using the
lspci
command from
OSx86 Tools.
I don't have any information on whether MAC spoofing was disabled only for the Yukon-2 NICs or all NICs supported in Leopard. I assume this did not happen by chance and probably all NICs (drivers) are affected, but of course I could be wrong. Please, share your experiences if you know about MAC "spoofability" of NICs other than the Yukon-2. Anyway, I try to be generic in this article so owners with all sorts of hardware can adopt the process to their own Mac.
It's quite important that you know the PCI device vendor ID and device ID of your NIC. If you do not want to install OSx86 Tools, there's a way to find out what driver your OS X is using from the I/O Kit Networking Family bundle (
/System/Library/Extensions/IONetworkingFamily.kext
kernel extension). I've prepared a small shell script snippet to compare the list of plugins (
/System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns
) with the list of loaded kernel extensions that you can get by running
kextload -l
. The script works on my Leopard setup with the default Bash shell (
/bin/sh
) and also with the Z shell (
/bin/zsh
), but of course there's no guarantee that it will work flawlessly (out-of-the-box) for you too. Try and see if it does:
echo "List of loaded IONetworkingFamily plugins:"; for kext in /System/Library/Extensions/IONetworkingFamily.kext/Contents/Plugins/*.kext; do
awk 'BEGIN {cfname = ""; cfid = ""} /<key> *CFBundle(Identifier|Name) *<\/key>/ {getline value; sub(".*<string> *", "", value); sub(" *</string>.*", "", value); if (index($0, "CFBundleName") > 0) {cfname=value} else {cfid=value}; if (cfname != "" && cfid != "") {exit} } END {print cfname "#" cfid}' $kext/Contents/Info.plist | (
IFS=# read cfname cfid
kextstat -l | fgrep -qis "$cfid" && echo " extension name: $(basename $kext)\n bundle name: $cfname"
)
done
If the script does not work, either fix it or do the script's job manually (ie. get a list of driver bundle identifiers -CFBundleIdentifier- from the
Contents/Info.plist
files inside the various driver directories in
/System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns
, then get the intersection of this list and the bundle IDs in the loaded kernel extension list from the output of
kextload -l
).
Unfortunately this way you still have only the driver that your OS X (Leopard) is using at the moment. So let's consider the above two paragraphs as a little scripting exercise.
There's no guarantee that the driver for your NIC had the same name in Tiger as it has in Leopard. Eg. in my case in Leopard the Yukon-2 NIC (PCI ID "11ab:4362") driver is named "AppleYukon2". However in Tiger there is both an "AppleYukon" and an "AppleYukon2" driver! And moreover: in Tiger my NIC used the AppleYukon driver, while in Leopard the AppleYukon2 (in Leopard there's no "AppleYukon" ... it seems all Yukon devices are now supported by the AppleYukon2 driver). To be absolutely sure, we've to know the PCI ID of the NIC. There're a number of ways to get the IDs of your PCI devices:
- You can use the already mentioned OSx86 Tools. I've tested it and worked (at least for me). It contains a binary of lspci that is part of PCI Utilities. Note that OSx86 Tools installs a kext and requires a reboot to be able to list/access your PCI devices.
- You can use a utility named DPCI Manager. I've tested it and worked. It's a lot more simple than OSx86 Tools. Seems like a proof-of-concept application: the developer did not bother to polish the edges. Eg. the app's about menu item is called "About NewApplication". The app presents a single window titled "Window". There's a list of PCI devices in this window with three columns containing: PCI IDs, Vendor names and device names. The window has a button labelled "Button", which seems to do nothing. But I've to admit: it does what we need right now. You can read out the PCI ID of your NIC. And it seems not to use any extra kext (at least it did not ask me to install one) and thus no reboot is required.
- You can use a Mac port of PCI Utilties. The official site states that the developer has abandoned the project and that the binaries and source are available through this forum post.
- You can parse the output of the
ioreg
command that is shipped with Mac OS X.
As for the latter, here's what to do:
Now let us get the Tiger drivers.
You've a couple of options here too:
- You can decide to replace your whole ethernet driver package (
/System/Library/Extensions/IONetworkingFamily.kext
) with the Tiger variant. I've done this and it worked well for me.
- Or you can replace only the driver of your NIC. This might not work, I've not tested it.
You may select the strategy based on what sources you've available too. To replace the whole IONetworkingFamily.kext, you'll need an original Tiger install DVD (only Disc#1). To replace just the driver (the IONetworkingFamily.kext plugin) with the Tiger version, you've to know which Leopard network driver to replace and with which Tiger driver. Here comes the PCI ID into the game: you can find the proper Tiger driver by looking for the PCI ID in the
Contents/Info.plist
files of the various drivers (IONetworkingFamily.kext plugins). The PCI ID can have a number of forms in these files. Check out
this page for a list of possible formats to look for. If you've got both driver names, then back up the original driver of your NIC and extract the Tiger driver from the Tiger update DMG of your choice. Instructions on these will follow later.
I've chosen to go with method#1, thus replacing the complete IONetworkingFamily.kext with the Tiger variant. My install DVD contains 10.4.10 of Mac OS X Tiger. This is important since the NIC driver might have got updated in later Tiger versions (updates). There's a list of various Tiger versions at
Wikipedia. You'll also find in this list a link to the download page of all these updates. I've downloaded each of them (starting with 10.4.1 and ending with 10.4.11) and made a list of the updated network drivers (ie. IONetworkingFamily plugins) in each version:
- 10.4.3: AppleBCM5701Ethernet.kext, AppleGMACEthernet.kext
- 10.4.6: AppleYukon.kext
- 10.4.7: AppleYukon.kext
- 10.4.8: AppleBCM5701Ethernet.kext, AppleIntel8254XEthernet.kext, AppleYukon.kext
- 10.4.9: AppleBCM5701Ethernet.kext, AppleIntel8254XEthernet.kext, AppleYukon.kext, AppleYukon2.kext
- 10.4.10: AppleIntel8254XEthernet.kext
- 10.4.11: AppleIntel8254XEthernet.kext, AppleYukon.kext
The complete list of Tiger IONetworkingFamily drivers is this:
- Apple3Com3C90x.kext
- AppleBCM440XEthernet.kext
- AppleBCM5701Ethernet.kext
- AppleBMacEthernet.kext
- AppleDP83816Ethernet.kext
- AppleGMACEthernet.kext
- AppleIntel8254XEthernet.kext
- AppleIntel8255x.kext
- AppleRTL8139Ethernet.kext
- AppleRTL8169Ethernet.kext
- AppleYukon.kext
- AppleYukon2.kext
- Apple_DEC21x4Ethernet.kext
So the following drivers never got an update:
- Apple3Com3C90x.kext
- AppleBCM440XEthernet.kext
- AppleBMacEthernet.kext
- AppleDP83816Ethernet.kext
- AppleIntel8255x.kext
- AppleRTL8139Ethernet.kext
- AppleRTL8169Ethernet.kext
- Apple_DEC21x4Ethernet.kext
These kexts are not officially (ie. from Apple) and publicly available and downloadable, so you can get them only from an install DVD.
In my case the AppleYukon.kext got the following updates (I list the Tiger update version and the AppleYukon driver version):
- 10.4.6: 1.0.2b9
- 10.4.7: 1.0.6b4
- 10.4.8: 1.0.7b3
- 10.4.9: 1.0.11b2
- 10.4.11: 1.0.12b1
My Tiger install DVD (since it's v10.4.10) contains AppleYukon v1.0.11b2 and in Tiger v10.4.11 an update came out. So I've fetched the complete IONetworkingFamily.kext from the install DVD and updated it with the IONetworkingFamily.kext from the 10.4.11 update.
Now let's assume you've your Tiger install DVD mounted under "/Volumes/Mac OS X Install Disc 1".
Here're the commands to back up your current IONetworkingFamily.kext and extract the Tiger version from the DVD:
sudo -s
cd /System/Library
mkdir Extensions.Backup
mv Extensions/IONetworkingFamily.kext Extensions.Backup/IONetworkingFamily.kext.original
cd /
cpio -izd "./System/Library/Extensions/IONetworkingFamily.kext*" < "/Volumes/Mac OS X Install Disc 1/System/Installation/Packages/Essentials.pkg/Contents/Archive.pax.gz"
touch /System/Library/Extensions
The last line regenerates the extensions cache (see
man kextcache
for details).
The file permissions should be OK after the
cpio
extraction, however if you want to go for sure, you can run the following to "reset" the permissions to what they should be:
sudo -s
chown -R root:wheel /System/Library/Extensions/IONetworkingFamily.kext
chmod -R u=rwX,go=rX /System/Library/Extensions/IONetworkingFamily.kext
ls -lR /System/Library/Extensions/IONetworkingFamily.kext
Now as I said: I've updated the IONetworkingFamily.kext with the one from the
Tiger v10.4.11 update (Intel version).
If you assume the DMG is mounted under
/Volumes/Mac OS X 10.4.11 Update (Intel)
, you can extract the needed files from the update with a command like this:
sudo -s
cd /
cpio -izd "./System/Library/Extensions/IONetworkingFamily.kext*" < "/Volumes/Mac OS X 10.4.11 Update (Intel)/MacOSXUpd10.4.11Intel.pkg/Contents/Archive.pax.gz"
touch /System/Library/Extensions
Of course the various
sudo -s
commands are not needed in every block
... I've added them only to make each command block work independently whether they are executed following any of the others.
Now we're almost at the end of the article.
Reboot and test whether your ethernet driver is still working. If not, here's how to restore your original driver:
sudo -s
cd /System/Library
rm -rf Extensions/IONetworkingFamily.kext
cp -pR Extensions.Backup/IONetworkingFamily.kext.original Extensions/IONetworkingFamily.kext
touch Extensions
I hope you remember how I started the article: you've to be able to restore your OS into a pre-hacking state yourself. I'll not provide any help on this so do not even ask.
But let's assume it worked and your network device is still working.
Test the MAC spoofing by first querying the current MAC address (I assume your ethernet device is
en0
):
ifconfig en0 | fgrep -i ether
Now try to set it to something else:
ifconfig en0 lladdr aa:bb:cc:dd:ee:ff
And check whether the MAC really changed:
ifconfig en0 | fgrep -i ether
Hopefully it did. At least it did for me.
That's all. One more thing to remember: a later OS update might replace your IONetworkingFamily.kext completely or partially.
If it's replaced completely, then you'll just loose your MAC spoofing ability. No problem: you can keep a backup of your "MAC spoofable" IONetworkingFamily.kext in /System/Library/Extensions.Backup and revert to it in case it's needed.
However I do not know what happens if IONetworkingFamily.kext is only updated (this is what happens usually).
In my case the NIC driver for Tiger is AppleYukon.kext, while for Leopard it's AppleYukon2. So right now (with the Tiger "patch") I've only an AppleYukon.kext in
/System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns
and no AppleYukon2.kext. But what if a Leopard update deploys a new version of AppleYukon2.kext?
There'll be two drivers that support my NIC (based on PCI ID). Based on
this topic at InsanelyMac OS X loads every (?) kext that supports a given PCI device:
"OSX keeps a list of all vendor id's and device id's that are contained in the kexts installed in the system. When the computer is booted, OSX quizzes the ROM on each device to get its vendor and device id's. Then it uses its list to see if a match exists, and if it does, it binds the kext (driver) to that device."
Or does maybe the kext loader have enough IQ to load for each PCI device only one kext?
If not, what happens if two kernel extensions (IONetworkingFamily plugins) are loaded for the same ethernet device? Maybe OS X crashes on boot? I haven't tested this yet, but even if that's the case, you can always boot from your Leopard Install DVD and restore your original IONetworkingFamily.kext (I assume you can have some sort of terminal in recovery mode).
Update:
I've tested what happens if you just copy the AppleYukon.kext from Tiger's (v10.4.11) IONetworkingFamily.kext into Leopards
/System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns
directory: absolutely nothing.
The system will not even load the AppleYukon.kext and it'll still use the AppleYukon2.kext driver. The explanation takes a bit longer. The IONetworkingFamily.kext is not just some "wrapper" around its PlugIns directory. The IONetworkingFamily binary inside
IONetworkingFamily.kext/Contents/MacOS
is responsible (AFAIK) for actually selecting and loading the proper driver for your NIC. And there's a significant difference between the IONetworkingFamily "loader" of Tiger and Leopard: the latter accepts only plugins (drivers) that have various Code* files (namely: CodeDirectory, CodeRequirements, CodeResources, CodeSignature) in their
Contents
subdirectory. The existence of these files means that the given kernel extension has been
signed. Obviously singing kexts is not compulsory since in
/System/Library/Extensions
there're 349 signed ones and 84 unsigned ones (on my MBP). However Leopard's IONetworkingFamily.kext seems to demand from its plugins to be signed (at least all of Leopard's plugins are signed and my experiment shows that unsigned plugins are ignored). We could probably sign Tiger's AppleYukon driver (with a self-signed certificate that we put into OSX's trusted certificates store) and use this self-signed driver with Leopard's IONetworkingFamily, but imho it's not worth the trouble. It's a lot easier to just use Tiger's IONetworkingFamily.kext instead.
I've also tested the other way around: if you replace Leopard's IONetworkingFamily.kext with Tiger's and copy Leopard's AppleYukon2 driver over into the PlugIns directory (overwriting Tiger's AppleYukon2.kext), then IONetworkingFamily will load both kexts (a
kextstat -l | grep -i yukon
will confirm that), but it'll select and bind the AppleYukon2 driver (the one from Leopard) to the NIC.
These tests confimed that if a Leopard update would replace the complete IONetworkingFamily.kext or just the AppleYukon2.kext plugin, then your Mac would still boot. The worst that can happen is that OS X loads the AppleYukon2 driver and you loose the ability to spoof any MAC addresses.
And finally here's the answer to my own question: if there're two drivers supporting the same PCI ID, both are loaded by IONetworkingFamily, but only one is used (bound). No crash, no problems. OS X proved itself again.
I hope this post'll help a few people in making MAC spoofing work in a lot shorter time than it took me.
(Of course I did a lot of extra "research" to make this article as complete as possible, but the readers will most probably appreciate it.)
P.S.: I hope I've not made any typos in the commands, but since I'm "just" human
, I make mistakes. Please, let me know if you find any typos (mainly in the command listings, but I'm glad for any feedback regarding the whole article).
P.S.2: many have reported that MAC spoofing _does_ work in Leopard with older Macs (like PowerBooks, etc.). Maybe only MacBook Pros are affected and maybe it's only because the Marvell Yukon drivers prohibit it (and other NIC drivers permit).
Important:
I just had a crash (
early this morning, 2009-03-01) with my Mac. Of course it could have happened for any number of reasons, but since I never had a crash before and not much has changed recently, I guess something among the changed things is reponsible for the crash. Eg. one of the changes was the replacement of the Leopard Ethernet drivers with the ones from Tiger. I had no issues with this hack for a month, but this crash might just be related. And the trigger might have been a higher than usual download speed (2 MB/s) over the Ethernet network port. Of course I'm just guessing. I could not reproduce the issue later on and to be on the safe side, I've put back the Leopard drivers. I remember having read that some people had stability issues (crashes) with certain versions (and hw configurations) of the Ethernet drivers and higher network loads. I just might have hit this old bug with the old drivers. I guess I'll never find out. Fortunately I don't need MAC spoofing all the time. It was just one short experiment that I needed it for, so I can revert back to the Leopard drivers without any problem.
Comments
great post
There must be something special about the Marvell Yukon drivers under Leopard because my MacBookPro when booted under XP changes the MAC without complaint.
Also, I am not able to change the MAC address on a USB-to-Ethernet dongle (uses en4, com.apple.driver.AppleUSBEthernet). Perhaps Apple has requested all ethernet drivers to disallow MAC spoofing??
Re: great post
if your wireless stops working...
I got it to work by copying the Tiger version of IO80211Family.kext too. now both wireless and wired ethernet work, and wired allows spoofing (wireless already allowed spoofing for some reason..)
I didn't bother with applying the updates, since my Tiger DVD is only 10.4.8 and it seemed like it would be tough to get it up to 10.4.11...
Re: if your wireless stops working...
spoke too soon
for now, i'm reverting back to non-spoofable stable configuration. bummer.
Re: spoke too soon
AppleYukon2 Drivers
Nice post, I just have one problem. My McBook came with Leopard, so I don't have the Tiger DVD to get the driver. Is there a problem if I only copy the folder from the update?
[]s
same issue...
Re: same issue...
IONetworkingFamily.kext/Contents/PlugIns
subfolder (from the Tiger update DMG), you need the fullIONetworkingFamily.kext
package. If I remember well, the updates did not contain the wholeIONetworkingFamily.kext
package, but only parts of it.