2011-02-26

Using device mapper to mount the sliced partition

Let's say you have taken image of a drive and sliced it to several pieces.
How to mount it as a single partition for forensic investigation?

Sliced image might have been prepared with tool like dcfldd . To slice the image to smaller chunks might be usefull for example to be able to store files on a filesystem with poor support for large files or burn it to DVD media later on.
Example on acquire the image:
$ dcfldd if=/dev/sda1 split=4G of=img_sda1 bs=8M hash=md5,sha1 hashlog=img_sda1.sum hashwindow=1G
Outline 
  1. Acquire sliced disk image
  2. Setup files as loopback devices
  3. Set devices read only 
  4. Prepare description table for the device mapper (dmtable)
  5. Create the device based on the layout in dmtable
  6. Set the mapped device readonly
  7. mount read-only the filesystem

Caveats
  • when creating the image use chunks dividable by 512 (default sector size to use with device mapper). If you use human readable units like k, M, G - everything is super green :).
  • by default the loop module is loaded (Fedora 14) with 8 loop devices enabled.
  • keep the right order of the image slices
  • keep the created device read only to not compromise the data

Test scenario
Let's prepare 2 slices for testing. One full of zeroes and the second one full of ones.
$ #Create one image full of 0
$ dcfldd pattern=00 of=img_sda1.000 bs=8M count=1

$ #Create second image full of 1
$ dcfldd pattern=FF of=img_sda1.001 bs=8M count=1

$ ls -l img_sda1.00*
-rw-rw-r--. 1 rebus rebus 8388608 Feb 26 01:52 img_sda1.000
-rw-rw-r--. 1 rebus rebus 8388608 Feb 26 01:53 img_sda1.001

$ #Hex dump will show one file full 0 and second full of ones
$ od -x img_sda1.000
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
40000000
$ od -x img_sda1.001
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
40000000

Increase number of loop devices 
RedHat EL4 way
In case you will need to utilize more than the default number of loop devices (8) there is possibility to  establish more loop devices (up to 255) by unloading the loop kernel module an reloading with the right number of parameter max_loop=12.
$ sudo rmmod loop
$ sudo modprobe loop max_loop=128

Alternatively it is possible to place the option to the /etc/modprobe.conf
echo "options loop max_loop=128" >> /etc/modprobe.conf
Fedora 14 way
In new Fedora 14 the loop module is in the kernel and not in separate module. By default only 8 loopback devices appears in /dev.
It is possible to create the devices manually:
$ sudo mknod /dev/loop8 b 7 8
sudo mknod /dev/loop9 b 7 9
sudo mknod /dev/loop24 b 7 24


Or you can make it easy:
$ sudo yum install MAKEDEV
$ MAKEDEV loop

Setup Loopback devices
$ sudo losetup /dev/loop0 img_sda1.000
$ sudo losetup /dev/loop1 img_sda1.001

$ #Check the device sizes in sectors (needed for dmtable)
$ blockdev --getsize /dev/loop0
16384
$ sudo blockdev --getsize /dev/loop1
16384

$ #set devices read only
$ sudo blockdev --setro /dev/loop0
$ sudo blockdev --setro /dev/loop1

Generate suitable dmtable
$ cat > dmtable.txt << EOF
#offset  size    mode   device seek
0       16384 linear /dev/loop0 0
16384   16384 linear /dev/loop1 0
EOF

Map the device of using the dmsetup
$ sudo dmsetup create img_sda1 dmtable.txt
$ sudo blockdev --setro /dev/mapper/img_sda1

Check
Check that the device is really mapped and that everything works as expected. In our testing case we can use od to print the content of the image and compare it to original results.
$ ls -l /dev/mapper/img_sda1
lrwxrwxrwx. 1 rebus rebus 7 Feb 26 06:34 /dev/mapper/img_sda1 -> ../dm-6
$ sudo od -x /dev/mapper/img_sda1
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
40000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
100000000

Alltogether
Now let's put everything to some nice script which will do all together for dozens of image slices. Do not forget you need enough of the loop devices.

#!/bin/bash
#############################################
# Name: mount_slices.sh
# Author: Michal Ambroz
# Copyright: GPLv2+
#############################################
export PATH=$PATH:/usr/sbin:/sbin

TARGET="img_sda1"
IMAGES=`ls ${TARGET}.[0-9]*`
ICOUNT=`echo $IMAGES | wc -w `

DMTABLE=/tmp/dmtable
STARTLOOP=2
TOTALSIZE=0

sudo dmsetup remove "$TARGET"

#Loop devices
rm -f dmtable.$$
I=$STARTLOOP
echo "$IMAGES" | grep -v "^$" |\
while read IMAGE ; do
sudo losetup -d /dev/loop${I} > /dev/null
sudo losetup /dev/loop${I} $IMAGE
sudo blockdev --setro /dev/loop${I}
LSIZE=`sudo blockdev --getsize /dev/loop${I}`
echo "$TOTALSIZE $LSIZE linear /dev/loop${I} 0 " >> $DMTABLE.$$
TOTALSIZE=$(( $TOTALSIZE + $LSIZE))
I=$(( $I + 1 ))
done

echo sudo dmsetup create "$TARGET" $DMTABLE.$$
sudo dmsetup create "$TARGET" $DMTABLE.$$
echo sudo blockdev --setro "/dev/mapper/$TARGET"
sudo blockdev --setro "/dev/mapper/$TARGET"


Relevant links
http://linuxgazette.net/114/kapil.html
http://www.generationip.com/documentation/mini-howto/78-howto-create-loop-device-on-redhat-centos-or-fedora
http://sourceware.org/dm/
http://sources.redhat.com/lvm/
http://adam.younglogic.com/2010/12/mounting-a-kvmqemu-vm-root-partition-in-fedora-14/
http://www.forensicswiki.org/wiki/Mounting_Disk_Images

No comments:

Post a Comment