#!/usr/bin/perl -w # # gettypes - read the image file 512 bytes at a time, check # the type of data with File::MMagic and store the type # returned with it's offset into a hash. This is slow # because we are reading 512 bytes at a time and then # testing the buffer. A quick buffer check to determine # if all 512 bytes are the same value was added to speed # up the process. # # MMagic at http://search.cpan.org/author/KNOK/File-MMagic-1.16/MMagic.pm # CRC32 at ftp://ftp.ntua.gr/pub/linux/asplinux/sources/SRPMS.7.3/SRPMS/perl-String-CRC32-1.2-15.src.rpm # # usage: gettypes imagefile # # # N. DeBaggis 10/23/2002 # use strict; use File::MMagic; use String::CRC32; my $magicfile = '/usr/share/magic/magic.mime'; my $buf; my %typehash; my $blocksize = 512; my $magic; my %crchash; if(! -f $magicfile){ print "$magicfile file not found, using defaults\n"; $magic = File::MMagic::new(); } else{ $magic = File::MMagic::new($magicfile); } # precompute the CRC32's for each block from 0 - 255 # this will be used later to do a quick check on a block # so we can ignore blocks that have all the same byte values. for(my $z = 0; $z < 256; $z++){ my $temp = chr($z) x $blocksize; $crchash{crc32($temp)}++; } open(FH, "$ARGV[0]") or die "can't open $ARGV[0] : $!"; binmode(FH); print STDERR "attempting to find data types in $ARGV[0]...\n"; my $offset = 0; while(! eof(FH)){ $offset += $blocksize; $buf = (); read(FH, $buf, $blocksize); next if checkblock($buf); $typehash{$magic->checktype_contents($buf)} = $offset - $blocksize; } close(FH); print "\nPossible data types found in $ARGV[0] with offsets:\n\n"; print " hex dec type\n"; print '-' x 50 . "\n"; foreach(sort {$typehash{$a} <=> $typehash{$b}} keys %typehash){ printf("0x%08x %10d %s\n", $typehash{$_}, $typehash{$_}, $_); } print "\n"; # # checkblock($buffer) # # check if the buffer is all the same byte, return 1 if # the whole block is the same. This will # speed up the analysis a bit. # sub checkblock{ my $tmp = shift; my $check = 0; if($crchash{crc32($tmp)}){ return 1; } # if((unpack('%32C*', $buf) % $blocksize) == 0){ # return 1; # } return 0; }