Disk Images

From NST Wiki
Jump to: navigation, search

Overview

When trying to do forensics or recovery on a disk, it is often desirable to make a copy of the entire disk to a single file (a "disk image").

How Do I Create A Disk Image?

Making a copy of a disk is a relatively simple process as long as you have enough free space on another disk to copy the disk image to.

  • Identify the device entry for the disk (something like: /dev/sda).
  • Copy the device entry to a file on a different disk.

You can use the fdisk -l command to help identify the disk device entries. For example:

[root@cayenne-e ~]# fdisk -l

Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x8da2c67c

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1       13055   104857600    7  HPFS/NTFS
/dev/sda2           29094       30400    10485760   1b  Hidden W95 FAT32
/dev/sda3           30400       30401       16064+  ef  EFI (FAT-12/16/32)
/dev/sda4           13056       29093   128825235    5  Extended
/dev/sda5   *       13056       13081      204800   83  Linux
/dev/sda6           13081       18180    40959999+  83  Linux
/dev/sda7           18181       18310     1044193+  83  Linux

Partition table entries are not in disk order

Disk /dev/sdb: 62 MB, 62390272 bytes
255 heads, 63 sectors/track, 7 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x0003bc6e

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1           5       40131    b  W95 FAT32
/dev/sdb2               6           7       16065   83  Linux
[root@cayenne-e ~]# 

The above output indicates that there are two disks on the system /dev/sda (250GB) and /dev/sdb (62MB). The following command will copy the contents of the 62MB disk (/dev/sdb) to the file: /tmp/disk.img:

[root@cayenne-e ~]# cp /dev/sdb /tmp/disk.img
[root@cayenne-e ~]#

Now that we have a copy of the contents of the physical contents of /dev/sdb we will no longer need to directly access /dev/sdb.

How Do I List The Partitions In A Disk Image

You can print the partition table of a "disk image" (a file containing the raw contents of a disk), using the fdisk command as shown below:

[root@cayenne-e ~]# fdisk -l /tmp/disk.img
You must set cylinders.
You can do this from the extra functions menu.

Disk /tmp/disk.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x0003bc6e

        Device Boot      Start         End      Blocks   Id  System
/tmp/disk.img1               1           5       40131    b  W95 FAT32
/tmp/disk.img2               6           7       16065   83  Linux
[root@cayenne-e ~]#

You can also use the sfdisk command as shown below (the sfdisk command shows the size of each block):

[root@cayenne-e ~]# sfdisk -l /tmp/disk.img 
Disk /tmp/disk.img: cannot get geometry

Disk /tmp/disk.img: 7 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

   Device Boot      Start     End   #cyls    #blocks   Id  System
/tmp/disk.img1          0+      4       5-     40131    b  W95 FAT32
/tmp/disk.img2          5       6       2      16065   83  Linux
/tmp/disk.img3          0       -       0          0    0  Empty
/tmp/disk.img4          0       -       0          0    0  Empty
[root@cayenne-e ~]#

How Do I Mount A Partition From A Disk Image?

Mounting a partition within a disk image is a bit trickier. In order to mount a partition from within a disk image, you must compute the offset to the start of the partition. To compute the offset, you need the following values from the output of sfdisk -l IMAGE_FILE:

  • T - The sectors/track value
  • B - The block size
  • 512 - The constant 512
  • S - The starting block of the partition

The offset to the partition is then computed as follows:

(S * B) + (T * 512)

For example, take a look at the partition table within the disk image /tmp/disk.img:

[root@cayenne-e ~]# sfdisk -l /tmp/disk.img
Disk /tmp/disk.img: cannot get geometry

Disk /tmp/disk.img: 7 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

   Device Boot      Start     End   #cyls    #blocks   Id  System
/tmp/disk.img1          0+      4       5-     40131    b  W95 FAT32
/tmp/disk.img2          5       6       2      16065   83  Linux
/tmp/disk.img3          0       -       0          0    0  Empty
/tmp/disk.img4          0       -       0          0    0  Empty
[root@cayenne-e ~]# 

In the output above, if we wanted to mount the second partition (Linux) shown in the partition table, we would set T=63, B=1024, and S=40131 (the 40131 is the sum of the #blocks column for all of the partitions that come before the Linux partition we are trying to mount) and compute the offset as follows:

(S * B) + (T * 512) = (40131 * 1024) + (63 * 512)

So, to mount the second partition using, we would use the following command sequence:

[root@cayenne-e ~]# mkdir /mnt/img
[root@cayenne-e ~]# OFFSET=$(( (40131 * 1024) + (63 * 512) ))
[root@cayenne-e ~]# echo $OFFSET
41126400
[root@cayenne-e ~]# mount -o loop,offset=${OFFSET} /tmp/disk.img /mnt/img
[root@cayenne-e ~]# ls -l /mnt/img
total 4705
drwx------ 2 root root   12288 2010-03-01 12:29 lost+found
-rw------- 1 root root 4784530 2010-03-01 12:40 messages
[root@cayenne-e ~]# 

At this point, we can now read and write to the Linux partition on the disk image as if it were the original drive:

[root@cayenne-e ~]# echo "Hello World" >| /mnt/img/hello.txt
[root@cayenne-e ~]# cat /mnt/img/hello.txt
Hello World
[root@cayenne-e ~]# 

Finally, after we are done using the disk image, we'll use the umount command to release it:

[root@cayenne-e ~]# umount /mnt/img
[root@cayenne-e ~]#

If you have access to the parted utility, you can use it to print out the offsets for each partition within your disk image (no computation required). For example, the following uses parted, and sets the output units to bytes to determine that the offset to the second partition is 41126400 within our sample disk image:

[root@cayenne-e ~]# printf "unit B\nprint\nquit\n" | parted /tmp/disk.img 
GNU Parted 1.9.0
Using /tmp/disk.img
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit B                                                           
(parted) print                                                            
Model:  (file)
Disk /tmp/disk.img: 62390272B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End        Size       Type     File system  Flags
 1      32256B     41126399B  41094144B  primary  fat32
 2      41126400B  57576959B  16450560B  primary  ext2

(parted) quit                                                             
[1]+  Terminated              printf "unit B\nprint" | parted /tmp/disk.img
[root@cayenne-e ~]# mount -o loop,offset=41126400 /tmp/disk.img /mnt/img
[root@cayenne-e ~]# ls /mnt/img
hello.txt  lost+found  messages
[root@cayenne-e ~]# umount /mnt/img
[root@cayenne-e ~]#