FreeCalypso > hg > freecalypso-reveng
view mysteryffs/scan1.c @ 312:6cba849e3332
frbl/reconst/inc: import from TCS211 surviving source
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 04 Mar 2020 23:06:07 +0000 |
parents | d41c555d7f1d |
children |
line wrap: on
line source
/* * This program is the first MysteryFFS analysis tool written. * Here I'm trying to understand the meaning of various fields * in the index block records. */ #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> #include <endian.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <unistd.h> typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; u8 blank_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; u8 mysteryffs_hdr[6] = {'F', 'f', 's', '#', 0x10, 0x02}; struct index_entry { u16 len; u8 unknown1; u8 type; u16 nptr1; u16 nptr2; u32 dataptr; u16 unknown2; u16 version; }; char *imgfile; u32 eraseblk_size; int total_blocks; u32 total_img_size; u8 *image, *indexblk; read_img_file() { int fd; struct stat st; fd = open(imgfile, O_RDONLY); if (fd < 0) { perror(imgfile); exit(1); } fstat(fd, &st); if (!S_ISREG(st.st_mode)) { fprintf(stderr, "%s is not a regular file\n", imgfile); exit(1); } if (st.st_size < total_img_size) { fprintf(stderr, "%s has fewer than 0x%x bytes\n", imgfile, total_img_size); exit(1); } image = malloc(total_img_size); if (!image) { perror("malloc"); exit(1); } read(fd, image, total_img_size); close(fd); } find_index_block() { int i; u8 *ptr; for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) { if (bcmp(ptr, mysteryffs_hdr, 6)) continue; if (ptr[8] != 0xAB) continue; indexblk = ptr; return(0); } fprintf(stderr, "could not find a MysteryFFS index block in %s\n", imgfile); exit(1); } is_namestr_ok(s) char *s; { int cnt; for (cnt = 0; *s; s++, cnt++) { if (cnt >= 32) return(0); if (!isprint(*s)) return(0); } if (cnt) return(1); else return(0); } char * dataptr_to_name(dptr) u32 dptr; { u8 *data; if (dptr > 0x0FFFFFFF) { inv: return("<invptr>"); } dptr <<= 4; if (dptr >= total_img_size) goto inv; data = image + dptr; if (is_namestr_ok(data)) return(data); else return("<notname>"); } dump_entry(rawptr, entrynum) u8 *rawptr; { struct index_entry ent; bcopy(rawptr, &ent, 0x10); ent.len = le16toh(ent.len); ent.nptr1 = le16toh(ent.nptr1); ent.nptr2 = le16toh(ent.nptr2); ent.dataptr = le32toh(ent.dataptr); ent.unknown2 = le16toh(ent.unknown2); ent.version = le16toh(ent.version); printf("%x %s: len=%x %02X %02X nptr1=%x nptr2=%x %04X %04X\n", entrynum, dataptr_to_name(ent.dataptr), ent.len, ent.unknown1, ent.type, ent.nptr1, ent.nptr2, ent.unknown2, ent.version); } dump_index() { u32 offset; u8 *entry; for (offset = 0x10; offset < eraseblk_size; offset += 0x10) { entry = indexblk + offset; if (!bcmp(entry, blank_line, 16)) continue; dump_entry(entry, offset >> 4); } } main(argc, argv) char **argv; { if (argc != 4) { fprintf(stderr, "usage: %s imgfile blksize nblocks\n", argv[0]); exit(1); } imgfile = argv[1]; eraseblk_size = strtoul(argv[2], 0, 0); total_blocks = strtoul(argv[3], 0, 0); total_img_size = eraseblk_size * total_blocks; read_img_file(); find_index_block(); dump_index(); exit(0); }