Personal Musings

This blog is intended to be just a jumble of thoughts that hit me and need not necessarily mean anything.

My Photo
Name:
Location: Kerala, India

Water flows ...

Friday, February 29, 2008

Mounting virtualbox vdi disk: An authentic weblog for achange

Using virtualBox had, of late, made things very easy for me. I am having enough ram to run linux as host OS with windows guest OS.
All the things I need windows specifically, I get to do in the Guest OS. All the normal activities are now in linux.
Using the virtual disk to store valuable information seemed a very nice, and sort of secure, till I finally found i needed some data stored in the virtual file very badly.

My office machine can be connected from my home, but getting the data out was the tricky part.


Stop the Virtual Machine
First problem was that my guest OS was running while I wanted to get the information.
$VBoxManage controlvm "my vm" poweroff

even
$VBoxManage controlvm "my vm" acpipowerbutton

will work. Essentially the first line works as if we are trying to switch off the windows machine. The second method works as if the ACPI is going to shut down the machine.
Note that if giving the name of the vm doesnt work for you, you can try giving the command
$ VBoxManage list vms
This command will list the Guest OS and the Host OS in the machine with all the glory details. The line that you have to look for is
....
Guest OS: Windows XP
UUID: deadbeef-dead-beef-dead-feebfeebdaed
......
You can replace the UUID instead of the name of the vm.

Figure out how to mount
For this half, I had to use the help of a post
http://forensicir.blogspot.com/2008/01/virtualbox-and-forensics-tools.html
by hogfly.
I picked up the vditool from the link mentioned in the blog.
http://www.virtualbox.org/download/testcase/vditool
(You have to right click and do "Save Link as.." to save the above file.)
First, you have to ensure that vditool can be executed.
so, first make it executable.
$ chmod u+x vditool
Then test whether the binary can be executed or not, by using ldd.

$ ldd vditool
linux-gate.so.1 => (0x00110000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0065e000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00111000)
librt.so.1 => /lib/librt.so.1 (0x00a00000)
libdl.so.2 => /lib/libdl.so.2 (0x00657000)
VBoxDD.so => /usr/lib/VBoxDD.so (0x00115000)
VBoxRT.so => /usr/lib/VBoxRT.so (0x0090e000)
libstdc++.so.5 => (not installed)
libm.so.6 => /lib/libm.so.6 (0x0062c000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00a0b000)
libc.so.6 => /lib/libc.so.6 (0x004d1000)
/lib/ld-linux.so.2 (0x004b2000)
VBoxVMM.so => /usr/lib/VBoxVMM.so (0x00258000)
VBoxDDU.so => /usr/lib/VBoxDDU.so (0x00679000)
VBoxDD2.so => /usr/lib/VBoxDD2.so (0x00340000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00a95000)
VBoxREM.so => /usr/lib/VBoxREM.so (0x00b80000)
libutil.so.1 => /lib/libutil.so.1 (0x00368000)

In my case, the initial output was like above. Watch out the libstdc++-so.5 line. Initially the library was not installed in my machine. So i had to manually install it first before i could run the library. All those VBox libraries will get installed by default in the machine in which you install VirtualBox. In my case, I had to install compat-libstdc++-3.3 package for my Fedora 8 machine.
(The right way is to install the corresponding package in the system. Expert users can definitely pick and put just the libraries from someother machine to
just get things working for the time being, though it is not recommended at all.)
Once you are through installing all the libraries, it should look something like this.

$ ldd vditool
linux-gate.so.1 => (0x00110000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0065e000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00111000)
librt.so.1 => /lib/librt.so.1 (0x00a00000)
libdl.so.2 => /lib/libdl.so.2 (0x00657000)
VBoxDD.so => /usr/lib/VBoxDD.so (0x00115000)
VBoxRT.so => /usr/lib/VBoxRT.so (0x0090e000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x0019f000)
libm.so.6 => /lib/libm.so.6 (0x0062c000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00a0b000)
libc.so.6 => /lib/libc.so.6 (0x004d1000)
/lib/ld-linux.so.2 (0x004b2000)
VBoxVMM.so => /usr/lib/VBoxVMM.so (0x00258000)
VBoxDDU.so => /usr/lib/VBoxDDU.so (0x00679000)
VBoxDD2.so => /usr/lib/VBoxDD2.so (0x00340000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00a95000)
VBoxREM.so => /usr/lib/VBoxREM.so (0x00b80000)
libutil.so.1 => /lib/libutil.so.1 (0x00368000)

Now comes crucial part.

Find disk offset
use vditool to know the starting offset of the Data in the disk.

For this you should know were your virtual machine's virtual disk is stored. If you didnt do it manually, the default location is ~/.VirtualBox/VDI

Assuming that You have put the vditool file in your home directory, cd to the directory with the vdi file.

$ cd /path/to/vdi/file

$ ~/vditool DUMP my.vdi
vditool Copyright (c) 2004-2005 InnoTek Systemberatung GmbH.

