Skip to content

Instantly share code, notes, and snippets.

@flyinprogrammer

flyinprogrammer/checksum.c

Last active Jul 29, 2020
Embed
What would you like to do?
#include <stdio.h>
#include <stdint.h>
typedef uint32_t DWORD;
typedef uint16_t WORD;
int main(int argc, char *argv[]) {
char *filename = "firmware.bin";
FILE *input_file;
if (argc > 1)
filename = argv[1];
fprintf(stderr, "Opening file %s\n", filename);
input_file = fopen(filename, "r");
DWORD dLength, dCheckSum, dExpectedCheckSum, dAddress, i, dImageBuf[512*1024];
WORD wSignature;
fread(&wSignature,1,2,input_file); // read signature bytes
if (wSignature != 0x5943) // check ‘CY’ signature byte
{
printf("Invalid image");
return 1;
}
fread(&i, 2, 1, input_file); // skip 2 dummy bytes
dCheckSum = 0;
while (1)
{
fread(&dLength,4,1,input_file); // read dLength
fread(&dAddress,4,1,input_file); // read dAddress
if (dLength==0) break; // done
// read sections
fread(dImageBuf, 4, dLength, input_file);
for (i=0; i<dLength; i++) dCheckSum += dImageBuf[i];
}
printf("checksum: %#x\n", dCheckSum);
// read pre-computed checksum data
fread(&dExpectedCheckSum, 4, 1, input_file);
printf("expected checksum: %#x\n", dExpectedCheckSum);
if (dCheckSum != dExpectedCheckSum)
{
printf("Fail to boot due to checksum error (calculated %#x != file %#x)\n", dCheckSum, dExpectedCheckSum);
return 1;
}
return 0;
}
@miek

This comment has been minimized.

Copy link

@miek miek commented Jul 29, 2020

I think the problem is that dCheckSum is too wide, it should only be 32-bits. Here's the version I used for reference: https://gist.github.com/miek/b6248205b6cfd26c1c6c5d6ac0abdc3d

@flyinprogrammer

This comment has been minimized.

Copy link
Owner Author

@flyinprogrammer flyinprogrammer commented Jul 29, 2020

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv) {
    unsigned long ulong;
    unsigned short ushort;
    uint32_t uint32Magic;
    uint16_t uInt16Magic;

    printf("the size of unsigned long %ld\n", sizeof(ulong) );
    printf("the size of unsigned short %ld\n", sizeof(ushort) );
    printf("the size of uint32_t %ld\n", sizeof(uint32Magic) );
    printf("the size of uint16_t %ld\n", sizeof(uInt16Magic) );

    return 0;
}

yields:

the size of unsigned long 8
the size of unsigned short 2
the size of uint32_t 4
the size of uint16_t 2

https://stackoverflow.com/questions/35844586/can-i-assume-the-size-of-long-int-is-always-4-bytes/35844670

Lols, so don't I feel silly now. Thanks for your help @miek!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment