CRC-32 Reverse Utility

About

Background

When developing embedded software for microcontrollers, it is sometimes useful to know the checksum (the CRC) firmware in the application. Moreover, you may need the original CRC (before programming) and the current (runtime), for comparison.

Options for save the original CRC can be different:

  • Append CRC at the end of the firmware and read it in the application;
  • Write CRC at a fixed address in the program memory, with further ignore this area when calculating the CRC at runtime;
  • Save of the original CRC elsewhere, such as EEPROM.

For various reasons, it is still not satisfied.

Therefore, another method has been selected.

Implementation

Define structure:

#ifndef APPLICATION_DATA_VERSION_INFO_H_
#define APPLICATION_DATA_VERSION_INFO_H_

#include <stdint.h>

typedef struct {
  uint32_t length;
  uint32_t checksum;
  ...
  /* Other data */
  ...
  uint32_t crc_correct;
} tFirmwareData;

#endif /* APPLICATION_DATA_VERSION_INFO_H_ */

Here can be defined some other necessary data. Including using third-party utilities to fill them after the firmware build.

The structure is placed at a fixed address in the program memory, with the attribute:

__attribute__ ((section(".firmware_data")))
static const tFirmwareData firmwareData = {
  0x00000000, // length
  0x00000000, // checksum
  0x00000000 // crc_correct
};

and section in the linker script:

  .firmware_data :
  {
    . = 0x12345678; /* Фиксированный адрес для структуры */
    KEEP(*(.firmware_data))
  } >FLASH

Next:

  • After build, the firmware binary file is obtained;
  • By using other utility we can calculate a checksum of the resulting file;
  • Also, we can find out the length of the this file;
  • These checksum and length of the firmware placed in a file at a fixed address, corresponding to fields of the structure;
  • Calculate the correction stub, write it to the structure crc_correct field, and checksum will return to its original value.

Task of calculating checksums and firmware modification can be solved by using srecord. To calculate the correction stub has been written this utility.