Skip to content

Instantly share code, notes, and snippets.

@velenux
Created February 2, 2010 12:40
Show Gist options
  • Save velenux/292627 to your computer and use it in GitHub Desktop.
Save velenux/292627 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
########################################################################
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Copyright 2009 Gilberto "Velenux" Ficara <[email protected]>
#
# This is very very *ugly* and slow, but it has recovered some files
# that photorec didn't recover, for me.
#
# I used it in conjunction with dd_raw to recover photos from a
# defective compact flash
#
#####################################################################
use strict;
use warnings;
my $file = $ARGV[0] ;
(-r $file ) or die "Use: $0 <file>\n" ;
open STREAM, "<$file" or die "Can't open file <$file>, $!\n" ;
binmode STREAM;
my $buff; # buffer
my $buff_len = 2; # buffer len
my $seek = 0; # seek address
my $start_addr = 0; # start address of file
my %addr;
# START PATTERN
# 49 49 2A 00 10 00 00 00 43 52 02 00
my $start_pattern = pack 'H*', '49492a001000000043520200';
my $start_pattern_2b = pack 'H*', '4949';
# END PATTERN
# FF D9
my $end_pattern = pack 'H*', 'FFD9';
while( read( STREAM, $buff, $buff_len ) ) {
# debug
#my $ubuff = unpack 'H*', $buff;
#print "[ $ubuff ] Seek: $seek --> ";
if((not $start_addr) and ($buff eq $start_pattern_2b)) {
seek STREAM, -2, 1 ; # rewind 2 bytes
read STREAM, $buff, 12 ; # read 12 bytes
if($buff eq $start_pattern) {
warn "Found file start at $seek!\n";
$addr{$seek} = 0;
$start_addr = $seek;
$seek+=10;
} else {
seek STREAM, -10, 1; # rewind 10 bytes (12-2=10)
}
}
if((defined $start_addr) and ($buff eq $end_pattern)) {
warn "Found file end at $seek!\n";
$addr{$start_addr} = $seek+2;
undef $start_addr;
}
$seek += 2;
print "$seek\n";
}
foreach my $a (sort keys %addr) {
next if $addr{$a} == 0;
my $fname = sprintf("%08d", $a) . '-' . sprintf("%08d", $addr{$a}) . '.cr2';
my $image;
seek STREAM, $a, 0;
read STREAM, $image, ($addr{$a} - $a) ; # read full image
open OUT, ">$fname";
binmode OUT;
print OUT $image;
close OUT;
}
close STREAM;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment