int pack_krnl(FILE *fp_in, FILE *fp_out) { char buf[1024]; struct krnl_header header = { MAGIC_CODE, 0 }; unsigned int crc = 0; fwrite(&header, sizeof(header), 1, fp_out); while (1) { int readlen = fread(buf, 1, sizeof(buf), fp_in); if (readlen == 0) break; header.length += readlen; fwrite(buf, 1, readlen, fp_out); RKCRC(crc, buf, readlen); } fwrite(&crc, sizeof(crc), 1, fp_out); fseek(fp_out, 0, SEEK_SET); fwrite(&header, sizeof(header), 1, fp_out); printf("%04X\n", crc); return 0; //fail: fprintf(stderr, "FAIL\n"); return -1; }
int import_package(FILE *ofp, struct update_part *pack, const char *path) { FILE *ifp; char buf[2048]; size_t readlen; pack->pos = ftell(ofp); ifp = fopen(path, "r"); if (!ifp) return -1; if (strcmp(pack->name, "parameter") == 0) { unsigned int crc; struct param_header *header = (struct param_header*)buf; strcpy(header->magic, "PARM"); readlen = fread(buf + sizeof(*header), 1, sizeof(buf) - 12, ifp); header->length = readlen; RKCRC(crc, buf + sizeof(*header), readlen); readlen += sizeof(*header); memcpy(buf + readlen, &crc, sizeof(crc)); readlen += sizeof(crc); memset(buf+readlen, 0, sizeof(buf) - readlen); fwrite(buf, 1, sizeof(buf), ofp); pack->size += readlen; pack->padded_size += sizeof(buf); } else { do { readlen = fread(buf, 1, sizeof(buf), ifp); if (readlen == 0) break; if (readlen < sizeof(buf)) memset(buf + readlen, 0, sizeof(buf) - readlen); fwrite(buf, 1, sizeof(buf), ofp); pack->size += readlen; pack->padded_size += sizeof(buf); } while (!feof(ifp)); } fclose(ifp); return 0; }
void append_crc(const char* filename) { int fd = -1; unsigned int crc = 0; size_t file_len = 0; void *buf = MAP_FAILED; fd = open(filename, O_RDWR); if (fd == -1) { fprintf(stderr, "can't open file \"%s\": %s\n", filename, strerror(errno)); goto fail; } file_len = lseek(fd, 0, SEEK_END); if (file_len == (size_t) -1) goto fail; buf = mmap(NULL, file_len, PROT_READ, MAP_SHARED | MAP_FILE, fd, 0); if (buf == MAP_FAILED) { perror("Error mmap"); goto fail; } printf("Add CRC...\n"); RKCRC(crc, buf, file_len); munmap(buf, file_len); lseek(fd, 0, SEEK_END); write(fd, &crc, sizeof(crc)); close(fd); fail: if (fd != -1) { if (buf != MAP_FAILED) munmap(buf, file_len); close(fd); } }
unsigned int filestream_crc(FILE *fs, size_t stream_len) { char buffer[1024]; unsigned int crc = 0; while (stream_len) { int read_len = stream_len < sizeof(buffer) ? stream_len : sizeof(buffer); read_len = fread(buffer, 1, read_len, fs); if (!read_len) break; RKCRC(crc, buffer, read_len); stream_len -= read_len; } return crc; }
int unpack_krnl(FILE *fp_in, FILE *fp_out) { char buf[1024]; struct krnl_header header; size_t length = 0; unsigned int crc = 0; unsigned int file_crc = 0; fprintf(stderr, "unpacking..."); fflush(stderr); if (sizeof(header) != fread(&header, 1, sizeof(header), fp_in)) { goto fail; } fseek(fp_in, header.length + sizeof(header), SEEK_SET); if (sizeof(file_crc) != fread(&file_crc, 1, sizeof(file_crc), fp_in)) goto fail; length = header.length; fseek(fp_in, sizeof(header), SEEK_SET); while (length > 0) { int readlen = length < sizeof(buf) ? length : sizeof(buf); readlen = fread(buf, 1, readlen, fp_in); length -= readlen; fwrite(buf, 1, readlen, fp_out); RKCRC(crc, buf, readlen); if (readlen == 0) break; } if (file_crc != crc) fprintf(stderr, "WARNING: bad crc checksum\n"); fprintf(stderr, "OK\n"); return 0; fail: fprintf(stderr, "FAIL\n"); return -1; }
int check_update(const unsigned char *data, size_t data_len) { unsigned int stored_crc = 0, crc = 0; printf("Check file... "); fflush(stdout); if (data_len < 4) goto check_failed; memcpy(&stored_crc, &data[data_len - 4], 4); RKCRC(crc, data, data_len - 4); if (crc != stored_crc) goto check_failed; printf("OK\n"); return 0; check_failed: printf("Failed\n"); return -1; }
int main(int argc, char *argv[]) { ssize_t nr; uint32_t crc, ocrc, size; uint8_t *buf, *end; int in, out, type; if (argc != 3) { fprintf(stderr, "usage: %s infile outfile\n", argv[0]); exit(EXIT_FAILURE); } if ((in = open(argv[1], O_RDONLY)) == -1) err(EXIT_FAILURE, "%s", argv[1]); if ((buf = malloc(_BLOCKSIZE)) == NULL) err(EXIT_FAILURE, "malloc"); if ((nr = read(in, buf, _BLOCKSIZE)) == -1 || nr == 0) err(EXIT_FAILURE, "read"); if (buf[0] == 0x45 && buf[1] == 0x3d && buf[2] == 0xcd && buf[3] == 0x28) { printf("cramfs"); type = T_CRAMFS; } else if (buf[0] == 'K' && buf[1] == 'R' && buf[2] == 'N' && buf[3] == 'L') { printf("kernel.img"); type = T_KERNEL; } else if (buf[0] == 'P' && buf[1] == 'A' && buf[2] == 'R' && buf[3] == 'M') { printf("parameter"); type = T_PARAMETER; } else if (buf[0] == 'R' && buf[1] == 'K' && buf[2] == 'A' && buf[3] == 'F') { printf("update.img"); type = T_UPDATE_AF; } else if (strncmp((void*)buf, "ANDROID!", 8) == 0) { printf("android"); type = T_ANDROID; } else { fprintf(stderr, "unknown image (%02x %02x %02x %02x)\n", buf[0], buf[1], buf[2], buf[3]); exit(EXIT_FAILURE); } size = buf[4] | buf[5] << 8 | buf[6] << 16 | buf[7] << 24; if (type == T_KERNEL || type == T_PARAMETER) size += 8; else if (type == T_ANDROID) { unsigned pgsz, pages; pgsz = buf[36] | buf[37] << 8 | buf[38] << 16 | buf[39] << 24; pages = 1 /* header */ + ((buf[8] | buf[9] << 8 | buf[10] << 16 | buf[11] << 24) + pgsz - 1) / pgsz + /* kernel */ ((buf[16] | buf[17] << 8 | buf[18] << 16 | buf[19] << 24) + pgsz - 1) / pgsz + /* ramdisk */ ((buf[24] | buf[25] << 8 | buf[26] << 16 | buf[27] << 24) + pgsz - 1) / pgsz; /* second */ size = pages * pgsz; } printf(" found (%u bytes)\n", size); if ((out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) err(EXIT_FAILURE, "%s", argv[2]); printf("dumping...\n"); if (size < (uint32_t)nr) nr = size; crc = 0; if (type == T_CRAMFS || type == T_UPDATE_AF) RKCRC(crc, buf, nr); else RKCRC(crc, &buf[8], nr - 8); if (type != T_PARAMETER) write(out, buf, nr); else write(out, &buf[8], nr - 8); size -= nr; while (size > 0) { if ((nr = read(in, buf, _BLOCKSIZE)) == -1 || nr == 0) break; if (size < (uint32_t)nr) nr = size; RKCRC(crc, buf, nr); write(out, buf, nr); size -= nr; } if (nr == _BLOCKSIZE) { if ((nr = read(in, buf, _BLOCKSIZE)) == -1 || nr == 0) goto end; nr = 0; } if (type != T_ANDROID) { ocrc = buf[nr] | buf[nr + 1] << 8 | buf[nr + 2] << 16 | buf[nr + 3] << 24; if (crc != ocrc) goto end; printf("crc found (4 bytes, 0x%08x)\n", ocrc); if (type != T_PARAMETER) write(out, &buf[nr], 4); nr += 4; } if (type == T_KERNEL) { if (nr != _BLOCKSIZE) { if ((end = memchr(&buf[nr], '\0', _BLOCKSIZE - nr)) == NULL) write(out, &buf[nr], _BLOCKSIZE - nr); else { write(out, &buf[nr], end - &buf[nr]); goto end; } } while ((nr = read(in, buf, _BLOCKSIZE)) != -1 && nr != 0) { if ((end = memchr(buf, '\0', nr)) == NULL) write(out, buf, nr); else { write(out, buf, end - buf); goto end; } } } end: printf("done\n"); close(out); free(buf); close(in); return EXIT_SUCCESS; }