FreeCalypso > hg > freecalypso-reveng
diff mysteryffs/scan1.c @ 21:d41c555d7f1d
beginning to explore MysteryFFS
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 18 May 2013 08:22:15 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mysteryffs/scan1.c Sat May 18 08:22:15 2013 +0000 @@ -0,0 +1,174 @@ +/* + * 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); +}