#!perl -w use strict; use IO::File; use Getopt::Long; my $blocksize; GetOptions("b=s"=> sub { $blocksize= eval($_[1]); } ); if (@ARGV<1 || @ARGV>2) { die "Usage: decode_fffbd.pl [-b BLOCKSIZE] \n"; } my $ifn= shift; my $ofn= shift; my $ifh= IO::File->new($ifn, "r") or die "$ifn: $!\n"; binmode $ifh; my $ofh= IO::File->new($ofn, "w") or die "$ofn: $!\n" if $ofn; binmode $ofh if $ofh; $blocksize ||= find_blocksize($ifh); printf("blocksize=%08lx\n", $blocksize); $ifh->seek(0, SEEK_SET); my $start; my $ofs1=0; my $ofs2=0; my @prevf; while (!$ifh->eof) { my $data; $ifh->read($data, $blocksize+8); my @f= unpack("VV", substr($data, $blocksize)); my $this_t= $f[0]==0xffffffff ? 0xffffffff : $f[0]-$ofs2/0x800; if (!$start || $this_t!=$start->{t} || $f[1]!=$start->{f}[1]) { if ($start) { printf("%08x-%08x %08x-%08x %05x-%05x %08x\n", $start->{ofs1}, $ofs1, $start->{ofs2}, $ofs2, $start->{f}[0], $prevf[0], $start->{f}[1]); } $start= {ofs1=>$ofs1, ofs2=>$ofs2, f=>\@f, t=> $f[0]==0xffffffff ? 0xffffffff : $f[0]-$ofs2/0x800 }; } $ofh->print(substr($data, 0, $blocksize)) if $ofh; $ofs1+=$blocksize+8; $ofs2+=$blocksize; @prevf= @f; } printf("%08x-%08x %08x-%08x %05x-%05x %08x\n", $start->{ofs1}, $ofs1, $start->{ofs2}, $ofs2, $start->{f}[0], $prevf[0], $start->{f}[1]); $ifh->close(); $ofh->close() if $ofh; sub find_blocksize { my ($fh)=@_; my $data; $fh->read($data, 0x4000); for my $bs (0x200, 0x400, 0x800, 0x1000) { if (substr($data, $bs, 8) eq "\x00\x00\x00\x00\xfd\xff\xfb\xff" && substr($data, 2*$bs+8, 8) eq "\x01\x00\x00\x00\xfd\xff\xfb\xff") { return $bs; } } die "could not determine blocksize\n"; }