view bootutil/c139_main.c @ 17:632d62e5efb4

c1xx-analyze-image: add bootloader analysis
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 10 Jun 2023 06:24:15 +0000
parents fe5f7ba7f154
children
line wrap: on
line source

/*
 * This C module is the main for c139-analyze-boot utility.
 */

#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "../bootmatch/bootmatch.h"

extern struct bootmatch bootmatch_c11x_lockable[];
extern struct bootmatch bootmatch_c11x_nolock[];
extern struct bootmatch bootmatch_c139_lockable[];
extern struct bootmatch bootmatch_c139_nolock[];
extern struct bootmatch bootmatch_fc_patch[];

#define	LENGTH_OF_INTEREST	0x2064

static u_char image[LENGTH_OF_INTEREST];

static void
read_bin_file(filename)
	char *filename;
{
	int fd;
	struct stat st;

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		perror(filename);
		exit(1);
	}
	fstat(fd, &st);
	if (!S_ISREG(st.st_mode)) {
		fprintf(stderr, "error: %s is not a regular file\n", filename);
		exit(1);
	}
	if (st.st_size < LENGTH_OF_INTEREST) {
		fprintf(stderr, "error: %s is too short\n", filename);
		exit(1);
	}
	read(fd, image, LENGTH_OF_INTEREST);
	close(fd);
}

static int
check_810_signature()
{
	if (image[0x810] != '1')
		return(0);
	if (image[0x811] != '0')
		return(0);
	if (image[0x812] != '0')
		return(0);
	if (image[0x813] == '3' || image[0x813] == '4')
		return(1);
	else
		return(0);
}

static void
classify_by_lock_word()
{
	unsigned lword;

	lword = ((unsigned) image[0x2060]) |
		((unsigned) image[0x2061] << 8) |
		((unsigned) image[0x2062] << 16) |
		((unsigned) image[0x2063] << 24);
	if (lword == 0xDDDDDDDD)
		puts("unlocked");
	else
		puts("locked");
}

main(argc, argv)
	char **argv;
{
	if (argc != 2) {
		fprintf(stderr, "usage: %s flashdump.bin\n", argv[0]);
		exit(1);
	}
	read_bin_file(argv[1]);
	if (check_for_match(image, bootmatch_fc_patch)) {
		puts("fc");
		exit(0);
	}
	if (check_for_match(image, bootmatch_c11x_nolock)) {
		puts("unlocked");
		exit(0);
	}
	if (check_for_match(image, bootmatch_c11x_lockable)) {
		classify_by_lock_word();
		exit(0);
	}
	if (check_for_match(image, bootmatch_c139_nolock)) {
		if (!check_810_signature()) {
			puts("unknown");
			exit(0);
		}
		puts("unlocked");
		exit(0);
	}
	if (check_for_match(image, bootmatch_c139_lockable)) {
		if (!check_810_signature()) {
			puts("unknown");
			exit(0);
		}
		classify_by_lock_word();
		exit(0);
	}
	puts("unknown");
	exit(0);
}