HK Invoke necromancy
I have a Harman Kardon Invoke. If you don’t remember it, it was the Cortana speaker built by Harman Kardon. It actually sounds great. Then Microsoft pulled the plug on Cortana, and Harman shipped one last update that removed Cortana and nerfed it to be a meh bluetooth speaker that needed pairing every time you wanted to use it. All the wifi, touch buttons, microphones were left to waste.
There were some people trying to reverse engineer it / root it HKHacking but I don’t think they got too far.
Enter AI. Recently there’s been a wave of people using AI tools to reverse engineer their TVs, head units, gaming consoles etc using things like REA. I figured a few hours of messing around a few claude tokens can’t hurt.
I am ‘familiar’ with embedded programming and have messed around with bootloaders and custom firmwares since PSP days (shoutout to DarkAlex days of PSP hacking), but I generally followed in footsteps of others / needed a lot of source code/existing POCs to do stuff. This was my first time developing a CFW from scratch.
Step 1: Can we even flash it?
Harman still hosts the final firmware package and a recovery procedure on their support site. Unpacking it showed:
- A Marvell ARM chip running plain old embedded Linux (kernel 3.8, glibc 2.23, very 2016)
- A
squashfsroot filesystem inside Harman’s own container format, with a CRC per partition - No signature checks on the USB recovery path. The CRCs are just there to catch corruption
That last one is the whole ballgame. If the device will flash whatever you hand it, you can modify it.
Harman’s flashing tool is Windows only, and I wanted to flash from Linux, so we reverse engineered the USB protocol and wrote a small flasher in Python. But it kept stalling for reasons I could not figure out. After a whole evening of it, I decided to give up and install windows on an old unused laptop.
Step 2: Wi-Fi and AirPlay
Turns out the “Wi-Fi is gone” update didn’t remove anything. There’s a service literally called wifi-blocker with a hardcoded shutoff date of September 11, 2021. Comment it out and the Wi-Fi comes back. Classic. I figured the EOL update was cooked with a hurry and least effort so it made sense.
I packaged this changed firmware up and tried flashing it. It started off well but then crashed mid flash (after my millionth attempt of holding the reset button with a sim card remover and holding the mute button and plugging it in and out to get it into flashing mode….). The error was a CRC error. At this point I was worried I had seriously bricked the device and we were ‘cooked’. But luckily the partition I was flashing was NOT the boot loader (which btw you don’t need to flash at all), it recovered after another reboot + magic button reset combo. I fixed the CRC calculation but, repackaged it, and this time it took. After a restart I was able to see the device on my wifi network!
Aside: I had hardcoded my wifi creds in the firmware for this step (remediated later).
For AirPlay I compiled shairport-sync for the speaker. I already run this on my RPI hooked up to my sound system so this was an obvious choice (and I had already gone through pains of figuring out ARM toolchains for it in the past). The trick was matching the speaker’s ancient toolchain: an Ubuntu 16.04 Docker container with GCC 4.9 produces binaries that the speaker’s glibc is happy with. The speaker’s own audio stack (a closed-source DSP behind ALSA) wouldn’t negotiate a format with shairport-sync directly, so the audio gets piped into the speaker’s own aplay instead. Not elegant, works great.
The first time it showed up in the AirPlay picker on my phone and played was a very satisfying moment.
Step 3: Make it something other people can use
At this point it worked for me, but “I hand-patched a squashfs image” isn’t super shareable. So it became a kit:
- A build script that downloads Harman’s firmware from Harman’s server, compiles everything locally in Docker, asks you for a root password and spits out a ready-to-flash folder. Works on Linux, macOS and Windows (via WSL)
- No binaries in the repo. Nothing of Harman’s and nothing compiled. Licensing headaches? Ain’t nobody got time for that
- A Wi-Fi setup page. The Cortana app that used to set up the speaker is gone, so if the speaker can’t get online it now opens its own
Invoke-Setup-XXXXnetwork with a captive portal, like a smart plug would - AirPlay and Bluetooth play nice. AirPlay is registered with Harman’s own music source manager, so starting one stops the other and a tap on the top stops AirPlay
Things I found along the way
- The stock firmware has ADB open on the network. As root. With no password. Harman’s firewall script has its final “drop everything else” line commented out. The kit closes that, and gives every build its own SSH host keys (every stock speaker shares the same one)
- There’s a message bus that controls the LED ring and publishes button presses (tap, volume ring, Bluetooth button). That’s my next project: hooking it into Home Assistant
- AirPlay didn’t show up on my Mac even though it worked on my phone. The speaker was answering, but my Wi-Fi wasn’t passing its multicast replies along. Announcing through the speaker’s own mDNS daemon (which answers directly) fixed it
- Claude gets angsty about reverse engineering type of work. Even when I manually did a lot of the ‘risky’ work, any time I asked it to add ssh/bake in custom keys, it tripped its security safeguards.
Doing this with your own dead device
The kit is up on GitHub: B-1P/invoke-firmware-kit. If you have an Invoke in a drawer somewhere, the README walks you through building and flashing.
If you have some other abandoned smart thing, the playbook is roughly the same:
- Find the official firmware. Support pages for discontinued products often still host the last update and a recovery tool
- Unpack it and look for a Linux filesystem (
binwalkandunsquashfsare your friends) - Check whether updates are signed. No signature = you can flash your own
- Find the recovery mode first. Being able to always flash back to stock makes everything else low stakes
- Match the device’s toolchain when compiling things for it. An old Docker image beats fighting glibc versions
- Reuse what’s already on the device. This speaker already had
hostapd,dnsmasq, Python and an mDNS daemon; most of the work was wiring them up - Share scripts, not images. Let people download the vendor firmware themselves and build locally
TLDR;
A speaker Microsoft and Harman left for dead is now an AirPlay speaker on my Wi-Fi, with SSH and a setup page, and it’ll probably outlive the phone I’m streaming from. Kit is here.