Break photo.png
Ecco un esempio su come utilizzare comuni programmi Linux, disponibili in tutte le distro, per recuperare le immagini cancellare da un qualsiasi supporto di memorizzazione. Questo tutorial è fornito "as is", così com'è, e senza alcuna garanzia. Da usarsi a tuo rischio e pericolo.

Contents

Primo esempio: solo con comandi Linux standard

Uno script bash che usa il comando 'dd' per estrarre una porzione di dati memorizzata sul disco o su un altro supporto multimediale (potrebbe essere anche un file), il comando 'file' per ottenere il file-type, l'utility 'convert' di ImageMagick per aggiustare la lunghezza del file E' un esempio di processo comunemente chiamato "data carving".

imagescan.sh

Nota: questo script è piuttosto lento come tempi di esecuzione.

#!/bin/sh
 
if [ $# -ne 2 ] ; then
 echo "------"
 echo "Usage:"
 echo "./imagescan.sh disk|file starting_sector"
 echo "Example:"
 echo "./imagescan.sh /dev/sda 100000"
 echo
 exit
fi
 
DISK=$1
START=$2
DELTA=1
SKIPS=$START
 
MAXBLK=`sfdisk -s $DISK`
 
let MAXBLK=$MAXBLK+$MAXBLK
 
echo "$DISK - $MAXBLK blocks"
 
while [ $MAXBLK -gt $SKIPS ]
do
 
 is_File=`dd if=$DISK of=/dev/stdout bs=512 count=1 skip=$SKIPS 2>/dev/null | \
          file -eapptype -eascii -eencoding -etokens -ecdf -ecompress -eelf -etar -`
 
 imgType=""
 
 is_IMAGE=`echo $is_File | grep JPEG`
 if [ "a$is_IMAGE" != "a" ] ; then
  imgType="jpg"
 fi
 
 #is_IMAGE=`echo $is_File | grep PNG`
 #if [ "a$is_IMAGE" != "a" ] ; then
 # imgType="png"
 #fi
 
 #is_IMAGE=`echo $is_File | grep BMP`
 #if [ "a$is_IMAGE" != "a" ] ; then
 # imgType="bmp"
 #fi
 
 if [ "a$imgType" != "a" ] ; then
 
  #dd if=$DISK of=/dev/stdout bs=512 count=200 skip=$SKIPS 2>/dev/null | xv -geometry 320x240 -
 
  dd if=$DISK of=$SKIPS.$imgType bs=512 count=2000 skip=$SKIPS 2>/dev/null
 
  isCorruptImage=`convert $SKIPS.$imgType $SKIPS.$imgType 2>&1`
 
  isCorruptImage=""
 
  if [ "a$isCorruptImage" != "a" ] ; then
   rm -f $SKIPS.$imgType
   echo "$SKIPS.$imgType corrupt, not saved"
  else
   echo "$SKIPS.$imgType saved"
  fi
 
 fi
 
 let SKIPS=$SKIPS+$DELTA
 
done
 
echo "$SKIPS blocks ... exit"

Secondo esempio: usando un'utility scritta in Pascal per accelerare la ricerca dei file

Lo script lavora come quello sopra, ma usa un programma esterno per migliorare le prestazioni. Nota: ritrova solo i file jpg di tipo più comune, ma è molto veloce come tempo di esecuzione.

getimages.sh, lo script

#!/bin/sh
 
if [ $# -ne 2 ] ; then
 echo "------"
 echo "Usage:"
 echo "./getimages.sh disk|file starting_sector"
 echo "Example:"
 echo "./getimages.sh /dev/sda 100000"
 echo
 exit
fi
 
DISK=$1
START=$2
DELTA=1
SKIPS=$START
 
imgType="jpg"
 
WORKDIR=`pwd`
 
if [ ! -e $WORKDIR/findimgblock ] ; then
 echo
 echo "Binary program 'findimgblock' not found in path"
 echo "... exit"
 echo
 exit
fi
 
MAXBLK=`sfdisk -s $DISK`
 
let MAXBLK=$MAXBLK+$MAXBLK
 
echo "$DISK - $MAXBLK blocks"
 
while [ $MAXBLK -gt $SKIPS ]
do
 
 SKIPS=`$WORKDIR/findimgblock $DISK $SKIPS`
 
 dd if=$DISK of=$SKIPS.$imgType bs=512 count=4000 skip=$SKIPS 2>/dev/null
 
 isCorruptImage=`convert $SKIPS.$imgType $SKIPS.$imgType 2>&1`
 
 if [ "a$isCorruptImage" != "a" ] ; then
  rm -f $SKIPS.$imgType
  echo "$SKIPS.$imgType corrupt, not saved"
 else
  echo "$SKIPS.$imgType saved"
 fi
 
 let SKIPS=$SKIPS+$DELTA
 
done
 
echo "$SKIPS blocks ... exit"

findimgblock.pas, l'utility che ricerca i file jpg

Questo programma legge semplicemente i blocchi in sequenza e si ferma se un blocco contiene l'intestazione jpg standard (6 byte).

{$mode objfpc}
{$h+ }
Uses
	SysUtils;
type
	disk_B = array [0..32767] of byte;
const
	ImgSignature : array [0..5] of byte = ($FF,$D8,$FF,$E0,$00,$10);
var
	i, n : integer;
	sectorCount : longword;
	BB  : disk_B;
	P : pointer;
	deviceName : string;
	hddDevice : file;
 
function extended_Read (var hdd : file; sector : longword; var buffer : disk_B) : integer;
 
begin
 {$I-}
 seek  (hdd,sector);
 blockread  (hdd,buffer,64);
 {$I+}
 extended_Read := ioresult;
end;
 
function findImgSignature (pos : integer; buffer : disk_B) : boolean;
var
	i : integer;
	match : boolean;
begin
 match := true;
 for i := 0 to 5 do
  if buffer [pos+i] <> ImgSignature [i] then match := false;
 findImgSignature := match;
end;
 
begin
 
 if paramcount <> 2 then
 begin
  writeln ('Usage: findimgblock device startsector');
  exit;
 end;
 
 Try
  sectorCount:=StrToInt(paramstr(2));
 except
   On sectorCount : Exception do begin
    Writeln('Error exception when converting : ',sectorCount.Message);
    exit;
   end;
 end;
 
 deviceName := paramstr(1);
 assign (hddDevice,deviceName);
 
 {$I-}
 reset (hddDevice,512);
 {$I+}
 
 while true do
 begin
 extended_Read (hddDevice, sectorCount, BB);
 
 for i := 0 to 63 do
 begin
  if findImgSignature (i*512, BB) then
  begin
   sectorCount := sectorCount + i;
   write (sectorCount);
   exit;
  end;
 end;
 
 sectorCount := sectorCount + 64;
 end;
 
 close (hddDevice);
 
end.

per compilarlo:

fpc -TLinux findimgblock.pas

Puoi anche scaricare qui il binario statico precompilato: File:Findimgblock.gz (scompattalo nella directory di lavoro e rendilo eseguibile). Anche le immagini recuperate vengono salvate nella directory di lavoro.

Buon divertimento!

Retrieved from "http://www.zoros.org/wiki/index.php?title=How_to_recover_jpg_images_using_standard_bash_linux_commands_and_other_examples/it"