Example #1
0
char * get(Url *u) {
  extern Prefs prefs;

  CURL *curl;
  CURLcode res;
  FILE *outfile;
  char *outfilename = prefs.tmpfile;
  
  curl = curl_easy_init();
  if (curl) {
    int success = 0;

    if (prefs.archive) {
      outfilename = datestamp_filename();
    }

    outfile = fopen(outfilename, "w");
    
    /* Really, this should have a max counter for retries so we
     * don't get all spammy with trying to get a broken image
     * over and over and over */
    while (!success) {
      curl_easy_setopt(curl, CURLOPT_URL, u->urlstring);
    if (prefs.userpass != NULL) {
      curl_easy_setopt(curl, CURLOPT_USERPWD, prefs.userpass);
    }
    curl_easy_setopt(curl, CURLOPT_FILE, outfile);
    res = curl_easy_perform(curl);
  
    success = verify_image(outfile);
    }

    fclose (outfile);
    curl_easy_cleanup(curl);
    
  }
  return outfilename;
}
Example #2
0
/*
Returns -1 if somethings fails otherwise 0
*/
int check_image(char* in){

	/*
	Load an image at given path
	*/
	FILE *imageinput;
	imageinput = fopen(in, "rb");

	if (imageinput == NULL){
		std::cerr << "[ ERROR ] Image does not exist at given location" << std::endl;
		return -1;
	}

	/*
	Check if file has contents
	*/
	unsigned imagefilesize = get_file_size(imageinput);
	if (imagefilesize == 0){
		std::cerr << "[ ERROR ] Image has no size" << std::endl;
		return -1;
	}

	/*
	Load image in buffer and close file
	*/
	unsigned char* image = NULL;
	image = (unsigned char*)malloc(imagefilesize);
	
	fread(image, imagefilesize, 1, imageinput);
	fclose(imageinput);

	/*
	Extract image header
	*/
	boot_img_hdr* hdr = NULL;
	hdr = (boot_img_hdr*)malloc(sizeof(boot_img_hdr));
	memcpy(hdr, image, sizeof(boot_img_hdr));

	
	/*
	Check if image is an Android bootimage
	*/
	if (memcmp((char*)hdr->magic, "ANDROID!", 8) != 0){
		std::cerr << "[ ERROR ] File is not an Android boot image" << std::endl;
		return -1;
	}

	/*
	Load necessary variables from header and delete header
	*/
	unsigned kernel_actual;
	unsigned ramdisk_actual;
	unsigned imagesize_actual;
	unsigned dt_actual;
	unsigned page_size = hdr->page_size;
	unsigned page_mask = hdr->page_size - 1;

	kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
	dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);

	free(hdr);
	/*
	Calculate size of the "real" image
	*/
	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual) ;

	/*
	If the "real" image is bigger than the file, the file is probably corrupted
	*/
	if (imagefilesize < imagesize_actual){
		std::cerr << "[ ERROR ] File is invalid (is it corrupted?)" << std::endl;
		return -1;
	}

	/*
	Verify the image.
	*/
	verify_image(image, image + imagesize_actual, imagesize_actual);
	
	return 0;
}
Example #3
0
/*
Returns -1 if somethings fails otherwise 0
*/
int sign_image(char* in, char* out){

	/*
	An int is enough because the partitions shouldn't be bigger than 4GB
	*/
	int finalimagesize = 0;
	/*
	Load an image at given path
	*/
	FILE *imageinput;
	imageinput = fopen(in, "rb");

	if (imageinput == NULL){
		std::cerr << "[ ERROR ] Image does not exist at given location" << std::endl;
		return -1;
	}

	/*
	Check if file has contents
	*/
	unsigned imagefilesize = get_file_size(imageinput);
	if (imagefilesize == 0){
		std::cerr << "[ ERROR ] Image has no size" << std::endl;
		return -1;
	}

	/*
	Extract image header first to determine if the final image is bigger than the orignal
	*/
	boot_img_hdr* hdr = NULL;
	hdr = (boot_img_hdr*)malloc(sizeof(boot_img_hdr));
	fread(hdr, sizeof(boot_img_hdr), 1, imageinput);

	/*
	Reposition pointer at start
	*/
	fseek(imageinput, 0, SEEK_SET);


	/*
	Check if image is an Android bootimage
	*/
	if (memcmp((char*)hdr->magic, "ANDROID!", 8) != 0){
		std::cerr << "[ ERROR ] File is not an Android boot image" << std::endl;
		return -1;
	}

	/*
	Load necessary variables from header and delete header
	*/
	unsigned kernel_actual;
	unsigned ramdisk_actual;
	unsigned imagesize_actual;
	unsigned dt_actual;
	unsigned page_size = hdr->page_size;
	unsigned page_mask = hdr->page_size - 1;

	kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
	dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
	free(hdr);

	/*
	Calculate size of the "real" image
	*/
	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);

	/*
	If the "real" image is bigger than the file, the file is probably corrupted
	*/
	if (imagefilesize < imagesize_actual){
		std::cerr << "[ ERROR ] File is invalid (is it corrupted?)" << std::endl;
		return -1;
	}

	/*
	If the file is smaller than the "real" image + one page, a buffer with the size of the image would be too small we need allocate a new bigger one
	*/
	if (imagefilesize < imagesize_actual + page_size){
		finalimagesize = imagefilesize + page_size;
	} else {
		finalimagesize = imagefilesize;
	}

	/*
	Load image in buffer and close file
	*/
	unsigned char* image = NULL;
	image = (unsigned char*)malloc(finalimagesize);
	fread(image, 1, imagefilesize, imageinput);
	fclose(imageinput);


	/*
	Create output file
	*/
	FILE *imageoutput;
	imageoutput = fopen(out, "wb");

	if (imageoutput == NULL){
		std::cerr << "[ ERROR ] Can't write output image to disk" << std::endl;
		return -1;
	}

	/*
	Hash the real image
	*/
	unsigned char hash[65];
	unsigned char signature[SIGNATURE_SIZE];
	memset(signature, 0, SIGNATURE_SIZE);
	sha256_buffer(image, imagesize_actual, hash);

	/*
	Create signature with given hash
	*/
	int sig = create_signature(hash, signature);

	/*
	If the signature is created successfully AND the signature passes the check, the signature will be written into the image buffer, which will written to the output file
	*/
	if (sig != -1){
		std::cerr << std::endl << "[ STATUS ] Checking created signature... ";
		if (verify_image(image, signature, imagesize_actual) == 0){
			memcpy(image + imagesize_actual, signature, SIGNATURE_SIZE);
			fwrite(image, finalimagesize, 1, imageoutput);
		}
	} 

	/*
	Cleanup
	*/
	fclose(imageoutput);
	free(image);

	/*
	Final check of the output file
	*/
	std::cerr << std::endl << "[ STATUS ] Checking created image... ";
	check_image(out);

	return 0;
}
Example #4
0
int elf_load(struct sys_info *info, const char *filename, const char *cmdline)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long phdr_size;
    unsigned long checksum_offset;
    unsigned short checksum = 0;
    Elf_Bhdr *boot_notes = NULL;
    int retval = -1;
    int image_retval;

    image_name = image_version = NULL;

    if (!file_open(filename))
	goto out;

    if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
	debug("Can't read ELF header\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS
	    || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_type != ET_EXEC
	    || !ARCH_ELF_MACHINE_OK(ehdr.e_machine)
	    || ehdr.e_version != EV_CURRENT
	    || ehdr.e_phentsize != sizeof(Elf_phdr)) {
	debug("Not a bootable ELF image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    phdr_size = ehdr.e_phnum * sizeof *phdr;
    phdr = malloc(phdr_size);
    file_seek(ehdr.e_phoff);
    if (lfile_read(phdr, phdr_size) != phdr_size) {
	printk("Can't read program header\n");
	goto out;
    }

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
	goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum);

    printk("Loading %s", image_name ? image_name : "image");
    if (image_version)
	printk(" version %s", image_version);
    printk("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset))
	goto out;

    if (checksum_offset) {
	if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
	    goto out;
    }

    boot_notes = build_boot_notes(info, cmdline);

    //debug("current time: %lu\n", currticks());

    debug("entry point is %#x\n", ehdr.e_entry);
    printk("Jumping to entry point...\n");
    image_retval = start_elf(ehdr.e_entry & ADDRMASK, virt_to_phys(boot_notes));

    // console_init(); FIXME
    printk("Image returned with return value %#x\n", image_retval);
    retval = 0;

out:
    if (phdr)
	free(phdr);
    if (boot_notes)
	free(boot_notes);
    if (image_name)
	free(image_name);
    if (image_version)
	free(image_version);
    return retval;
}
Example #5
0
int
elf_load(struct sys_info *info, ihandle_t dev, const char *cmdline, void **boot_notes)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long checksum_offset, file_size;
    unsigned short checksum = 0;
    int retval = -1;
    unsigned int offset;

    image_name = image_version = NULL;

    /* Mark the saved-program-state as invalid */
    feval("0 state-valid !");

    fd = open_ih(dev);
    if (fd == -1) {
        goto out;
    }

    offset = find_elf(&ehdr);
    if (!offset) {
        retval = LOADER_NOT_SUPPORT;
        goto out;
    }

#if DEBUG
    printk("ELF header:\n");
    printk(" ehdr.e_type    = %d\n", (int)ehdr.e_type);
    printk(" ehdr.e_machine = %d\n", (int)ehdr.e_machine);
    printk(" ehdr.e_version = %d\n", (int)ehdr.e_version);
    printk(" ehdr.e_entry   = 0x%08x\n", (int)ehdr.e_entry);
    printk(" ehdr.e_phoff   = 0x%08x\n", (int)ehdr.e_phoff);
    printk(" ehdr.e_shoff   = 0x%08x\n", (int)ehdr.e_shoff);
    printk(" ehdr.e_flags   = %d\n", (int)ehdr.e_flags);
    printk(" ehdr.e_ehsize  = 0x%08x\n", (int)ehdr.e_ehsize);
    printk(" ehdr.e_phentsize = 0x%08x\n", (int)ehdr.e_phentsize);
    printk(" ehdr.e_phnum   = %d\n", (int)ehdr.e_phnum);
#endif

    if (ehdr.e_phnum > MAX_HEADERS) {
        printk ("elfload: too many program headers (MAX_HEADERS)\n");
        retval = 0;
        goto out;
    }

    phdr = elf_readhdrs(offset, &ehdr);
    if (!phdr)
        goto out;

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
        goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset);

    printf("Loading %s", image_name ? image_name : "image");
    if (image_version)
        printf(" version %s", image_version);
    printf("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset, &file_size))
        goto out;

    if (checksum_offset) {
        if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
            goto out;
    }

    /* If we are attempting an ELF boot image, we pass a non-NULL pointer
       into boot_notes and mark the image as elf-boot rather than standard
       ELF */
    if (boot_notes) {
        *boot_notes = (void *)virt_to_phys(build_boot_notes(info, cmdline));
        feval("elf-boot saved-program-state >sps.file-type !");
    } else {
        feval("elf saved-program-state >sps.file-type !");
    }

    //debug("current time: %lu\n", currticks());

    debug("entry point is " FMT_elf "\n", addr_fixup(ehdr.e_entry));

    // Initialise saved-program-state
    PUSH(addr_fixup(ehdr.e_entry));
    feval("saved-program-state >sps.entry !");
    PUSH(file_size);
    feval("saved-program-state >sps.file-size !");

    feval("-1 state-valid !");

out:
    close_io(fd);
    if (phdr)
        free(phdr);
    if (image_name)
        free(image_name);
    if (image_version)
        free(image_version);
    return retval;
}
Example #6
0
int elf_load(struct sys_info *info, const char *filename, const char *cmdline)
{
    Elf_ehdr ehdr;
    Elf_phdr *phdr = NULL;
    unsigned long phdr_size;
    unsigned long checksum_offset;
    unsigned short checksum = 0;
    Elf_Bhdr *boot_notes = NULL;
    int retval = -1;
    int image_retval;
    unsigned int offset;

    image_name = image_version = NULL;

    if (!file_open(filename))
	goto out;

    for (offset = 0; offset < 16 * 512; offset += 512) {
        if ((size_t)lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) {
            debug("Can't read ELF header\n");
            retval = LOADER_NOT_SUPPORT;
            goto out;
        }

        if (ehdr.e_ident[EI_MAG0] == ELFMAG0)
            break;

        file_seek(offset);
    }

    if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS
	    || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_type != ET_EXEC
	    || !ARCH_ELF_MACHINE_OK(ehdr.e_machine)
	    || ehdr.e_version != EV_CURRENT
	    || ehdr.e_phentsize != sizeof(Elf_phdr)) {
	debug("Not a bootable ELF image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    phdr_size = ehdr.e_phnum * sizeof *phdr;
    phdr = malloc(phdr_size);
    file_seek(offset + ehdr.e_phoff);
    if ((unsigned long)lfile_read(phdr, phdr_size) != phdr_size) {
	printf("Can't read program header\n");
	goto out;
    }

    if (!check_mem_ranges(info, phdr, ehdr.e_phnum))
	goto out;

    checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset);

    printf("Loading %s", image_name ? image_name : "image");
    if (image_version)
	printf(" version %s", image_version);
    printf("...\n");

    if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset))
	goto out;

    if (checksum_offset) {
	if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum))
	    goto out;
    }

    boot_notes = build_boot_notes(info, cmdline);

    //debug("current time: %lu\n", currticks());

    debug("entry point is %#llx\n", addr_fixup(ehdr.e_entry));
    printf("Jumping to entry point...\n");

#if 0
    {
        extern unsigned int qemu_mem_size;
        extern char boot_device;
        void *init_openprom(unsigned long memsize, const char *cmdline, char boot_device);

        int (*entry)(const void *romvec, int p2, int p3, int p4, int p5);
        const void *romvec;

        romvec = init_openprom(qemu_mem_size, cmdline, boot_device);
        entry = (void *) addr_fixup(ehdr.e_entry);
        image_retval = entry(romvec, 0, 0, 0, 0);
    }
#else
    image_retval = start_elf(addr_fixup(ehdr.e_entry), virt_to_phys(boot_notes));
#endif

    // console_init(); FIXME
    printf("Image returned with return value %#x\n", image_retval);
    retval = 0;

out:
    file_close();
    if (phdr)
	free(phdr);
    if (boot_notes)
	free(boot_notes);
    if (image_name)
	free(image_name);
    if (image_version)
	free(image_version);
    return retval;
}