PICOKIT-46 BINARY RECON
September 25, 2026 ยท View on GitHub

FREE Reverse Engineering Self-Study Course HERE
FREE Embedded Hacking Course HERE
PICOKIT-46 BINARY RECON
ELF and UF2 Inspection of a Known Constant
Lesson 46 of the Picokit Series
LEGAL DISCLAIMER: The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
- Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
- The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
- You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.
Overview
The forty-sixth Picokit lesson. The node keeps a read-only blob that carries the four byte PKIT magic, locates it, and reports its byte offset in an authenticated heartbeat. The README lab inspects the built ELF and UF2, finds the same constant, and compares offsets.
What it teaches
- Locating a known constant inside a read-only blob.
- Reporting the constant offset in an authenticated heartbeat.
- Listing ELF sections and symbols with readelf and nm.
- Finding the constant bytes in the linked image and the UF2.
Hardware
| Peripheral | Pico 2 pin | Role |
|---|---|---|
| Red / Yellow / Green | GP16 / GP17 / GP18 | annunciator status |
| Onboard LED | GP25 | heartbeat, one blink per transmit |
| RYLR998 | GP8 TX / GP9 RX | LoRa heartbeat |
| Debug Probe | SWCLK/SWDIO/GND, GP0/GP1 | SWD and the console |
How it works
The node runs monitor_step in a loop. Every 5 seconds it locates the
PKIT magic in g_recon_blob, seals {"n":46,"s":<seq>,"o":<offset>} with the
shared field key, and sends it over LoRa.
Build and flash
cd firmware
cmake -S . -B build -G Ninja -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350-arm-s
cmake --build build
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
-c "program build/picokit_46_binary_recon verify reset exit"
Watch the node
Open the console at 115200 and reset:
BOOT
=== PICOKIT-46 BINARY RECON // ELF + UF2 INSPECT + DEBUG LAB ===
RECON n=46 offset=7 seq=1
RECON n=46 offset=7 seq=2
RX from 0x0001, N bytes
The gateway
cd gateway
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python3 listen.py --port /dev/cu.usbserial-A50285BI --hub 0001 --network 18 --db gateway.db
It prints OK node=46 rssi=... per authenticated heartbeat. The terminal
dashboard python3 tui.py --db gateway.db and the web dashboard
python3 web/app.py --db gateway.db show the same rows.
Debug lab: inspect the ELF and UF2 for a known constant
Build the firmware, then inspect the linked image. The blob carries the ASCII
magic PKIT (bytes 50 4B 49 54):
arm-none-eabi-readelf -S build/picokit_46_binary_recon.elf
arm-none-eabi-nm build/picokit_46_binary_recon.elf | grep g_recon_blob
strings -t x build/picokit_46_binary_recon.elf | grep PKIT
strings -t x build/picokit_46_binary_recon.uf2 | grep PKIT
The symbol g_recon_blob lands in .rodata; the PKIT bytes sit seven bytes
into it, so the file offset of the magic is the blob offset plus seven. The
same bytes appear in picokit_46_binary_recon.uf2. The heartbeat reports the
blob offset as o in {"n":46,"s":<seq>,"o":7}.
Verify
python3 .opencode/skill/embedded-c-standard/audit_c_standard.py
python3 .opencode/skill/embedded-python-standard/audit_python_standard.py
python3 .opencode/skill/iot-readme-standard/validate_readme.py
python3 .opencode/skill/iot-banner-standard/validate_banner.py
python3 scripts/run_tests.py
python3 scripts/check_coverage.py