Posts Tagged ‘break microcontroller protected firmware’

PostHeaderIcon STM32F723: What Two USB Controllers Tell You About a Product

Products built on this member usually have exactly one cable: a USB one. It powers the device, it carries the data, and in many designs it is the only external interface the product has. That makes the USB stack the most customer-visible part of the firmware and, from a recovery point of view, the most legible.

Two controllers are present. One reaches high speed through an external physical-layer device; the other has its transceiver on chip. A design that uses both is doing something specific — a fast data pipe to a host and a separate port for configuration or debugging — and that arrangement is visible in the image before any code is disassembled.

The enumeration tables

A USB device describes itself to the host through a hierarchy of descriptors. The host asks for them immediately after attachment, so they are the first structured data the firmware produces, and they are stored in the image in essentially the form they are sent.

descriptor what it declares what it reveals about the product
device vendor and product identifiers, class, maximum packet size who the product claims to be, and whether it uses a custom or a standard class
configuration power draw, number of interfaces, attributes whether the device is bus-powered and how much it asks for
interface class, subclass, protocol, endpoint count what the product does: storage, serial, audio, vendor-specific
endpoint address, direction, transfer type, interval how the data flows and at what rate
string human-readable text in UTF-16 manufacturer, product name, serial-number scheme

The identifiers in the first row are the fastest way to establish provenance. A vendor identifier that belongs to a known semiconductor vendor indicates a development or evaluation build; one that belongs to the customer indicates production firmware; a generic identifier shared across many products indicates a copied reference design. None of these is conclusive on its own, and together they narrow the question sharply.

Strings are the cheapest evidence

String descriptors are stored as UTF-16, which means they appear in a hex dump as alternating characters and zero bytes. They are legible without any disassembly at all, and they are frequently the most informative thing in the image.

what a string descriptor contains what it means for the job
a product name with a version number the firmware revision, which the customer can verify against their records
a serial-number format with a prefix the scheme used to derive serials, often from the device identifier
an interface name referring to a protocol which protocol stack the product implements
a manufacturer name that is not the customer’s the design was outsourced or licensed

The second row is worth following up. A serial number derived from the device’s unique identifier is a design decision with a consequence: a restored image on a different die will present a different serial, and any host-side licensing or pairing that depends on that serial will break. That is the same class of problem as an identifier-derived encryption key, described in STM32F756 code recovery, and it is easier to spot here because the string is readable.

The factory path

Every device of this family contains a bootloader in a read-only region that cannot be erased. It is reachable by holding the boot configuration pins at reset, and it speaks over several interfaces, one of which is USB.

This is the path most often proposed as a recovery method, and it deserves a precise description of what it can and cannot do.

command class what it does limitation
identify reports the supported commands and the flash geometry works regardless of protection
erase mass-erases the array works regardless of protection, and destroys the contents
write programs data at an address blocked in protected regions
read returns memory contents refused when read protection is active
jump transfers control to the application used to leave the bootloader without a reset

The fourth row is the decisive one, and it is the row that customers most often assume works. Reading memory through the factory bootloader is a privileged operation that the protection mechanism specifically disables; a device with read protection set will accept the erase command and refuse the read command, and the two responses arrive through the same channel from the same firmware. A bench that reports “connected to the bootloader, therefore readable” has established the first half and assumed the second.

The converse is equally worth stating. A device with protection unset can often be read entirely through this path, without opening anything, in a few minutes. That makes the protection state the single most valuable piece of information to obtain before quoting work, and it is obtainable by attempting one read of a single word.

Class requests as a behavioural summary

Beyond enumeration, the requests a device supports describe what it is for.

request pattern the design it implies
bulk endpoints with large maximum packet sizes a data pipe: streaming, storage or a custom protocol
interrupt endpoints with short intervals periodic status reporting, often a sensor or a control panel
isochronous endpoints audio or video, with timing guarantees
a vendor-specific class with a command header a proprietary protocol, and the header is the specification
standard device firmware update class field-updatable, and the update image format is defined by the class

The fourth row is where a recovery delivers the most value per hour. A vendor-specific protocol implemented over bulk transfers has a request header, a length field and a set of opcodes, and those are all in the image in a form that can be reconstructed into a usable specification. Customers frequently want that specification more than they want the code.

Reading a device whose only port is USB

If the protection is unset, the factory path is the simplest route and requires no disassembly. If it is set, the USB port is no help at all, and the work moves to the debug port — which may itself be disabled — and from there to physical access.

A useful intermediate check is the boot configuration at reset. A design that has tied the boot pins to fixed levels has removed the factory path from the product entirely, which is common in consumer hardware and rare in industrial hardware. Establishing that early prevents a plan built on a route that does not exist on this board.

The identification discipline that precedes all of this, for a device whose designation does not resolve, is in STM32F747 binary recovery. The same factory bootloader described from the command-set angle rather than the USB angle is in STM32F745 heximal extraction, and the member of the family without a network or display path, where USB is often the only interface at all, is in STM32F722 code recovery.

FAQ

Can USB alone recover a protected device? No. The factory bootloader refuses read commands when protection is active, and the application’s own USB stack is under the same restriction.

Are the descriptors always stored verbatim? Usually, and where they are generated at runtime the generator is short and recognisable by its table of lengths and types.

Does a serial number derived from the device identifier matter? It does if anything external depends on it — licensing, pairing or a host-side database. Restoring the image onto another die changes it.

Conclusion

On a product with one port, the port’s description of itself is the best documentation available. Descriptors give identity and purpose, strings give revision and provenance, class requests give behaviour, and the factory bootloader gives either a fast recovery or a fast refusal depending on a single option byte. Reading that byte first is the difference between a plan and a guess.