comparison 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
comparison
equal deleted inserted replaced
20:a52e76c12e6b 21:d41c555d7f1d
1 /*
2 * This program is the first MysteryFFS analysis tool written.
3 * Here I'm trying to understand the meaning of various fields
4 * in the index block records.
5 */
6
7 #include <sys/types.h>
8 #include <sys/file.h>
9 #include <sys/stat.h>
10 #include <endian.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <strings.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17
18 typedef unsigned char u8;
19 typedef unsigned short u16;
20 typedef unsigned int u32;
21
22 u8 blank_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
23 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
24
25 u8 mysteryffs_hdr[6] = {'F', 'f', 's', '#', 0x10, 0x02};
26
27 struct index_entry {
28 u16 len;
29 u8 unknown1;
30 u8 type;
31 u16 nptr1;
32 u16 nptr2;
33 u32 dataptr;
34 u16 unknown2;
35 u16 version;
36 };
37
38 char *imgfile;
39 u32 eraseblk_size;
40 int total_blocks;
41 u32 total_img_size;
42 u8 *image, *indexblk;
43
44 read_img_file()
45 {
46 int fd;
47 struct stat st;
48
49 fd = open(imgfile, O_RDONLY);
50 if (fd < 0) {
51 perror(imgfile);
52 exit(1);
53 }
54 fstat(fd, &st);
55 if (!S_ISREG(st.st_mode)) {
56 fprintf(stderr, "%s is not a regular file\n", imgfile);
57 exit(1);
58 }
59 if (st.st_size < total_img_size) {
60 fprintf(stderr, "%s has fewer than 0x%x bytes\n", imgfile,
61 total_img_size);
62 exit(1);
63 }
64 image = malloc(total_img_size);
65 if (!image) {
66 perror("malloc");
67 exit(1);
68 }
69 read(fd, image, total_img_size);
70 close(fd);
71 }
72
73 find_index_block()
74 {
75 int i;
76 u8 *ptr;
77
78 for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) {
79 if (bcmp(ptr, mysteryffs_hdr, 6))
80 continue;
81 if (ptr[8] != 0xAB)
82 continue;
83 indexblk = ptr;
84 return(0);
85 }
86 fprintf(stderr, "could not find a MysteryFFS index block in %s\n",
87 imgfile);
88 exit(1);
89 }
90
91 is_namestr_ok(s)
92 char *s;
93 {
94 int cnt;
95
96 for (cnt = 0; *s; s++, cnt++) {
97 if (cnt >= 32)
98 return(0);
99 if (!isprint(*s))
100 return(0);
101 }
102 if (cnt)
103 return(1);
104 else
105 return(0);
106 }
107
108 char *
109 dataptr_to_name(dptr)
110 u32 dptr;
111 {
112 u8 *data;
113
114 if (dptr > 0x0FFFFFFF) {
115 inv: return("<invptr>");
116 }
117 dptr <<= 4;
118 if (dptr >= total_img_size)
119 goto inv;
120 data = image + dptr;
121 if (is_namestr_ok(data))
122 return(data);
123 else
124 return("<notname>");
125 }
126
127 dump_entry(rawptr, entrynum)
128 u8 *rawptr;
129 {
130 struct index_entry ent;
131
132 bcopy(rawptr, &ent, 0x10);
133 ent.len = le16toh(ent.len);
134 ent.nptr1 = le16toh(ent.nptr1);
135 ent.nptr2 = le16toh(ent.nptr2);
136 ent.dataptr = le32toh(ent.dataptr);
137 ent.unknown2 = le16toh(ent.unknown2);
138 ent.version = le16toh(ent.version);
139 printf("%x %s: len=%x %02X %02X nptr1=%x nptr2=%x %04X %04X\n",
140 entrynum, dataptr_to_name(ent.dataptr),
141 ent.len, ent.unknown1, ent.type,
142 ent.nptr1, ent.nptr2,
143 ent.unknown2, ent.version);
144 }
145
146 dump_index()
147 {
148 u32 offset;
149 u8 *entry;
150
151 for (offset = 0x10; offset < eraseblk_size; offset += 0x10) {
152 entry = indexblk + offset;
153 if (!bcmp(entry, blank_line, 16))
154 continue;
155 dump_entry(entry, offset >> 4);
156 }
157 }
158
159 main(argc, argv)
160 char **argv;
161 {
162 if (argc != 4) {
163 fprintf(stderr, "usage: %s imgfile blksize nblocks\n", argv[0]);
164 exit(1);
165 }
166 imgfile = argv[1];
167 eraseblk_size = strtoul(argv[2], 0, 0);
168 total_blocks = strtoul(argv[3], 0, 0);
169 total_img_size = eraseblk_size * total_blocks;
170 read_img_file();
171 find_index_block();
172 dump_index();
173 exit(0);
174 }