3 # AppleSingle/AppleDouble dump
5 # (c) 2009 by HAT <hat@fa2.so-net.ne.jp>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
18 use bigint; # require perl >= 5.8
20 open(INFILE, "<$ARGV[0]");
22 binmode(INFILE); # for DOS/Win
24 # Magic Number -----------------------------------------------
26 $rc = read(INFILE,$buf,4);
27 $val = unpack("N", $buf );
28 printf("Magic Num. : %08X", $val);
29 if ( $val == 0x00051600 ) {
30 printf(" : AppleSingle");
32 elsif ( $val == 0x00051607 ) {
33 printf(" : AppleDouble");
36 printf(" : Unknown" );
40 # Version Number ---------------------------------------------
42 $rc = read(INFILE,$buf,4);
43 $val = unpack("N", $buf );
44 printf("Ver. Num. : %08X", $val);
45 if ( $val == 0x00010000 ) {
46 printf(" : Version 1");
48 elsif ( $val == 0x00020000 ) {
49 printf(" : Version 2");
52 printf(" : Unknown" );
56 # v1:Home file system / v2:Filler ----------------------------
58 $rc = read(INFILE,$buf,16);
60 hexdump($buf, 16, 16, " ");
62 # Number of entities -----------------------------------------
64 $rc = read(INFILE,$buf,2);
65 $entnum = unpack("n", $buf );
66 printf("Num. of ent: %04X ", $entnum);
67 printf(" : %d", $entnum);
70 # data -------------------------------------------------------
72 for ( $num = 0 ; $num < $entnum ; $num++) {
74 seek(INFILE, ($num * 12 + 26), 0);
76 # Entry ---------------------------------------------------
78 $rc = read(INFILE,$buf,4);
79 $entid = unpack("N", $buf );
80 printf("\nEntry ID : %08X", $entid);
81 if ( $entid == 1 ) { printf(" : Data Fork"); }
82 elsif ( $entid == 2 ) { printf(" : Resource Fork"); }
83 elsif ( $entid == 3 ) { printf(" : Real Name"); }
84 elsif ( $entid == 4 ) { printf(" : Comment"); }
85 elsif ( $entid == 5 ) { printf(" : Icon, B&W"); }
86 elsif ( $entid == 6 ) { printf(" : Icon Color"); }
87 elsif ( $entid == 7 ) { printf(" : File Info"); }
88 elsif ( $entid == 8 ) { printf(" : File Dates Info"); }
89 elsif ( $entid == 9 ) { printf(" : Finder Info"); }
90 elsif ( $entid == 10 ) { printf(" : Macintosh File Info"); }
91 elsif ( $entid == 11 ) { printf(" : ProDOS File Info"); }
92 elsif ( $entid == 12 ) { printf(" : MS-DOS File Info"); }
93 elsif ( $entid == 13 ) { printf(" : Short Name"); }
94 elsif ( $entid == 14 ) { printf(" : AFP File Info"); }
95 elsif ( $entid == 15 ) { printf(" : Directory ID"); }
96 elsif ( $entid == 0x8053567E ) { printf(" : CNID (Netatalk Extended)"); }
97 elsif ( $entid == 0x8053594E ) { printf(" : DB stamp (Netatalk Extended)"); }
98 elsif ( $entid == 0x80444556 ) { printf(" : dev (Netatalk Extended)"); }
99 elsif ( $entid == 0x80494E4F ) { printf(" : inode (Netatalk Extended)"); }
100 else { printf(" : Unknown"); }
103 # Offset -------------------------------------------------
105 $rc = read(INFILE,$buf,4);
106 $ofst = unpack("N", $buf );
107 printf("Offset : %08X", $ofst);
108 printf(" : %d ", $ofst);
110 # Length -------------------------------------------------
112 $rc = read(INFILE,$buf,4);
113 $len = unpack("N", $buf );
114 printf("\nLength : %08X", $len);
115 printf(" : %d", $len);
120 # Dump for each Entry ID --------------------------------
122 # if ( $entid == 1 ) { ; } # Data Fork
123 # if ( $entid == 2 ) { ; } # Resource Fork
124 # if ( $entid == 3 ) { ; } # Real Name
125 # if ( $entid == 4 ) { ; } # Comment
126 # if ( $entid == 5 ) { ; } # Icon, B&W
127 # if ( $entid == 6 ) { ; } # Icon Color
128 # if ( $entid == 7 ) { ; } # File Info
129 if ( $entid == 8 ) { filedatesdump($ofst,$len); }
130 elsif ( $entid == 9 ) { finderinfodump($ofst,$len); }
131 # if ( $entid == 10 ) { ; } # Macintosh File Info
132 # if ( $entid == 11 ) { ; } # ProDOS File Info
133 # if ( $entid == 12 ) { ; } # MS-DOS File Info
134 # if ( $entid == 13 ) { ; } # Short Name
135 # if ( $entid == 14 ) { ; } # AFP File Info
136 elsif ( $entid == 15 ) { bedump($ofst,$len); } # Directory ID
137 elsif ( $entid == 0x8053567E ) { bedump($ofst,$len); } # CNID (Netatalk Extended)
138 elsif ( $entid == 0x8053594E ) { bedump($ofst,$len); ledump($ofst,$len); } # DB stamp (Netatalk Extended)
139 elsif ( $entid == 0x80444556 ) { bedump($ofst,$len); ledump($ofst,$len); } # dev (Netatalk Extended)
140 elsif ( $entid == 0x80494E4F ) { bedump($ofst,$len); ledump($ofst,$len); } # inode (Netatalk Extended)
142 # Hex Dump ---------------------------------------------------
144 seek(INFILE, $ofst, 0);
146 for ( $line = 0 ; $line < $quo ; $line++) {
147 $rc = read(INFILE, $buf, 16);
148 printf ( "%08X :", $addrs);
149 hexdump($buf, 16, 16, " ");
150 $addrs = $addrs + 0x10;
153 $rc = read(INFILE, $buf, $rem);
154 printf ( "%08X :", $addrs);
155 hexdump($buf, $rem, 16, " ");
162 #sub -----------------------------------------------------------
165 my ($ofst, $len) = @_;
170 @datetype =('create ', 'modify ', 'backup ', 'access ');
172 seek(INFILE, $ofst, 0);
174 for ( $i = 0 ; $i < 4 ; $i++) {
175 $rc = read(INFILE,$buf,4);
176 $datedata = unpack("N", $buf );
177 if ($datedata < 0x80000000) {
178 $datestr = gmtime( $datedata + 946684800)
180 .localtime( $datedata + 946684800)
182 } elsif ($datedata == 0x80000000) {
183 $datestr = "Unknown or Initial";
185 $datestr = gmtime( $datedata - 3348282496)
187 .localtime( $datedata - 3348282496)
190 printf ("%s : %08X : %s\n",$datetype[$i], $datedata, $datestr);
195 my ($ofst, $len) = @_;
197 seek(INFILE, $ofst, 0);
199 $rc = read(INFILE,$buf,4);
201 hexdump($buf, 4, 4, "");
203 $rc = read(INFILE,$buf,4);
205 hexdump($buf, 4, 4, "");
207 $rc = read(INFILE,$buf,2);
208 $flags = unpack("n", $buf );
209 printf ("isAlias : %d\n", ($flags >> 15) & 1);
210 printf ("Invisible : %d\n", ($flags >> 14) & 1);
211 printf ("hasBundle : %d\n", ($flags >> 13) & 1);
212 printf ("nameLocked : %d\n", ($flags >> 12) & 1);
213 printf ("Stationery : %d\n", ($flags >> 11) & 1);
214 printf ("CustomIcon : %d\n", ($flags >> 10) & 1);
215 printf ("Reserved : %d\n", ($flags >> 9) & 1);
216 printf ("Inited : %d\n", ($flags >> 8) & 1);
217 printf ("NoINITS : %d\n", ($flags >> 7) & 1);
218 printf ("Shared : %d\n", ($flags >> 6) & 1);
219 printf ("SwitchLaunc: %d\n", ($flags >> 5) & 1);
220 printf ("colorReserv: %d\n", ($flags >> 4) & 1);
221 printf ("color : %d%d%d\n", ($flags >> 3) & 1,
224 printf ("isOnDesk : %d\n", ($flags >> 0) & 1);
226 $rc = read(INFILE,$buf,4);
228 hexdump($buf, 4, 4, "");
230 $rc = read(INFILE,$buf,2);
232 hexdump($buf, 2, 4, "");
234 $rc = read(INFILE,$buf,2);
236 hexdump($buf, 2, 4, "");
238 $rc = read(INFILE,$buf,2);
240 hexdump($buf, 2, 4, "");
241 $rc = read(INFILE,$buf,2);
243 hexdump($buf, 2, 4, "");
244 $rc = read(INFILE,$buf,2);
246 hexdump($buf, 2, 4, "");
248 $rc = read(INFILE,$buf,1);
250 hexdump($buf, 1, 4, "");
252 $rc = read(INFILE,$buf,1);
254 hexdump($buf, 1, 4, "");
256 $rc = read(INFILE,$buf,2);
258 hexdump($buf, 2, 4, "");
260 $rc = read(INFILE,$buf,4);
262 hexdump($buf, 4, 4, "");
264 if ($len <= 32) { return; }
266 $rc = read(INFILE,$buf,2);
268 hexdump($buf, 2, 4, "");
270 $rc = read(INFILE,$buf,4);
272 hexdump($buf, 4, 4, "");
274 $rc = read(INFILE,$buf,4);
275 print "debug_tag : ";
276 hexdump($buf, 4, 4, "");
278 $rc = read(INFILE,$buf,4);
279 $ofst = unpack("N", $buf );
280 printf("total_size : %08X", $ofst);
281 printf(" : %d \n", $ofst);
283 $rc = read(INFILE,$buf,4);
284 $ofst = unpack("N", $buf );
285 printf("data_start : %08X", $ofst);
286 printf(" : %d \n", $ofst);
288 $rc = read(INFILE,$buf,4);
289 $ofst = unpack("N", $buf );
290 printf("data_length: %08X", $ofst);
291 printf(" : %d \n", $ofst);
293 $rc = read(INFILE,$buf,4);
294 print "reserved[0]: ";
295 hexdump($buf, 4, 4, "");
297 $rc = read(INFILE,$buf,4);
298 print "reserved[1]: ";
299 hexdump($buf, 4, 4, "");
301 $rc = read(INFILE,$buf,4);
302 print "reserved[2]: ";
303 hexdump($buf, 4, 4, "");
305 $rc = read(INFILE,$buf,2);
307 hexdump($buf, 2, 4, "");
309 $rc = read(INFILE,$buf,2);
310 $ofst = unpack("n", $buf );
311 printf("num_attrs : %04X", $ofst);
312 printf(" : %d \n", $ofst);
317 my ($ofst, $len) = @_;
321 seek(INFILE, $ofst, 0);
323 printf("%2dbit-BE : ", $len * 8 );
326 for ( $i=0 ; $i < $len ; $i++ ) {
327 $rc = read(INFILE,$buf,1);
328 $bytedata[$i] = unpack("C", $buf );
329 $value += $bytedata[$i] << (($len - $i -1) * 8) ;
332 for ( $i=0 ; $i < $len ; $i++ ) {
333 printf("%02X", $bytedata[$i]);
336 printf(" : %s", $value);
342 my ($ofst, $len) = @_;
346 seek(INFILE, $ofst, 0);
348 printf("%2dbit-LE : ", $len * 8 );
351 for ( $i=0 ; $i < $len ; $i++ ) {
352 $rc = read(INFILE,$buf,1);
353 $bytedata[$len - $i - 1] = unpack("C", $buf );
354 $value += $bytedata[$len - $i -1] << ($i * 8) ;
357 for ( $i=0 ; $i < $len ; $i++ ) {
358 printf("%02X", $bytedata[$i]);
361 printf(" : %s", $value);
367 my ($buf, $len, $col, $delimit) = @_;
373 for ( $i=0 ; $i < $len ; $i++ ) {
374 $val = substr($buf, $i, 1);
376 $hexstr .= sprintf("%s%02X", $delimit, $ascval);
378 if (($ascval < 32) || ( $ascval > 126 )) {
383 for ( ; $i < $col ; $i++) {
384 $hexstr .= " ".$delimit;
388 printf("%s : %s", $hexstr,$ascstr);