summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2011-07-20 07:43:29 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2011-07-20 07:43:29 +0200
commitfbdc01bbc359a38383ce36db1682e0db6c1f4046 (patch)
treec5face36f2cee2c5c049b2899e0e76e8ce81fd3d /src
parentfcb2816ea33817d6f23ec617c3336a2a74dc04d0 (diff)
Add detection of Vmware VMFS partition
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/analyse.c21
-rw-r--r--src/analyse.h1
-rw-r--r--src/common.h1
-rw-r--r--src/godmode.c9
-rw-r--r--src/partnone.c9
-rw-r--r--src/vmfs.c102
-rw-r--r--src/vmfs.h49
8 files changed, 192 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3581b75..9f4c5e0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,8 +16,8 @@ EXTRA_PROGRAMS = photorecf
base_C = autoset.c common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c iso.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c parthumax.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c
base_H = alignio.h autoset.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h iso.h iso9660.h lang.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h parthumax.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h
-fs_C = analyse.c bfs.c bsd.c btrfs.c cramfs.c exfat.c fat.c fatx.c ext2.c jfs.c hfs.c hfsp.c hpfs.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c xfs.c zfs.c
-fs_H = analyse.h bfs.h bsd.h btrfs.h cramfs.h exfat.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h hfs.h hfsp.h hpfs.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h xfs.h zfs.h
+fs_C = analyse.c bfs.c bsd.c btrfs.c cramfs.c exfat.c fat.c fatx.c ext2.c jfs.c hfs.c hfsp.c hpfs.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c vmfs.c xfs.c zfs.c
+fs_H = analyse.h bfs.h bsd.h btrfs.h cramfs.h exfat.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h hfs.h hfsp.h hpfs.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h vmfs.h xfs.h zfs.h
testdisk_ncurses_C = addpart.c adv.c askloc.c chgtype.c chgtypen.c dimage.c dirn.c dirpart.c diskacc.c diskcapa.c edit.c ext2_sb.c ext2_sbn.c fat1x.c fat32.c fat_adv.c fat_cluster.c fatn.c geometry.c godmode.c hiddenn.c intrface.c intrfn.c nodisk.c ntfs_adv.c ntfs_fix.c ntfs_udl.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c tanalyse.c tbanner.c tdelete.c tdiskop.c tdisksel.c testdisk.c texfat.c thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
testdisk_ncurses_H = addpart.h adv.h askloc.h chgtype.h chgtypen.h dimage.h dirn.h dirpart.h diskacc.h diskcapa.h edit.h ext2_sb.h ext2_sbn.h fat1x.h fat32.h fat_adv.h fat_cluster.h fatn.h geometry.h godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h texfat.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
diff --git a/src/analyse.c b/src/analyse.c
index b3c967d..269d814 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -53,6 +53,7 @@
#include "swap.h"
#include "sysv.h"
#include "ufs.h"
+#include "vmfs.h"
#include "xfs.h"
#include "zfs.h"
#include "log.h"
@@ -380,6 +381,26 @@ int search_type_128(unsigned char *buffer, disk_t *disk, partition_t *partition,
return 0;
}
+int search_type_2048(unsigned char *buffer, disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
+{
+ void *data;
+ if(verbose>2)
+ {
+ log_trace("search_type_2048 lba=%lu\n",
+ (long unsigned)(partition->part_offset/disk->sector_size));
+ }
+ data=disk->pread_fast(disk, buffer, 2*DEFAULT_SECTOR_SIZE, partition->part_offset + 2048 * 512);
+ if(data==NULL)
+ return -1;
+ {
+ const struct vmfs_volume *sb_vmfs=(const struct vmfs_volume *)data;
+ if(le32(sb_vmfs->magic)==0xc001d00d &&
+ recover_VMFS(disk, sb_vmfs, partition, verbose, dump_ind)==0)
+ return 1;
+ }
+ return 0;
+}
+
int check_linux(disk_t *disk, partition_t *partition, const int verbose)
{
if(check_JFS(disk, partition)==0 ||
diff --git a/src/analyse.h b/src/analyse.h
index d0a95cc..a6c4f88 100644
--- a/src/analyse.h
+++ b/src/analyse.h
@@ -30,6 +30,7 @@ int search_type_8(unsigned char *buffer, disk_t *disk_car,partition_t *partition
int search_type_16(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_type_64(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_type_128(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
+int search_type_2048(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_EXFAT_backup(unsigned char *buffer, disk_t *disk, partition_t *partition);
int search_FAT_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind);
int search_HFS_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind);
diff --git a/src/common.h b/src/common.h
index 1483087..f3236d9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -262,6 +262,7 @@ enum upart_type {
UP_SYSV4,
UP_UFS,
UP_UFS2,
+ UP_VMFS,
UP_XFS,
UP_XFS2,
UP_XFS3,
diff --git a/src/godmode.c b/src/godmode.c
index 640d1c0..ce2d1b3 100644
--- a/src/godmode.c
+++ b/src/godmode.c
@@ -644,7 +644,7 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
if(res<=0 && test_nbr==6)
{
if(search_now==0)
- test_nbr=13;
+ test_nbr=14;
else
{
if(disk_car->pread(disk_car, buffer_disk0, 8 * DEFAULT_SECTOR_SIZE, partition->part_offset) == 8 * DEFAULT_SECTOR_SIZE)
@@ -691,7 +691,12 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
res=search_type_128(buffer_disk,disk_car,partition,verbose,dump_ind);
test_nbr++;
}
- if(test_nbr>=13)
+ if(res<=0 && test_nbr==13)
+ {
+ res=search_type_2048(buffer_disk,disk_car,partition,verbose,dump_ind);
+ test_nbr++;
+ }
+ if(test_nbr>=14)
{
sector_inc=1;
test_nbr=0;
diff --git a/src/partnone.c b/src/partnone.c
index 5026004..ef02c51 100644
--- a/src/partnone.c
+++ b/src/partnone.c
@@ -65,6 +65,7 @@
#include "swap.h"
#include "ufs.h"
#include "xfs.h"
+#include "vmfs.h"
#include "log.h"
static int check_part_none(disk_t *disk_car, const int verbose,partition_t *partition,const int saveheader);
@@ -119,6 +120,7 @@ static const struct systypes none_sys_types[] = {
{UP_UFS, "UFS"},
{UP_UFS2, "UFS 2"},
{UP_UNK, "Unknown"},
+ {UP_VMFS, "VMFS"},
{UP_XFS, "XFS"},
{UP_XFS2, "XFS 2"},
{UP_XFS3, "XFS 3"},
@@ -225,6 +227,10 @@ static list_part_t *read_part_none(disk_t *disk, const int verbose, const int sa
res=search_type_128(buffer_disk, disk, partition,verbose,0);
}
if(res<=0)
+ {
+ res=search_type_2048(buffer_disk, disk, partition,verbose,0);
+ }
+ if(res<=0)
{ /* Search FAT32 backup */
partition->part_offset = 6*512;
res=search_FAT_backup(buffer_disk, disk, partition, verbose, 0);
@@ -414,6 +420,9 @@ static int check_part_none(disk_t *disk_car,const int verbose,partition_t *parti
case UP_UFS2:
ret=check_ufs(disk_car,partition,verbose);
break;
+ case UP_VMFS:
+ ret=check_VMFS(disk_car, partition);
+ break;
case UP_XFS:
case UP_XFS2:
case UP_XFS3:
diff --git a/src/vmfs.c b/src/vmfs.c
new file mode 100644
index 0000000..0a2fd0d
--- /dev/null
+++ b/src/vmfs.c
@@ -0,0 +1,102 @@
+/*
+
+ File: vmfs.c
+
+ Copyright (C) 2011 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <stdio.h>
+#include "types.h"
+#include "common.h"
+#include "fnctdsk.h"
+#include "log.h"
+#include "vmfs.h"
+
+static int test_VMFS(disk_t *disk, const struct vmfs_volume *sb, partition_t *partition, const int dump_ind);
+static int set_VMFS_info(const struct vmfs_volume *sb, partition_t *partition);
+
+int check_VMFS(disk_t *disk,partition_t *partition)
+{
+ unsigned char *buffer=(unsigned char*)MALLOC(2*DEFAULT_SECTOR_SIZE);
+ if(disk->pread(disk, buffer, 2*DEFAULT_SECTOR_SIZE, partition->part_offset+0x100000) != DEFAULT_SECTOR_SIZE)
+ {
+ free(buffer);
+ return 1;
+ }
+ if(test_VMFS(disk, (struct vmfs_volume*)buffer, partition, 0)!=0)
+ {
+ free(buffer);
+ return 1;
+ }
+ set_VMFS_info((struct vmfs_volume*)buffer, partition);
+ free(buffer);
+ return 0;
+}
+
+static int set_VMFS_info(const struct vmfs_volume *sb, partition_t *partition)
+{
+ sprintf(partition->info,"VMFS %lu", (long unsigned)le32(sb->version));
+ return 0;
+}
+
+int recover_VMFS(disk_t *disk, const struct vmfs_volume *sb, partition_t *partition, const int verbose, const int dump_ind)
+{
+ const struct vmfs_lvm* lvm=(const struct vmfs_lvm*)(((const char *)sb)+0x200);
+ if(test_VMFS(disk, sb, partition, dump_ind)!=0)
+ return 1;
+ if(partition==NULL)
+ return 0;
+ set_VMFS_info(sb, partition);
+ partition->part_type_i386=P_VMFS;
+ partition->part_size=(uint64_t)le64(lvm->size);
+ partition->blocksize=0;
+ partition->sborg_offset=0;
+ partition->sb_offset=0;
+ if(verbose>0)
+ {
+ log_info("\n");
+ }
+ return 0;
+}
+
+static int test_VMFS(disk_t *disk, const struct vmfs_volume *sb, partition_t *partition, const int dump_ind)
+{
+ if(le32(sb->magic)!=0xc001d00d)
+ return 1;
+ if(dump_ind!=0)
+ {
+ if(partition!=NULL && disk!=NULL)
+ log_info("\nVMFS magic value at %u/%u/%u\n",
+ offset2cylinder(disk,partition->part_offset),
+ offset2head(disk,partition->part_offset),
+ offset2sector(disk,partition->part_offset));
+ dump_log(sb,DEFAULT_SECTOR_SIZE);
+ }
+ if(partition==NULL)
+ return 0;
+ partition->upart_type=UP_VMFS;
+ return 0;
+}
diff --git a/src/vmfs.h b/src/vmfs.h
new file mode 100644
index 0000000..e7dc37b
--- /dev/null
+++ b/src/vmfs.h
@@ -0,0 +1,49 @@
+/*
+
+ File: vmfs.h
+
+ Copyright (C) 2009 Christophe GRENIER <grenier@cgsecurity.org>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef _VMFS_H
+#define _VMFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* VMFS boot block */
+#define VDEV_BOOT_MAGIC 0x2f5b007b10cULL
+#define VDEV_BOOT_VERSION 1 /* version number */
+#define VDEV_BOOT_HEADER_SIZE (8 << 10)
+
+struct vmfs_volume
+{
+ uint32_t magic;
+ uint32_t version;
+} __attribute__ ((__packed__));
+struct vmfs_lvm
+{
+ uint64_t size;
+ uint64_t blocks;
+} __attribute__ ((__packed__));
+
+int check_VMFS(disk_t *disk,partition_t *partition);
+int recover_VMFS(disk_t *disk, const struct vmfs_volume *sb, partition_t *partition, const int verbose, const int dump_ind);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif