Exemple #1
0
int FlashIAP::deinit()
{
    int ret = 0;
    _mutex->lock();
    if (flash_free(&_flash)) {
        ret = -1;
    }
    delete[] _page_buf;
    _mutex->unlock();
    return ret;
}
Exemple #2
0
int main(int argc, char **argv)
{
	int can_write_bl = 0;
	int num_files = 0;
	int res;
	flash_file_t files[MAX_FILES];

	memset(files, 0, sizeof(files));

	if (argc < 2) {
		usage(argv[0]);
		return -1;
	}

	for (int i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			if (!strcmp(argv[i], "-b")) {
				can_write_bl = 1;
			} else {
				usage(argv[0]);
				return -1;
			}
		} else {
			res = flash_load(&files[num_files], argv[i], can_write_bl);
			if (res < 0) {
				fprintf(stderr, "Error while loading %s\n", argv[i]);
				return -1;
			}
			fprintf(stderr, "\n");
			num_files++;
		}
	}

	usb_init();

	fprintf(stderr, "Waiting for Proxmark to appear on USB...");
	while (!OpenProxmark(0)) {
		sleep(1);
		fprintf(stderr, ".");
	}
	fprintf(stderr, " Found.\n");

	res = flash_start_flashing(can_write_bl);
	if (res < 0)
		return -1;

	fprintf(stderr, "\nFlashing...\n");

	for (int i = 0; i < num_files; i++) {
		res = flash_write(&files[i]);
		if (res < 0)
			return -1;
		flash_free(&files[i]);
		fprintf(stderr, "\n");
	}

	fprintf(stderr, "Resetting hardware...\n");

	res = flash_stop_flashing();
	if (res < 0)
		return -1;

	CloseProxmark();

	fprintf(stderr, "All done.\n\n");
	fprintf(stderr, "Have a nice day!\n");

	return 0;
}
Exemple #3
0
// Load an ELF file and prepare it for flashing
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl)
{
	FILE *fd = NULL;
	Elf32_Ehdr ehdr;
	Elf32_Phdr *phdrs = NULL;
	int num_phdrs;
	int res;

	fd = fopen(name, "rb");
	if (!fd) {
		fprintf(stderr, "Could not open file '%s': ", name);
		perror(NULL);
		goto fail;
	}

	fprintf(stderr, "Loading ELF file '%s'...\n", name);

	if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
		fprintf(stderr, "Error while reading ELF file header\n");
		goto fail;
	}
	if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
		|| le32(ehdr.e_version) != 1)
	{
		fprintf(stderr, "Not an ELF file or wrong ELF type\n");
		goto fail;
	}
	if (le16(ehdr.e_type) != ET_EXEC) {
		fprintf(stderr, "ELF is not executable\n");
		goto fail;
	}
	if (le16(ehdr.e_machine) != EM_ARM) {
		fprintf(stderr, "Wrong ELF architecture\n");
		goto fail;
	}
	if (!ehdr.e_phnum || !ehdr.e_phoff) {
		fprintf(stderr, "ELF has no PHDRs\n");
		goto fail;
	}
	if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
		// could be a structure padding issue...
		fprintf(stderr, "Either the ELF file or this code is made of fail\n");
		goto fail;
	}
	num_phdrs = le16(ehdr.e_phnum);

	phdrs = malloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr));
	if (!phdrs) {
		fprintf(stderr, "Out of memory\n");
		goto fail;
	}
	if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
		fprintf(stderr, "Error while reading ELF PHDRs\n");
		goto fail;
	}
	if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
		fprintf(stderr, "Error while reading ELF PHDRs\n");
		goto fail;
	}

	res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs);
	if (res < 0)
		goto fail;
	res = check_segs(ctx, can_write_bl);
	if (res < 0)
		goto fail;

	free(phdrs);
	fclose(fd);
	ctx->filename = name;
	return 0;

