Esempio n. 1
0
static int
unpack_image(const char *infn, const char *outdn)
{
    struct imagewty_header *header;
    FILE *ifp, *lfp, *ofp;
    void *image, *curr;
    long imagesize;
    int i;

    ifp = fopen(infn, "rb");
    if (ifp == NULL) {
        fprintf(stderr, "Error: unable to open %s!\n", infn);
        return 2;
    }

    fseek(ifp, 0, SEEK_END);
    imagesize = ftell(ifp);
    fseek(ifp, 0, SEEK_SET);

    if (imagesize <= 0) {
        fprintf(stderr, "Error: Invalid file size %ld (%s)\n",
            imagesize, strerror(errno));
        return 3;
    }

    image = malloc(imagesize);
    if (!image) {
        fprintf(stderr, "Error: Unable to allocate memory for image: %ld\n", imagesize);
        return 4;
    }

    fread(image, imagesize, 1, ifp);
    fclose(ifp);

    /* Decrypt header (padded to 1024 bytes) */
    curr = rc6_decrypt_inplace(image, 1024, &header_ctx);

    /* Decrypt file headers */
    header = (struct imagewty_header*)image;
    curr = rc6_decrypt_inplace(curr, header->num_files * 1024, &fileheaders_ctx);

    /* Decrypt file contents */
    for (i=0; i < header->num_files; i++) {
        struct imagewty_file_header *filehdr;
        void *next;

        filehdr = (struct imagewty_file_header*)(image + 1024 + (i * 1024));
        next = rc6_decrypt_inplace(curr, filehdr->stored_length, &filecontent_ctx);
#if TF_DECRYPT_WORKING
        if (!(strlen(filehdr->filename) >= 4 &&
            strncmp(filehdr->filename + strlen(filehdr->filename) -4, ".fex", 4) == 0)) {
            /* Not a 'FEX' file, so we need to decrypt it even more! */
            tf_decrypt_inplace(curr, filehdr->stored_length);
        }
#endif
        curr = next;
    }

    if (flag_compat_output == OUTPUT_UNIMG) {
        lfp = dir_fopen(outdn, "base.hdr", "wb");
        if (lfp) {
            uint32_t *hdr = image + IMAGEWTY_MAGIC_LEN;
            fprintf(lfp, "%.8s\r\n", header->magic);
            for (i = 0; i < (sizeof(*header) - IMAGEWTY_MAGIC_LEN) / sizeof(uint32_t); i++)
                fprintf(lfp, "%08X\r\n", hdr[i]);
            fclose(lfp);
        }

        lfp = dir_fopen(outdn, "Filelist.txt", "wb");
    } else if (flag_compat_output == OUTPUT_IMGREPACKER) {
        lfp = dir_fopen(outdn, "image.cfg", "wb");
        if (lfp != NULL) {
            char timestr[256];
            struct tm *tm;
            time_t t;
            time(&t);
            tm = localtime(&t);
            strcpy(timestr, asctime(tm));
            /* strip newline */
            timestr[strlen(timestr) -1] = '\0';

            fputs(";/**************************************************************************/\r\n", lfp);
            fprintf(lfp, "; %s\r\n", timestr);
            fprintf(lfp, "; generated by %s\r\n", progname);
            fprintf(lfp, "; %s\r\n", infn);
            fputs(";/**************************************************************************/\r\n", lfp);
            fputs("[FILELIST]\r\n", lfp);
        }
    }

    for (i=0; i < header->num_files; i++) {
        struct imagewty_file_header *filehdr;
        char hdrfname[32], contfname[32];

        filehdr = (struct imagewty_file_header*)(image + 1024 + (i * 1024));
        if (flag_compat_output == OUTPUT_UNIMG) {
            printf("Extracting: %.8s %.16s (%u, %u)\n", 
                filehdr->maintype, filehdr->subtype,
                filehdr->original_length, filehdr->stored_length);

            sprintf(hdrfname, "%.8s_%.16s.hdr", filehdr->maintype, filehdr->subtype);
            ofp = dir_fopen(outdn, hdrfname, "wb");
            if (ofp) {
                fwrite(filehdr, filehdr->total_header_size, 1, ofp);
                fclose(ofp);
            }

            sprintf(contfname, "%.8s_%.16s", filehdr->maintype, filehdr->subtype);
            ofp = dir_fopen(outdn, contfname, "wb");
            if (ofp) {
                fwrite(image + filehdr->offset, filehdr->original_length, 1, ofp);
                fclose(ofp);
            }

            fprintf(lfp, "%s\t%s\r\n", hdrfname, contfname);
        } else if (flag_compat_output == OUTPUT_IMGREPACKER) {
	    printf("Extracting %s\n", filehdr->filename);

            ofp = dir_fopen(outdn, filehdr->filename, "wb");
            if (ofp) {
                fwrite(image + filehdr->offset, filehdr->original_length, 1, ofp);
                fclose(ofp);
            }

            fprintf(lfp, "\t{filename = INPUT_DIR .. \"%s\", maintype = \"%.8s\", subtype = \"%.16s\",},\r\n",
                filehdr->filename[0] == '/' ? filehdr->filename+1 : filehdr->filename,
                filehdr->maintype, filehdr->subtype);
        }
    }

    if (lfp && flag_compat_output == OUTPUT_IMGREPACKER) {
        /* Now print the relevant stuff for the image.cfg */
        fputs("\r\n[IMAGE_CFG]\r\n", lfp);
        fprintf(lfp, "version = 0x%06x\r\n", header->version);
        fprintf(lfp, "pid = 0x%08x\r\n", header->pid);
        fprintf(lfp, "vid = 0x%08x\r\n", header->vid);
        fprintf(lfp, "hardwareid = 0x%03x\r\n", header->hardware_id);
        fprintf(lfp, "firmwareid = 0x%03x\r\n", header->firmware_id);
        fprintf(lfp, "imagename = %s\r\n", infn);
        fputs("filelist = FILELIST\r\n", lfp);
    }

    if (lfp)
        fclose(lfp);

    return 0;
}
Esempio n. 2
0
static int
decrypt_image(const char *infn, const char *outfn)
{
    int num_files, pid, vid, hardware_id, firmware_id;
    struct imagewty_header *header;
    void *image, *curr;
    FILE *ifp, *ofp;
    long imagesize;
    int i;

    ifp = fopen(infn, "rb");
    if (ifp == NULL) {
        fprintf(stderr, "Error: unable to open %s!\n", infn);
        return 2;
    }

    fseek(ifp, 0, SEEK_END);
    imagesize = ftell(ifp);
    fseek(ifp, 0, SEEK_SET);

    if (imagesize <= 0) {
        fprintf(stderr, "Error: Invalid file size %ld (%s)\n",
            imagesize, strerror(errno));
        return 3;
    }

    image = malloc(imagesize);
    if (!image) {
        fprintf(stderr, "Error: Unable to allocate memory for image: %ld\n", imagesize);
        return 4;
    }

    fread(image, imagesize, 1, ifp);
    fclose(ifp);

    /* Check for encryption; see bug #2 (A31 unencrypted images) */
    header = (struct imagewty_header*)image;
    if (memcmp(header->magic, IMAGEWTY_MAGIC, IMAGEWTY_MAGIC_LEN) == 0)
        flag_encryption_enabled = 0;

    /* Decrypt header (padded to 1024 bytes) */
    curr = rc6_decrypt_inplace(image, 1024, &header_ctx);


    /* Check version of header and setup our local state */
    if (header->header_version == 0x0300) {
        num_files = header->v3.num_files;
        hardware_id = header->v3.hardware_id;
        firmware_id = header->v3.firmware_id;
        pid = header->v3.pid;
        vid = header->v3.vid;
    } else /*if (header->header_version == 0x0100)*/ {
        num_files = header->v1.num_files;
        hardware_id = header->v1.hardware_id;
        firmware_id = header->v1.firmware_id;
        pid = header->v1.pid;
        vid = header->v1.vid;
    }

    /* Decrypt file headers */
    curr = rc6_decrypt_inplace(curr, num_files * 1024, &fileheaders_ctx);

    /* Decrypt file contents */
    for (i=0; i < num_files; i++) {
        struct imagewty_file_header *filehdr;
	uint64_t stored_length;
	const char *filename;
        void *next;

        filehdr = (struct imagewty_file_header*)(image + 1024 + (i * 1024));
        if (header->header_version == 0x0300) {
            stored_length = filehdr->v3.stored_length;
            filename = filehdr->v3.filename;
        } else {
            stored_length = filehdr->v1.stored_length;
            filename = filehdr->v1.filename;
        }

        next = rc6_decrypt_inplace(curr, stored_length, &filecontent_ctx);
        if (TF_DECRYPT_WORKING &&
            !(strlen(filename) >= 4 &&
            strncmp(filename + strlen(filename) -4, ".fex", 4) == 0)) {
            /* Not a 'FEX' file, so we need to decrypt it even more! */
            tf_decrypt_inplace(curr, stored_length);
        }
        curr = next;
    }

    ofp = fopen(outfn, "wb");
    if (ofp == NULL) {
        fprintf(stderr, "Error: unable to open output file %s!\n", outfn);
        return 4;
    }

    fwrite(image, imagesize, 1, ofp);
    fclose(ofp);

    return 0;
}