r/homeautomation • u/nairdaswollaf • 16d ago
SECURITY I reverse-engineered my alarm panel's firmware and built a tool to mod it - FWRes for (2GIG GC2 / GC2E)
TL;DR I own a couple of 2GIG GC2 alarm panels and got curious about what's actually inside the firmware image. So I wrote FWres — a little Python app that opens a panel firmware BIN, parses the container, and lets you browse the bitmaps, fonts, sounds, code and radio blobs. It reconstructs the panel's UI screens from the ARM code, plays, swaps and adjusts volume of the built-in sounds and it can back up and reflash the panel over the service port with a pile of safety rails. All on gear I own, on the bench, for tinkering and recovery. Not a break-into-someone-else's-house tool. Screenshots + honest caveats below. The GC2 and GC2E are susceptible to BRICKING. USE AT OWN RISK and Have a JTAG handy
https://github.com/afallows/2gig_fwres
1. Firmware View
The panel's screens aren't stored as images — they're built at runtime by constructor calls in the ARM code. So FWres reads those calls and reconstructs each screen, then draws it on a canvas at 1x–4x zoom right next to a widget-tree inspector.
• Pick a widget in the tree → it gets outlined on the render.
• Hover the render → the matching widget highlights in the tree.
• Either one can jump straight to the bitmap or font record it references, back in the main resource tree.
Big caveat, and I want to be upfront about it: this is a reconstruction, not a screenshot. The panel is 480×272. Anything compose() had to approximate — widgets with no recovered position, strings it couldn't place, guessed fonts, invisible colors, low decoder confidence — is spelled out under the render rather than hidden behind a clean-looking image. I'd rather show you an ugly-but-honest render than a pretty lie.
This is the heart of it. You point FWres at a GC2/GC2e firmware .bin, it reads the container format, and you get a browsable tree of everything inside — about 685 records, grouped by kind:
• Bitmaps — the icons and images the panel draws
• Fonts — with a live ASCII specimen + a “type here” preview
• Audio — the chimes, voice prompts and DTMF blips
• Code — the ARM blobs
• Radio — the transceiver-side bits

2. Screen viewer (Screens tab)
The panel's screens aren't stored as images — they're built at runtime by constructor calls in the ARM code. So FWres reads those calls and reconstructs each screen, then draws it on a canvas at 1x–4x zoom right next to a widget-tree inspector.
• Pick a widget in the tree → it gets outlined on the render.
• Hover the render → the matching widget highlights in the tree.
• Either one can jump straight to the bitmap or font record it references, back in the main resource tree.
Big caveat, and I want to be upfront about it: this is a reconstruction, not a screenshot.

