<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leon</title>
    <description>The latest articles on DEV Community by Leon (@cynostial).</description>
    <link>https://dev.to/cynostial</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122046%2Fefda37f9-11aa-493d-9993-668d733a2b26.jpg</url>
      <title>DEV Community: Leon</title>
      <link>https://dev.to/cynostial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cynostial"/>
    <language>en</language>
    <item>
      <title>I Reverse Engineered Snapchat Spectacles 2 and Built My Own iPhone App</title>
      <dc:creator>Leon</dc:creator>
      <pubDate>Sat, 12 Sep 2026 10:50:39 +0000</pubDate>
      <link>https://dev.to/cynostial/i-reverse-engineered-snapchat-spectacles-2-and-built-my-own-iphone-app-36l2</link>
      <guid>https://dev.to/cynostial/i-reverse-engineered-snapchat-spectacles-2-and-built-my-own-iphone-app-36l2</guid>
      <description>&lt;p&gt;I had a pair of Snapchat Spectacles 2 sitting around that I wanted to use again.&lt;/p&gt;

&lt;p&gt;The hardware still worked perfectly fine. The problem was the software.&lt;/p&gt;

&lt;p&gt;So I decided to figure out how the glasses actually communicate with a phone and build my own client.&lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;Malibu&lt;/strong&gt;: an open-source iPhone app that can pair directly with Spectacles 2 and import their videos without a Snapchat account or cloud service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Cynostial/malibu" rel="noopener noreferrer"&gt;https://github.com/Cynostial/malibu&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It started as a Windows probe
&lt;/h2&gt;

&lt;p&gt;I didn't start by building an iOS app.&lt;/p&gt;

&lt;p&gt;The first goal was simply to understand what the glasses were doing.&lt;/p&gt;

&lt;p&gt;Bluetooth advertisements exposed a pairing marker, and looking at the GATT services revealed a BLE service with UART-like characteristics. From there, I started capturing packets and figuring out the command framing.&lt;/p&gt;

&lt;p&gt;Eventually I found that the protocol wasn't just a simple collection of Bluetooth commands.&lt;/p&gt;

&lt;p&gt;There was an actual pairing and authentication protocol underneath it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse engineering the pairing protocol
&lt;/h2&gt;

&lt;p&gt;After inspecting the old client and comparing it with packet captures, I found that Spectacles 2 use protobuf messages for commands and media metadata.&lt;/p&gt;

&lt;p&gt;The pairing process includes an &lt;strong&gt;X25519 key exchange&lt;/strong&gt;, a proof exchange, and an &lt;strong&gt;AES-GCM encrypted session&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Getting this right was probably the most interesting part of the project.&lt;/p&gt;

&lt;p&gt;It wasn't enough to identify the cryptography being used. Things like nonce ordering, message layout, key inputs, and byte ordering all had to match what the glasses expected exactly.&lt;/p&gt;

&lt;p&gt;I reproduced the protocol in Python first so I could test it independently before trying to implement everything inside an iPhone app.&lt;/p&gt;

&lt;p&gt;Once I could reliably authenticate with the glasses, the rest of the system started opening up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bluetooth is only half of it
&lt;/h2&gt;

&lt;p&gt;Spectacles don't actually transfer the videos over Bluetooth.&lt;/p&gt;

&lt;p&gt;BLE handles things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;discovery&lt;/li&gt;
&lt;li&gt;pairing&lt;/li&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;controlling the glasses&lt;/li&gt;
&lt;li&gt;starting their Wi-Fi network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the actual media transfer, the glasses create their own private Wi-Fi access point.&lt;/p&gt;

&lt;p&gt;The iPhone joins that network and talks directly to a media service running on the glasses. Malibu can then retrieve the media catalogue, thumbnails, and MP4 data.&lt;/p&gt;

&lt;p&gt;So the basic architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iPhone
  |
  | Bluetooth LE
  | pairing / authentication / Wi-Fi control
  v
Spectacles 2
  |
  | private Wi-Fi
  | thumbnails / MP4 data
  v
Malibu
  |
  v
Photos / Files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything happens locally.&lt;/p&gt;

&lt;p&gt;There is no Malibu server in the middle and no account required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it feel like a normal iPhone app
&lt;/h2&gt;

&lt;p&gt;Reverse engineering the protocol was one problem.&lt;/p&gt;

&lt;p&gt;Making the result pleasant to actually use was another.&lt;/p&gt;

&lt;p&gt;I didn't want the workflow to be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Settings.&lt;/li&gt;
&lt;li&gt;Manually connect to some Wi-Fi network.&lt;/li&gt;
&lt;li&gt;Return to the app.&lt;/li&gt;
&lt;li&gt;Import.&lt;/li&gt;
&lt;li&gt;Repeat every time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On modern iOS, Malibu uses Apple's &lt;code&gt;AccessorySetupKit&lt;/code&gt; to authorize the Spectacles as a Bluetooth and Wi-Fi accessory.&lt;/p&gt;

&lt;p&gt;After the first pairing, Malibu can authenticate with the glasses, ask them to start their saved private network, join it, and begin importing videos automatically.&lt;/p&gt;

&lt;p&gt;If a connection drops in the middle of a download, the app can establish a new encrypted media session and resume the partial transfer rather than downloading the entire video again.&lt;/p&gt;

&lt;p&gt;Imported videos can be stored inside Malibu, accessed through Files, and optionally copied into Photos.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fun part
&lt;/h2&gt;

&lt;p&gt;There's something very satisfying about taking hardware that has become difficult to use because of its original software and making it useful again.&lt;/p&gt;

&lt;p&gt;The camera was still there.&lt;/p&gt;

&lt;p&gt;The Bluetooth radio was still there.&lt;/p&gt;

&lt;p&gt;The Wi-Fi radio was still there.&lt;/p&gt;

&lt;p&gt;The glasses could still record video.&lt;/p&gt;

&lt;p&gt;They just needed something that understood how to talk to them.&lt;/p&gt;

&lt;p&gt;Now they do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Malibu is open source
&lt;/h2&gt;

&lt;p&gt;The project is still experimental. I've currently verified it with a 2018 Spectacles 2 Sapphire unit, so I'd especially love to hear from anyone who still owns another Spectacles 2 model or firmware version and wants to test it.&lt;/p&gt;

&lt;p&gt;I've also documented the reverse-engineered protocol, including the message framing, pairing flow, cryptographic derivation, media protocol, and the parts I still don't understand.&lt;/p&gt;

&lt;p&gt;If you're interested in Bluetooth, iOS, reverse engineering, abandoned hardware, or just making old gadgets useful again:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Cynostial/malibu" rel="noopener noreferrer"&gt;https://github.com/Cynostial/malibu&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feedback and contributions are very welcome.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>reverseengineering</category>
      <category>ios</category>
      <category>bluetooth</category>
    </item>
  </channel>
</rss>
