How to spoof the MAC address in Leopard

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. Smile

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. Wink 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. Smile

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. Wink

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. Smile 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:
  • Run ioreg -l -w 0. It'll print a tree of nodes (ie. "objects", as the manpage refers to them).
  • Look for a node with class=IOEthernetInterface (ie. search for the string "class IOEthernetInterface").
  • The parent (or the "grandparent") of this node should be a reference to the driver your OS is using for the NIC. In my case the grandparent node name was "yukon2osx" (this is the CFBundleSignature from the Info.plist of the AppleYukon2 driver), its "Model" was "Yukon Gigabit Adapter 88E8053 Singleport Copper SA" and its "CFBundleIdentifier" was "com.apple.iokit.AppleYukon2".
  • The parent node of the driver node is the actual ("raw") PCI device (the node has a class="IOPCIDevice" and an IOName="ethernet"). Here you'll find your NIC's PCI ID in the "device-id" and "vendor-id" properties of the node. The usual notation of the PCI ID comes by swapping byte orders in the properties and putting the two together. Eg. in my ioreg output I had these:
    "device-id" = <62430000>
    "vendor-id" = <ab110000>
    And the PCI ID from these is: 4362:11ab
Now let us get the Tiger drivers. Smile 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 Smile ... 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? Shock 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? Shock 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. Smile 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. Smile

I hope this post'll help a few people in making MAC spoofing work in a lot shorter time than it took me. Smile (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 Smile, 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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

great post

Thanks for this post, i can't wait to get home to my Tiger install DVDs to try this out at home.

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

Definitely not. I've read quite a few posts at various forums from people with older models (eg. Powerbooks) who could still change the MAC of the wired ethernet interface in Leopard. I think only the Yukon drivers are affected. This would be worth of a new poll at maxosxhints.com. Wink

if your wireless stops working...

This worked for my ethernet card but had the side affect of causing os x to think i had no wireless card installed anymore.

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...

Thanks for the feedback and the tip. I'm not using the WiFi on a regular basis so I have not noticed the WiFi becoming non-operational.

spoke too soon

ok so while copying IO80211Family.kext from the tiger dvd does fix the "no wireless card installed" issue, it appears that I am still unable to connect to a WPA wireless network - there must be some other piece to this puzzle. maybe a crypto library or something?

for now, i'm reverting back to non-spoofable stable configuration. bummer.

Re: spoke too soon

My Airport interface seems to be OK in Leopard (regardless of using the Ethernet drivers from Tiger). At least System Profiler finds and reports it as an existing/working device. It's turned off though, but that's on purpose (I don't use it so no need to have it turned on Smile ).

AppleYukon2 Drivers

Hi!
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...

I was wondering the same thing - can I just get the relevant files from the update ?

Re: same issue...

Most probably not. It's not enough to copy just the driver from the IONetworkingFamily.kext/Contents/PlugIns subfolder (from the Tiger update DMG), you need the full IONetworkingFamily.kext package. If I remember well, the updates did not contain the whole IONetworkingFamily.kext package, but only parts of it.