Brighton's Blog

Reverse Engineering a Fire TV App

reverse-engineeringandroidfire-tv

A streaming service had a Fire TV app built with a white-label app builder platform. We wanted to extract every piece of data it uses – content feeds, video URLs, thumbnails, API endpoints, the intro video, every asset – so we could rebuild the app from scratch with our own architecture.

Read more →

3 - Reverse Engineering the TI EV2300: The DLL Battle

Reverse EngineeringGhidraSTM32USBHIDTIEV2300DLLCRCFirmware

“I’ve been through the desert on a horse with no name” — America

The Timeout That Wouldn’t Die

After Part 2 I had bqStudio reading registers through the STM32 bridge. The silent command fixes got the GUI working. But the DLL path—bq80xrw.dll’s ReadSMBusWord—still returned “EV2X00 Adapter USB Timeout” every single time.

Read more →

2 - Reverse Engineering the TI EV2300: Building the Firmware Clone

Reverse EngineeringSTM32USBHIDI2CSMBusTIEV2300FirmwareEmbedded

“started from the bottom now we’re here” — Drake

From Python Driver to Firmware Clone

In Part 1 I reverse engineered the EV2300’s HID protocol and built a pure-Python driver that talks to the real adapter without TI’s DLLs. That solved the “no scripting interface” problem—but we still needed the physical EV2300 hardware. At $200 a pop, with a supply chain that’s been spotty since 2020, that’s not great for a university lab with 30 students.

Read more →

1 - Reverse Engineering the TI EV2300

Reverse EngineeringPythonUSBHIDI2CSMBusTIEV2300ctypesWindowsLinux

The Problem

A $200 USB Adapter Held Hostage by Proprietary DLLs

Texas Instruments makes the EV2300—a USB-to-I2C adapter for talking to their battery management ICs. It’s the standard tool for the BQ76920/BQ76940 evaluation boards. Plug it in, fire up bqStudio (TI’s official GUI), read some registers, write some registers. Simple.

Read more →

1 - Fixing Choppy Audio on the Topping DX5 II in Linux

LinuxAudioKernelUSBALSAPipeWireDAC

This one is less of an adventure story and more of a debugging post-mortem. The MR18 saga had 23 bugs over a full week. This had 0 bugs in the fix—just a two-line kernel patch—but the debugging got deep into USB audio internals and Linux kernel source code.

Read more →

15 - MR18 Deep Dive: UART Scripts

MerakiMR18PythonUARTOpenWrtdeep-dive

Hex-encoding 7 million bytes because the PHY won’t cooperate

Post 6 described the hex-over-UART transfer protocol at a high level—hex-encode every byte, pipe it through an awk decoder on the MR18, pray nothing goes wrong for 20 minutes straight. This post rips open send_binary.py and uart_transfer.py and walks through the actual Python. Two scripts, two transfer sizes, same dumb protocol, very different engineering challenges.

Read more →

14 - MR18 Deep Dive: Bare-Metal C

MerakiMR18CMIPSAssemblyAR8035PHYdeep-dive

Writing a PHY driver without libc

Post 6 mentioned a standalone C program that pokes two MDIO registers to fix the AR8035 PHY’s broken RGMII RX clock delay. This deep dive rips open the actual source—ar8035_start.S, ar8035.c, and the Makefile—and walks through every layer from the assembly entry point down to the register writes that make Ethernet work. If you’ve ever wondered what bare-metal Linux userspace programming looks like on MIPS with zero library dependencies, this is it.

Read more →

13 - MR18 Deep Dive: Network and Sysupgrade

MerakiMR18PythonOpenWrttelnetdeep-dive

Network setup and sysupgrade

They won’t leave in the night. Have no fear that they might desert me — Kanye West ft. JAY-Z, “Diamonds From Sierra Leone”

Twelve posts deep. Cache flushes, MIPS trampolines, XOR verification, UART monitoring, failsafe timing. This post covers the last mile—once the kernel is booted and failsafe is confirmed, how do we talk to the device over the network and flash the permanent sysupgrade image? No more PRACC, no more cache paranoia. Just TCP/IP and a couple of file transfers.

Read more →

12 - MR18 Deep Dive: Launch and Failsafe

MerakiMR18PythonJTAGOpenWrtUARTdeep-dive

Launching the kernel and catching failsafe on the way down

Lotta different problems, you would think they came with lessons — AVGUST, “Vanilla Latte”

Post 10 ended with a verified binary in clean DRAM. Post 5 gave the high-level failsafe saga. This post covers the actual code: the launch trampoline, the regression that taught me to stop touching the CPU, and two competing strategies for triggering failsafe mode.

Read more →

11 - MR18 Deep Dive: Verification

MerakiMR18PythonJTAGOpenWrtMIPSdeep-dive

CPU-executed XOR verification

Post 10 covered phases 0 through 2—flush, load, flush again. At that point we have 6.9 MB of initramfs sitting in DRAM, and now we need to answer a simple question: is it correct? This post covers phase 3, the XOR verification pipeline, including the approach that didn’t work and the one that does.

Read more →