fail:
	if (phdrs)
		free(phdrs);
	if (fd)
		fclose(fd);
	flash_free(ctx);
	return -1;
}
Exemple #4
0
int parse_flash_partition(uint8_t *data, unsigned int length, const char *partition_name, uint32_t offset, const char *filepath, int detected_device)
{
	struct flash_file *flash;
	int file_device;
	
	flash = flash_create(data, length);
	if(!flash) {
		fprintf(stderr, "%s: Memory error\n", program);
		return 0;
	}
	
	switch(flash->header->magic) {
		case AOS_ZMfX_MAGIC: {
			if(verbose) printf("\t%s: Stage 2 bootloader\n", filepath);
			break;
		}
		case AOS_KERNEL_MAGIC: {
			if(verbose) printf("\t%s: Kernel (zImage+initramfs)\n", filepath);
			break;
		}
		case AOS_GZIP_MAGIC: {
			if(verbose) printf("\t%s: Boot Logo\n", filepath);
			break;
		}
		default: {
			if(offset == 0x3f8000 || offset == 0x000000) {
				// We know those are never signed, so we don't warn about them
				flash_free(flash);
				return 0;
			}
			
			printf("\t%s: Unknown magic, this is weird.\n", filepath);
			flash_free(flash);
			return 0;
		}
	}
	
	if(flash->header->magic != AOS_GZIP_MAGIC) {
		if(flash->header->bits != 0x400) {
			if(verbose)
				printf("\t%s: Signature is 0 bits long (SDE Firmware?).\n", filepath);
		}
		else {
			if(!flash_is_signed(flash)) {
				if(verbose)
					printf("\t%s: File is not signed.\n", filepath);
			}
			else {
				if(!flash_detect_key(flash, Bootloader_Keys, MPK_KNOWN_DEVICES, &file_device)) {
					printf("WARNING: %s: Signature is not valid.\n", filepath);
				}
				else {
					if(detected_device != file_device) {
						printf("WARNING: %s: The detected device type for this file does not match the .aos device type (detected %s).\n", filepath, mpk_device_type(file_device));
					}
					else {
						if(verbose)
							printf("\t%s: Signature is valid, detected device type %s.\n", filepath, mpk_device_type(file_device));
					}
				}
			}
		}
	}
	
	if(flash->header->magic == AOS_KERNEL_MAGIC) {
		unsigned int gz_length;
		uint8_t *gz_data;
		char *folder_name;
		char *device_shortname;
		
		gz_data = (uint8_t *)flash->header+flash->header->cpio;
		gz_length = (flash->length - flash->header->cpio);
		
		if(*(uint32_t *)gz_data == AOS_GZIP_MAGIC) {
			folder_name = strdup((const char *)&gz_data[10]);
			if(endswith(folder_name, ".cpio"))
				folder_name[strlen(folder_name)-strlen(".cpio")] = 0;
		}
		else if((*(uint32_t *)gz_data & AOS_GZIP_NONAME_MASK) == AOS_GZIP_NONAME_MAGIC) {
			folder_name = bprintf("%s", partition_name);
		}
		else {
			printf("error: Could not find GZIP magic at given offset in %s.\n", filepath);
			flash_free(flash);
			return 0;
		}
		
		switch(detected_device) {
			case MPK_DEVICE_A5: device_shortname = "a5"; break;
			case MPK_DEVICE_A5IT: device_shortname = "a5it"; break;
			case MPK_DEVICE_A3GP: device_shortname = "a3g"; break;
			default: device_shortname = "unk"; break;
		}
		
		// Unpack script
		log_write("unpack.sh", "## zImage+initramfs: %s\n", filepath);
		log_write("unpack.sh", "rm -f -r unpacked/%s/\n", folder_name);
		log_write("unpack.sh", "mkdir -p unpacked/%s/initramfs/\n", folder_name);
		log_write("unpack.sh", "aos-unpack %s --%s --output unpacked/%s/ --zimage zImage --initramfs initramfs.cpio.gz\n", filepath, device_shortname, folder_name);
		log_write("unpack.sh", "gunzip --decompress unpacked/%s/initramfs.cpio.gz\n", folder_name);
		log_write("unpack.sh", "(cd unpacked/%s/initramfs/ && cpio -i -d -H newc -F ../initramfs.cpio --no-absolute-filenames)\n", folder_name, folder_name);
		log_write("unpack.sh", "rm unpacked/%s/initramfs.cpio\n", folder_name);
		log_write("unpack.sh", "\n");
		
		// Repack script
		log_write("repack.sh", "## zImage+initramfs: %s\n", filepath);
		log_write("repack.sh", "(cd unpacked/%s/initramfs/ && find . | cpio -o -H newc -F ../initramfs.cpio)\n", folder_name);
		log_write("repack.sh", "rm -f -r unpacked/%s/initramfs/\n", folder_name);
		log_write("repack.sh", "gzip --name --best unpacked/%s/initramfs.cpio\n", folder_name);
		log_write("repack.sh", "aos-repack --kernel --output %s --zimage unpacked/%s/zImage --initramfs unpacked/%s/initramfs.cpio.gz\n", filepath, folder_name, folder_name);
		log_write("repack.sh", "rm -f -r  unpacked/%s/\n", folder_name);
		log_write("repack.sh", "\n");
		
		free(folder_name);
	}
	else if(flash->header->magic == AOS_GZIP_MAGIC) {
		const char *gz_name = (const char *)&data[10];
		
		log_write("unpack.sh", "## .gz: %s\n", filepath);
		log_write("unpack.sh", "mkdir -p unpacked/\n", gz_name);
		log_write("unpack.sh", "rm -f unpacked/%s\n", gz_name);
		log_write("unpack.sh", "cp %s unpacked/%s.gz\n", filepath, gz_name);
		log_write("unpack.sh", "gunzip -d unpacked/%s.gz\n", gz_name);
		log_write("unpack.sh", "\n");
		
		log_write("repack.sh", "## .gz: %s\n", filepath);
		log_write("repack.sh", "gzip -N --best unpacked/%s\n", gz_name);
		log_write("repack.sh", "cp unpacked/%s.gz %s\n", gz_name, filepath);
		log_write("repack.sh", "rm -f unpacked/%s.gz\n", gz_name);
		log_write("repack.sh", "\n");
	}
	
	flash_free(flash);
	
	return 1;
}
Exemple #5
0
int parse_cramfs_archive(const char *filename, uint8_t *data, unsigned int length, const char *filepath, int detected_device)
{
	struct flash_file *flash;
	int file_device;
	char cramfs_name[2048];
	
	flash = flash_create(data, length);
	if(!flash) {
		fprintf(stderr, "%s: Memory error\n", program);
		return 0;
	}
	
	if(flash->header->magic != AOS_CRAMFS_MAGIC) {
		fprintf(stderr, "%s: Invalid Cramfs magic on file.\n", filename);
		flash_free(flash);
		return 0;
	}
	
	if(!flash_detect_key(flash, Bootloader_Keys, MPK_KNOWN_DEVICES, &file_device)) {
		printf("WARNING: %s: Signature is invalid.\n", filename);
	}
	else {
		if(detected_device != file_device) {
			printf("WARNING: %s: The detected device type for this file does not match the .aos device type (detected %s).\n", filename, mpk_device_type(file_device));
		}
		else {
			if(verbose)
				printf("\t%s: Signature is valid, detected device type %s\n", filename, mpk_device_type(file_device));
		}
	}
	
	strcpy(cramfs_name, filename);
	cramfs_name[strlen(cramfs_name)-strlen(".secure")] = 0;
	
	log_write("unpack.sh", "## .cramfs.secure: %s\n", filepath);
	log_write("unpack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
	log_write("unpack.sh", "mkdir -p unpacked\n");
	if(*(uint32_t *)&flash->header->data[0] == 0x28cd3d45 /* CRAMFS_MAGIC */) {
		/* this is a cramfs with a small header (0x100 bytes), which is nonstandard for a cramfs file. */
		log_write("unpack.sh", "dd if=%s of=unpacked/%s.stripped bs=256 skip=1\n", filepath, cramfs_name);
		log_write("unpack.sh", "(cd unpacked/ && cramfsck -v -x %s %s.stripped)\n", cramfs_name, cramfs_name);
		log_write("unpack.sh", "rm unpacked/%s.stripped\n", cramfs_name);
	} else {
		/* this is a cramfs file with either no header or a standard cramfs header (0x200 bytes). */
		log_write("unpack.sh", "cramfsck -x unpacked/%s %s\n", cramfs_name, filepath);
	}
	log_write("unpack.sh", "\n");
	
	log_write("repack.sh", "## .cramfs.secure: %s\n", filepath);
	if(*(uint32_t *)&flash->header->data[0] == 0x28cd3d45 /* CRAMFS_MAGIC */) {
		log_write("repack.sh", "mkcramfs unpacked/%s unpacked/%s.tmp\n", cramfs_name, cramfs_name);
		log_write("repack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
		log_write("repack.sh", "aos-fix --add-header unpacked/%s.tmp\n", cramfs_name);
		log_write("repack.sh", "mv unpacked/%s.tmp unpacked/%s.secure\n", cramfs_name, cramfs_name);
	} else {
		// create a cramfs with padding for the header, and write the header in-place
		log_write("repack.sh", "mkcramfs -p unpacked/%s unpacked/%s.secure\n", cramfs_name, cramfs_name);
		log_write("repack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
		log_write("repack.sh", "aos-fix --add-header --overwrite unpacked/%s.secure\n", cramfs_name);
	}
	log_write("repack.sh", "mv unpacked/%s.secure %s\n", cramfs_name, filepath);
	log_write("repack.sh", "\n");
	
	flash_free(flash);
	
	return 1;
}