Is it possible to read Windows 2008 LDM partitions in Linux?
We have five 512GB LUNS exported through ISCSI to a dead Windows 2008 and this box doesn’t want them anymore. Windows believes they are now raw devices… So I’d like to read the partitions with Linux. I am using the latest Ubuntu to try to save at least some of the data. The problem is that all documentation I’ve found so far seems to be obsolete (often talking about w2k or XP Logical Disk Manager (LDM). But I think now it’s different with 2008.
Testdisk [0] gives me the following output
testdisk /list LUN01
TestDisk 6.11, Data Recovery Utility, April 2009
Christophe GRENIER <grenier@cgsecurity.org>
http://www.cgsecurity.org
Please wait...
Disk LUN01 - 536 GB / 500 GiB - CHS 65271 255 63, sector size=512
Disk LUN01 - 536 GB / 500 GiB - CHS 65271 255 63
Partition Start End Size in sectors
1 P MS LDM MetaData 34 2081 2048 [LDM metadata partition]
No FAT, NTFS, EXT2, JFS, Reiser, cramfs or XFS marker
2 P MS Reserved 2082 262177 260096 [Microsoft reserved partition]
2 P MS Reserved 2082 262177 260096 [Microsoft reserved partition]
3 P MS LDM Data 262178 1048576966 1048314789 [LDM data partition]
Note: Each of the 5 LUN has the same partition table.
In many documentations like cgssecurity and kernel.org, they talk about ldminfo which doesn’t return any useful information. I suspect that it’s now obsolete, just because it was very hard to find ๐ And because it does not work I guess windows 2008 uses a different format.
# ldminfo LUN01
Something went wrong, skipping device 'LUN01'
# losetup /dev/loop1 LUN01
# losetup -a
/dev/loop1: [fd00]:14 (/mnt/LUN01)
# ldminfo /dev/loop1
Something went wrong, skipping device '/dev/loop1'
Then, I tried to concat them with dmsetup but again no luck. That’s how I used dmsetup :
# losetup /dev/loop1 LUN01
# losetup /dev/loop2 LUN02
# losetup /dev/loop3 LUN03
# losetup /dev/loop4 LUN04
# losetup /dev/loop5 LUN05
# blockdev --getsize /dev/loop1
1048577000
# cat > w2008.mapping
# Offset into Size of this Raid type Device Start sector
# volume device of device
0 1048577000 linear /dev/loop1 0
1048577000 1048577000 linear /dev/loop2 0
2097154000 1048577000 linear /dev/loop3 0
3145731000 1048577000 linear /dev/loop4 0
4194308000 1048577000 linear /dev/loop5 0
# dmsetup create myfs w2008.mapping
# mount -t ntfs /dev/mapper/myfs /mnt/final
NTFS signature is missing.
Failed to mount '/dev/loop1': Invalid argument
The device '/dev/loop1' doesn't seem to have a valid NTFS.
Maybe the wrong device is used? Or the whole disk instead of a
partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?
# echo Poo.
So still no NTFS filesystem ๐
Does anyone have any ideas about how I can extract the data from there or give me some pointers?
Allright, I will reply to my own question to avoid the same pain to others.
0. WARNING
In case you are doing a recovery, ALWAYS COPY YOUR DATA and work
on the copy. Do NOT alter the original ‘broken’ data. That thing
said, keep reading.
1. Your partition looks like …
Install sleuth kit and testdisk. Hopefully there will packages for your distro ๐
Note: testdisk will give you the same info with less details
# testdisk /list LUN01
2. Extract disks metadata
All information about the disk order, data size and other ciphered attributes
about the partition will be found in the LDM metadata partition. W2k8 has not
changed so much since this document [2] albeit some sizes are different and some
attributes are new (and obviously unknown)…
At line 0002410 you should see the name of the server. Reassuring ? But we are
after the disks order and disk ID. Scroll down.
2.1. Disks Order
At line 0003210 you should see ‘Disk1’ followed by a long string.
This means that the first disk of this Volume is identfied by the
following Unique ID (UID) : 79e80293-6eb1-11df-88dc-0026b9835db3
But at the moment, we don’t know which of the disk has this UID !
So move to the Disk2 entry and take note of its UID and so on for
all the disks you had in your volume. Note: Based on my experience
only the first 8 characters are changing, the rest stays the same.
Indeed, W2k8 seems to increment the ID by 6. $ is a separator.
Eg. :
2.2. Find Disk UID
Go to line 00e8200 (lun01.metadata). You should find ‘PRIVHEAD’.
What we are after is the disk UID of this particular disk. We see:
– Disk Id : 79e80299-6eb1-11df-88dc-0026b9835db3
– Host Id : 1b77da20-c717-11d0-a5be-00a0c91db73c
– Disk Group Id : 891d0e8f-d929-11e0-a8a7-0026b9835db5
So this disk with the UID 79e80299-… is Windows Disk2 but for us
it was Physical Disk 1. Indeed find this UID in the disk order you
found above.
Note: There is no logical order. I mean Windows decide how to setup
the disk order not you. So there is NO human logic and don’t expect
your first disk to be Disk1.
So don’t assume that the order above is going to follow any human
logic. I recommend you to go through all the LDM data of your disks
and extract their UID. (You can use the following command to just
extract the PRIVHEAD info: dd if=LUNXX skip=1890 count=1 |xxd -a)
e.g:
I am sure that somewhere in the LDM metadata you can find the type
of Volume (spanned, RAID0, RAIDX, and the associated stripe sizes)
However, I haven’t dug it. I used a ‘try and retry’ method to find
my data. So if you know how you setup your configuration before
the drama, you will save yourself a lot of time.
3. Find the NTFS filesystem and your data
Now we are interested in the big chunk of data we want to restore.
In my case it’s ~512GB of data so we won’t convert the whole in
ASCII. I haven’t really search how Windows find the beginning of
its NTFS partition. But what I found is that it logically starts
with the following keyword : R.NTFS. Let’s find this and find the
offset we will have to apply later to see our NTFS FS.
In this example, the data starts at 262178 and is 1048314789 sectors long
We found above that Disk1 (of the volume group) is actually the 2nd
physical disk. We will extract some of its information to find
where the NTFS partition start.
Here we can see that NTFS starts at 00fbc00. So knowing that we can
start to extract our data from sector 262178 + 00fbc00 bytes. Let’s
do a bit of hexadecimal to decimal conversion with bytes to sector
conversion as well.
0xfbc00 bytes = 1031168 bytes = 1031168/512 sectors = 2014 sectors
So our NTFS partition starts at 262178 + 2014 = 264192 sectors.
This value is going to be an offset we will use later on all disks.
Let’s called it the NTFS offset.
Obviously the total size is shrinked by the offset. So the new size is:
1048314789 – 2014 = 1048312775 sectors
4. Try to mount/see the data
From now on, either it will work out of the box because your NTFS partition is
healthy or it won’t because you’re doing this to recover some data.
The following process is the same whatever is your status. All the following is
based on [1] (see Links at the bottom)
A spanned volume, will fill a volume after another. Where as a striped (RAID0)
will copy chunk of data over many disks (a.k.a a file is spread across many
disks). In my case, I didn’t know if it was a spanned or striped volume. The
easiest way to know, if your volume is not full is to check if you have a lot
of zeroes at then end of all your volumes. If that’s the case then it’s striped.
Because if it’s spanned, if will fill the first disk, then the second. I am
not 100% sure of that but that’s what I observed. So dd a bunch of sectors
from the end of the LDM data partition.
4.0 Preparations to access your data
First mount your dd file or your device through a loopback device with the NTFS
offset and the size we calculated above. However the offset and size must be
in bytes not in sectors to be used with losetup.
offset = 264192*512 = 135266304
size = 1048312775*512 = 536736140800
Note: you can add ‘-r’ to mount in Read-Only mode.
Do the above for all the physical disks part of your volume. Display the result
with: losetup -a
Note: If you don’t have enough loop devices you can easily create more with :
# mknod -m0660 /dev/loopNUMBER b 7 NUMBER && chown root.disk /dev/loopNUMBER
Check your alignment by opening the first Disk of the group (eg: Disk2) to see
if the first line is R.NTFS. If not then your alignment is wrong. Verify your
calculations above and try again. Or you are not looking at the 1st Windows Disk
e.g:
All good. Let’s move to the annoying part ๐
4.1 Spanned
Spanned disks are actually a chain of disks. You fill the first then you use
the second one and so and so forth. Create a file which look like this, eg :
Notes:
– Remember to use the good disk order (you found before). eg: Physical Disk2
followed by Physical Disk1 and Physical Disk3
– 2096625550 = 2*1048312775 and obviously if you have a fourth disk it’s gonna
be 3 times the size for the offset for the 4th disk.
4.2 Striped
The problem with striped mode (aka RAID0) is you must know what is your stripe
size. Apparently by default it is 64k (in my case it was 128k but I dunno if it
was tuned by the Windows sysadmin:). Anyway if you don’t know it, you just have to
try all the possible standard values and see which one gives you a possible viable
NTFS filesystem.
Create a file like the following for 3 disks with a 128k chunk size
/!\ : Size of the volume is not exactly the size we calculated before. dmsetup needs
a volume size divisible by the chunk size (aka stripe size) AND by the number
of disks in the volume. So in our case. We have 3 disks of 1048312775 sectors
So the ‘normal’ size is 1048312775*3=3144938325 sectors but due to the above
contraint we will recalculate the size and round it
# echo “3144938325/128*128” | bc
3144938240 sectors
4.3 Mount it.
Now lets aggregate everything together with dmsetup :
If it does not mount. Then you can use testdisk :
5. Conclusion
The above worked for me. Your mileage may vary. And there is maybe a better and
easier way to do it. If so, share it so nobody else will have to go through this
hassle ๐ Also, it may look hard but it is not. As long as you copy your data
somewhere, just try and retry until you can see something. It took me 3 days to
understand how to put all the bits together. Hopefully the above will help you
to not waste 3 days.
Note: All examples above have been made up. There is maybe some inconsistencies
between the examples despite my thoroughness ๐
Good luck.
6. Links