Dumping VDI image file="my.vdi" into the log file...
Log created: 2008-02-29T13:20:02.737901000Z
Executable: /home/me/vditool
Arg[0]: ~/vditool
Arg[1]: DUMP
Arg[2]: my.vdi
--- Dumping VDI Disk, Images=1
Dumping VDI image "my.vdi" mode=r/o fOpen=1 File=00000004
Header: Version=00010001 Type=2 Flags=0 Size=11811160064
Header: cbBlock=1048576 cbBlockExtra=0 cBlocks=11264 cBlocksAllocated=11264
Header: offBlocks=512 offData=45568
Header: Geometry: C/H/S=22885/16/63 cbSector=512 Mode=3
Header: uuidCreation={deadbeef-dead-beef-dead-feebfeebdaed}
Header: uuidModification={deadbeef-dead-beef-dead-feebfeebdaed}
Header: uuidParent={00000000-0000-0000-0000-000000000000}
Header: uuidParentModification={00000000-0000-0000-0000-000000000000}
Image: fFlags=00000000 offStartBlocks=512 offStartData=45568
Image: uBlockMask=000FFFFF uShiftIndex2Offset=20 uShiftOffset2Index=20 offStartBlockData=0
The operation completed successfully!

Type says whether it is dynamic or fixed virtual disk. (I dont yet know whther it is important, but mine definitely is fixed. I know it because I made it that way.)

actually, you can do a grepping of the output
$ ~/vditool DUMP my.vdi | grep OffData
Header: offBlocks=512 offData=45568

The number sacred to us is 45568.
Now, a normal vdi file has some meta data and then followed by the actual disk data. The sacred number is the offset from which our windows disk starts. But then this offset point to the place MBR is.
So to get the actual data mount, you have to add 32256 to 45568 giving us the final offset of 77824.
To mount,
$mkdir mp
$mount -t ntfs -o ro,noatime,noexec,loop,offset=77824 my.vdi mp


You can now start using the disk contents directly.

$ ls mp
AUTOEXEC.BAT Documents and Settings MSDOS.SYS pagefile.sys
.........





If you feel there needs to be any improvements, please post a comment.

Labels:

12 Comments:

Blogger Amber said...

This post deserves more credit. All other posts on loopmounting VDIs converge here. It has simply the best info on vditool. THanks

August 20, 2008 4:57 AM  
Blogger Amber said...

For convenience, here is a snippet that I now keep around to document/automate this:

#!/bin/bash
VDI=mydisk.vdi
OFFSET=./vditool DUMP $VDI|perl -ne 'print 32256+$1 if m/offData=(\d+)/'
sudo mount -o ro,noatime,noexec,loop,offset=$OFFSET $VDI loopmnt/

Have fun

August 20, 2008 6:22 PM  
Blogger Amber said...

Sorry, i managed to screw up quotes (let me use the preview this time)

#!/bin/bash
VDI=mydisk.vdi
OFFSET=$(./vditool DUMP $VDI|perl -ne 'print 32256+$1 if m/offData=(\d+)/')
sudo mount -o ro,noatime,noexec,loop,offset=$OFFSET $VDI loopmnt/

August 20, 2008 6:30 PM  
Blogger Znupi said...

This doesn't work with dynamically expanding images. I'm not saying it should, just don't try to do it, or you'll waste your time.

November 10, 2008 1:05 AM  
Blogger guilt said...

I've put together a couple of C/Perl utilities to do the same:

vdiinfo (replacement for vditool which I didn't find, source at: http://pastebin.ca/1297026)
vdimount (perl script which requires above utility, at: http://pastebin.ca/1297025)

It's a little bigger than Amber's, but it helps you mount the right partitions based on fdisk information as well.

December 31, 2008 4:09 PM  
Blogger Chaz Larson said...

Thanks for the utilities, Guilt. They work very well.

January 15, 2009 12:16 AM  
Blogger joona said...

Let's bash-oneline it for greater confusion ;)
(needs the vditool ofc)

mount -t ntfs -o ro,noatime,noexec,loop,offset=`vditool DUMP mydisk.vdi |grep OffData |awk -F= '{print $3}'` mydisk.vdi /mnt/path

April 07, 2009 10:09 PM  
Blogger Marco Caminati said...

Thanks for great info.
I packaged a bash script with vditool to give something like joona's one-liner, just a bit less rudimental.
It can directly mount any of the four primary partitions automagically.
Check it out at
www.mat.uniroma1.it/~caminati/mount_vdi.html

May 08, 2009 3:08 AM  
Blogger Jeroen said...

Great info!

I failed finding vditool, so I thought to find the correct offset by "brute-force" like so:

# R=12; S=0; while [ $R -eq 12 ]; do mount -t ntfs -o loop,offset=$S WinXP.vdi /mnt/tmp; R=$?; S=$(expr $S + 1); done

This will try mounting the image, letting mount fail with return code 12 if (as long as) "no valid ntfs signature is found". After a succesfull mount (I suppose this gives return code 0), the loop is ended.

I let it run for quite some time, however without luck.

I do have a dynamically expanding image, and most sources only describe how to mount a fixed image, although some are not explicit about this.

Would anybody know why this fails?

January 02, 2010 10:29 PM  
Blogger Eric Chang said...

vditool is old. I think they took it off of VirtualBox.org. Another command that does similar thing is VBoxManage internalcommands dumphdinfo [NameOfImage].vdi

May 27, 2010 7:52 AM  
Blogger xenserver said...

What happen if the virtual machine also has got snapshots?

Do you have any kind hint with that?

Thank you
Cor

April 30, 2014 11:10 AM  
Blogger Murali said...

vditool is pretty old.

VBoxManage replaced it.

I am not aware of the latest tool.

June 23, 2014 10:06 PM  

Post a Comment

<< Home