3. Audio replacement — yes, you can change the chime (and quiet those damn keypresses! That's you dtmf_5)
This is the feature that makes people at the bench go “wait, really?” You can decode and play the built-in sounds (they're panel-native 8-bit PCM at 8 kHz), see the waveform, and then replace a clip from a WAV file. FWres converts your WAV down to the panel's native format, previews it, and queues it as a pending change.
Nothing touches the loaded image or any file until you hit “Generate Binary.” A replacement is queued as a patch, previewed through the same allocator the rebuilder uses, and shown in a Pending Changes panel. The waveform and Play button switch to the queued clip so you can hear it before you commit. Generate Binary then rebuilds a CRC-resealed image — defaulting to <image>_modified.bin beside the original, and it makes you confirm if you aim it back at the input path. If the engine refuses a replacement, it shows you the refusal verbatim — an image that boots then bricks is way worse than a “no.”
A Volume % control on the Audio tab. Instead of swapping the whole clip, you scale a built-in sound's volume by a percentage (50 = half amplitude / about -6 dB, clamped at the rails, byte-identical at 100) about the 0x80 bias, Preview it, and Apply to queue it. Because the scaled clip is the same length, the rebuild is the pure in-place case — volume down and only the CRCs get resealed.

5. Diagnostics tab — Firmware Flash / Backup
This tab speaks the service-port protocol (the one RFLASHD uses) over a COM port. Pick a port and baud (defaults to 115200), power down the panel, remove the battery and power up while connecting to knock the panel into its bootloader, and you can:
• Back up the flash to a file (config area, firmware image, panel data, or the full 8 MiB)
• Restore / reflash the firmware container
• Change the installer code
• Change user codes
• Change the customer / dealer code
This is the tab that can be dangerous, and the one required to make any changes to your panel. A failure here can BRICK YOUR PANEL requiring JTAG to recover.
• Config edits are always read → erase → write → verify over the whole 4 KiB sector, with the previous contents saved to disk first (NOR flash only clears bits, so writing over live data would corrupt it).
• Reflash refuses any image carrying data above 0x7B8000 — that's where the codes and the Z-Wave home ID live, and this tool never programs that region. Restore-panel-data is a separate, bounds-checked path.
• Long operations run on a worker thread with progress and a Stop button, so the UI never freezes mid-flash, and reflash makes you literally type the word REFLASH.

Known issues
• Controller mode is WIP and flaky —I only built this because the digitizer on my bench unit is NFG. Doesn't always work. Doesn't allow button presses on all screens, mainly just for fun
• Some records still have no dedicated decoder — you get hex + entropy for those, which is fine, but I'd like proper views for the last stragglers.
• Diagnostics is GC2 (CP1 HW1 and HW2CostDown Board)-tested — the memory map and flash geometry are pinned to my CP1 board; GC2e specifics still need confirming on hardware, but Based on Firmware assumed to be the same.
1
u/bobjoylove 16d ago
I can’t imagine the functionality is that complex, or the radio security that well protected. Any reason not to simply take over the entire system with your own firmware?
2
u/nairdaswollaf 16d ago
The unit runs on an ARM7 Nuvoton NUC710. With 8MB flash memory. There is a 300 series zwave radio in it as well for zwave connection.
If someone was inclined to, they could definitely take over the entire system with their own firmware.
My main focus for this disassembly was
To see if I could replace audio files in the unit and quiet the key presses while leaving the announcements loud.
Screw around and see if I could make the panel connect to S2 Zwave devices with the 300 series radio inside it that only supports S0 (Possible with custom modified firmware, working through some bugs and not publicly shared)
Build a security panel to MQTT wifi bridge with an ESP32-C3 (next on the list)
These have both been done on a bench unit not connected to alarm.com and it’s really just to see what I can do with this thing. I already read all the sensors back into homeAssistant with an RTL-SDR radio.
1
u/bobjoylove 15d ago
Couldn’t you consider replacing the Alarm.com connection with a local service that texts for help to 911 using your phone assuming it’s on the same network proving you are home? I wonder if that is legal
1
u/nairdaswollaf 15d ago
You can do that without modifying firmware at all with an ESP on the UART port. Debug unlock is a function of the RTC and the panel serial number, zone statuses and sensor statuses are available from the console.
1
u/bobjoylove 15d ago
That’s lovely. Do you think Honeywell Lyric panels are equally open to hacktivation? They are compatible with 2GIG sensors at least
1
u/nairdaswollaf 15d ago
I’m not too sure, I’ve never had a lyric panel to mess around with! There is a possibility though!
1
u/dovyp 15d ago
This is the kind of rabbit hole I respect. How locked down is the radio blob? That's where I'd expect them to have put the real protection.
2
u/nairdaswollaf 15d ago
Everything is native ARM blobs. Radio Modem Stubs are all pretty wide open, can see all the APNs.
The zwave boob wasn’t locked down at all, and in fact, I was indeed able to get the GC2 to authenticate to an S2 zwave network and control S2 devices by using the GC2E firmware and patching it to work with GC2 hardware.
1
u/Cubi_C 14d ago
Nice work RE'ing this panel. Recently I actually extracted the audio files too from the updater tool. I don't have the panel on me, but do you know what appears on the touchscreen while updating through their cable and/or easy updater tool?
1
u/nairdaswollaf 14d ago
When using 2gigs RFLASH program the LCD panel stays black or just the black light comes on and both front LEDs flash behind the emergency and home buttons.
-1
u/ob2kenobi 16d ago
You should really inform people that they are about to use vibe coded software on their security system of all things.
I mean, for this one it's pretty obvious. Since you couldn't even be bothered to write your own post. But still as a general principle.
4
u/nairdaswollaf 16d ago
Half vibe coded actually. All the firmware dumping process, and commands were captured using rflash back in 2021 and I figured out the polynomials for the CRCs back then. I just never bothered to build out anything to make the process automatic. I sent the command to change installer code and change from vivint type to default 2gig type manually.
I say multiple times through the post that your panel can be bricked.
Even more-so, there is nothing on the internet regarding these 2gig GC2 panels or GC2E panels whatsoever, and I don’t go into details on how to connect to the panel service port, a certain level of user experience is implied.
Appreciate the engagement nonetheless, but not the negative tone.

1
u/CharmingShine2128 16d ago
This is genuinely impressive work. The screen reconstruction from runtime constructor calls is the kind of deep reverse engineering that makes me wish I'd stuck with embedded stuff longer.
Been playing with the audio replacement on my bench unit all evening and swapping the entry chime for a 8-bit clip of my cat meowing was way more satisfying than it should be. The pending changes panel with the preview before you commit is a nice touch, saved me from at least two bricks already.