Skip to content

Instantly share code, notes, and snippets.

@henrik242
Last active June 30, 2025 02:13
Show Gist options
  • Save henrik242/1da3a252ca66fb7d17bca5509a67937f to your computer and use it in GitHub Desktop.
Save henrik242/1da3a252ca66fb7d17bca5509a67937f to your computer and use it in GitHub Desktop.
Read AirTag data from the FindMy.app cache and convert to GPX
#!/usr/bin/env bash
#
# Reads AirTag data from the FindMy.app cache and converts it to a daily GPX file
#
# Rsyncs the data to a web accessible folder that can be displayed with e.g.
# https://gist.github.com/henrik242/84ad80dd2170385fe819df1d40224cc4
#
# This should typically be run as a cron job
#
set -o pipefail -o nounset -o errexit
export PATH=/usr/local/bin:$PATH
DATADIR=/tmp/airtag-data
TODAY=$(date +%d)
mkdir -p $DATADIR
DATA=$DATADIR/airtagdata-$TODAY.txt
GPX=$DATADIR/airtagdata-$TODAY.gpx
TAGNAME=Foobar
if [[ $(uname -s) == "Darwin" ]]; then
TOMORROW=$(date -v +1d +%d)
else
TOMORROW=$(date --date="tomorrow" +%d)
fi
rm -f $DATADIR/airtagdata-$TOMORROW.gpx
jq -r '.[] | select(.name == "'$TAGNAME'") | .location | "\(.latitude) \(.longitude) \(.altitude) \(.timeStamp/1000 | todate)"' \
$HOME/Library/Caches/com.apple.findmy.fmipcore/Items.data >> $DATA
START='<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:mytracks="http://mytracks.stichling.info/myTracksGPX/1/0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creator="myTracks" version="1.1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
<name>'$TAGNAME'</name>
<extensions>
<mytracks:color red="0.000000" green="0.000000" blue="1.000000" alpha="1.000000" />
<mytracks:area showArea="no" areaDistance="0.000000" />
<mytracks:directionArrows showDirectionArrows="yes" />
<mytracks:sync syncPhotosOniPhone="no" />
<mytracks:timezone offset="120" />
</extensions>
<trkseg>'
END=' </trkseg>
</trk>
</gpx>'
echo $START > $GPX
function elems() {
LAT=$1
LON=$2
ELE=$3
TS=$4
}
cat $DATA | while read line; do
elems $line
echo '<trkpt lat="'$LAT'" lon="'$LON'">
<ele>'$ELE'</ele>
<time>'$TS'</time>
</trkpt>' >> $GPX
done
echo $END >> $GPX
cp $GPX $DATADIR/airtagdata.gpx
rsync -a --exclude='*.txt' $DATADIR example.com:public_html/airtag/
@23tom2323
Copy link

The web archive worked. Thank you.

I'm interested in the code. I'd also like to share my code. What do I do? Do we do this here on GitHub? Directly here?

@henrik242
Copy link
Author

You can just fork this gist :)

@hubert3
Copy link

hubert3 commented Jun 26, 2025

I looked at this a while ago and I believe the encryption key for the Items/Devices.data binary plists may be this item in iCloud Keychain. Keychain Access won't display the value, more research needed on how to dump this:

image

@hubert3
Copy link

hubert3 commented Jun 26, 2025

The Find My app on Mac loads these dylibs and there is code related to decrypting the plist files in them. I got as far as setting breakpoints around where it's doing the decryption but haven't extracted the keys yet.

You can extract the dylibs from the macOS dylib cache using ipsw:

% ipsw dyld extract /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e FindMyCrypto FMFCore FMIPCore -o .

% file *
FindMyCrypto: Mach-O 64-bit dynamically linked shared library arm64e
FMFCore: Mach-O 64-bit dynamically linked shared library arm64e
FMIPCore: Mach-O 64-bit dynamically linked shared library arm64e

Process 33543 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x00007ffb24c14a1a FindMyCrypto`FindMyCrypto.SymmetricKey256.init(from: Swift.Decoder) throws -> FindMyCrypto.SymmetricKey256 + 42
FindMyCrypto`FindMyCrypto.SymmetricKey256.init(from: Swift.Decoder) throws -> FindMyCrypto.SymmetricKey256:
->  0x7ffb24c14a1a <+42>: movq   -0x8(%rax), %rax
    0x7ffb24c14a1e <+46>: movq   %rax, -0x38(%rbp)
    0x7ffb24c14a22 <+50>: movq   0x40(%rax), %rax
    0x7ffb24c14a26 <+54>: callq  0x7ffb24c01630            ; __chkstk_darwin
