![]() |
![]() |
![]() |
![]() |
![]() |
Contenido |
A bash script that uses 'dd' command to extract a portion of data stored to disk or to other media support (may be a file also), 'file' command to get file-type, and ImageMagick 'convert' progam to adjust file length. This is an example of a process commonly referred as "data carving".
Note: this script is very slow as execution time.
#!/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"
The script works as the script above, but uses an external program to improve performance. Note: it retrieves only common jpg files, but it is very fast as execution time.
#!/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"
This program simply reads blocks sequentially and stops if a block contains the standard jpg header (6 bytes).
{$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.
to compile:
fpc -TLinux findimgblock.pas
Here you can also download a precompiled static binary: File:Findimgblock.gz (unpack it in working directory and set to executable). Also recovered images are saved in working directory.
Have fun!