Target 0: (FindMy) stopped.

* thread #1, queue = 'com.apple.findmy.fmcore.diskio', stop reason = breakpoint 62.1
    frame #0: 0x00007ffb24c05c20 FindMyCrypto`FindMyCrypto.decryptAndValidate(envelope: FindMyCrypto.EncryptAndSignEnvelope, symmetricKey: FindMyCrypto.SymmetricKey256, publicKey: FindMyCrypto.P256PublicKey) throws -> Foundation.Data
FindMyCrypto`FindMyCrypto.decryptAndValidate(envelope: FindMyCrypto.EncryptAndSignEnvelope, symmetricKey: FindMyCrypto.SymmetricKey256, publicKey: FindMyCrypto.P256PublicKey) throws -> Foundation.Data:
->  0x7ffb24c05c20 <+0>: pushq  %rbp
    0x7ffb24c05c21 <+1>: movq   %rsp, %rbp
    0x7ffb24c05c24 <+4>: pushq  %r15
    0x7ffb24c05c26 <+6>: pushq  %r14

@marcelosanchez
Copy link

Yea your right, I have been working on decrypting sequoia Items.data for a while now and can't see how to get the decryption key so giving up for now. I decided to build a bunch of VMs running older Macos version for now (Monterey works great, Sonoma is a bit of a challenge under VirtualBox). Have 5 VMs running under VirtualBox on a Windows PC (16GB memory 2.3Ghz cpu). I am harvesting data on 160 airtags which I feed in to my django server and serve the data via Rest API to my iOS and android app clients. Works well so far. Saves having to buy and maintain a bunch of Macs!

Hi @wilkyconsultants,

Your setup with VirtualBox VMs running Monterey on Windows to collect AirTag data and serve it via Django is exactly what I’d like to replicate.

Would you mind sharing a few more technical details?
• Which version of Windows are you using as the host?
• What are the exact VirtualBox VM settings you used (CPU, RAM, storage, EFI, network, etc.) to get Monterey running stably?
• Which Monterey version worked best for you?
• Any specific steps or advice for enabling and using Find My in the VM, and making sure it works with your Apple ID?
• Did you use a prebuilt macOS image, or build it yourself? If you have a link or reference to the image or guide you used, it would help a lot.
• Any tricky parts or tips you wish you knew before starting?

Any info or resources you can share would be incredibly helpful. Thanks again for sharing your results!

@wilkyconsultants
Copy link

Yea your right, I have been working on decrypting sequoia Items.data for a while now and can't see how to get the decryption key so giving up for now. I decided to build a bunch of VMs running older Macos version for now (Monterey works great, Sonoma is a bit of a challenge under VirtualBox). Have 5 VMs running under VirtualBox on a Windows PC (16GB memory 2.3Ghz cpu). I am harvesting data on 160 airtags which I feed in to my django server and serve the data via Rest API to my iOS and android app clients. Works well so far. Saves having to buy and maintain a bunch of Macs!

Hi @wilkyconsultants,

Your setup with VirtualBox VMs running Monterey on Windows to collect AirTag data and serve it via Django is exactly what I’d like to replicate.

Would you mind sharing a few more technical details? • Which version of Windows are you using as the host? • What are the exact VirtualBox VM settings you used (CPU, RAM, storage, EFI, network, etc.) to get Monterey running stably? • Which Monterey version worked best for you? • Any specific steps or advice for enabling and using Find My in the VM, and making sure it works with your Apple ID? • Did you use a prebuilt macOS image, or build it yourself? If you have a link or reference to the image or guide you used, it would help a lot. • Any tricky parts or tips you wish you knew before starting?

Any info or resources you can share would be incredibly helpful. Thanks again for sharing your results!

happy to share all but can't dump my versions of software until jul 4 cuz i am at my cottage til then and servers are at home, didn't set up remote access so don't recall versions.attached is my ecosystem for Mr Tracker (my app for airtags).
mrtracker

@marcelosanchez
Copy link

happy to share all but can't dump my versions of software until jul 4 cuz i am at my cottage til then and servers are at home, didn't set up remote access so don't recall versions.attached is my ecosystem for Mr Tracker (my app for airtags).

Thanks so much for being willing to share your setup—your info will definitely help me and others!

Your diagram is very similar to what I have, but I’m still limited by physical Mac minis, so I can’t scale like you do with VMs. Any details you share when you’re back will be super helpful.

Really appreciate your openness!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment