summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2009-08-18 09:13:37 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2009-08-18 09:13:37 +0200
commit1f9997af851d03798ffff957c0d462d5c9ce1afe (patch)
tree87997ed42d5777700cd1bc16b6efa2db5241d1b3
parent32babefd2d759fd0905ea00cc73c71fe07645938 (diff)
TestDisk: locate ZFS partition beginning
-rw-r--r--src/Makefile.am4
-rw-r--r--src/analyse.c2
-rw-r--r--src/common.h37
-rw-r--r--src/partgpt.c1
-rw-r--r--src/partnone.c1
-rw-r--r--src/zfs.c105
-rw-r--r--src/zfs.h45
7 files changed, 179 insertions, 16 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b6fa4ca..51ad955 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,8 +16,8 @@ EXTRA_PROGRAMS =
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 log.c log_part.c misc.c msdos.c parti386.c partgpt.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 lang.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h
-fs_C = analyse.c bfs.c bsd.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
-fs_H = analyse.h bfs.h bsd.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
+fs_C = analyse.c bfs.c bsd.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 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
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 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 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 19b2dbb..ced1d55 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -53,6 +53,7 @@
#include "sysv.h"
#include "ufs.h"
#include "xfs.h"
+#include "zfs.h"
#include "log.h"
int search_NTFS_backup(unsigned char *buffer, disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind)
@@ -223,6 +224,7 @@ int search_type_16(unsigned char *buffer, disk_t *disk_car,partition_t *partitio
return -1;
/* Test UFS */
if(recover_ufs(disk_car,(const struct ufs_super_block*)buffer,partition,verbose,dump_ind)==0) return 1;
+ if(recover_ZFS(disk_car,(const struct vdev_boot_header*)buffer,partition,verbose,dump_ind)==0) return 1;
return 0;
}
diff --git a/src/common.h b/src/common.h
index d30a6e7..f58c455 100644
--- a/src/common.h
+++ b/src/common.h
@@ -132,6 +132,8 @@ struct efi_guid_s
((efi_guid_t){le32(0x516e7cb5),le16(0x6ecf),le16(0x11d6),0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}})
#define GPT_ENT_TYPE_FREEBSD_UFS \
((efi_guid_t){le32(0x516e7cb6),le16(0x6ecf),le16(0x11d6),0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}})
+#define GPT_ENT_TYPE_FREEBSD_ZFS \
+ ((efi_guid_t){le32(0x516e7cb),le16(0x6ecf),le16(0x11d6),0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}})
/*
* The following is unused but documented here to avoid reuse.
*
@@ -193,6 +195,7 @@ struct efi_guid_s
((efi_guid_t){le32(0x6a8b642b),le16(0x1dd2),le16(0x11b2),0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}})
#define GPT_ENT_TYPE_SOLARIS_USR \
((efi_guid_t){le32(0x6a898cc3),le16(0x1dd2),le16(0x11b2),0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}})
+#define GPT_ENT_TYPE_MAC_ZFS GPT_ENT_TYPE_SOLARIS_USR
#define GPT_ENT_TYPE_SOLARIS_VAR \
((efi_guid_t){le32(0x6a8ef2e9),le16(0x1dd2),le16(0x11b2),0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}})
#define GPT_ENT_TYPE_SOLARIS_HOME \
@@ -217,7 +220,7 @@ struct efi_guid_s
#define TESTDISK_O_READAHEAD_32K 010
#define TESTDISK_O_ALL 020
-enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXT4, UP_EXTENDED, UP_EXFAT, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4};
+enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXT4, UP_EXTENDED, UP_EXFAT, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4, UP_ZFS};
typedef enum upart_type upart_type_t;
enum status_type { STATUS_DELETED, STATUS_PRIM, STATUS_PRIM_BOOT, STATUS_LOG, STATUS_EXT, STATUS_EXT_IN_EXT};
typedef enum status_type status_type_t;
@@ -299,17 +302,12 @@ typedef struct arch_fnct_struct arch_fnct_t;
struct param_disk_struct
{
- uint64_t disk_size;
+ char description_txt[DISKDESCRIPTION_MAX];
+ char description_short_txt[DISKDESCRIPTION_MAX];
CHSgeometry_t geom; /* logical CHS */
- int write_used;
- int autodetect;
- int access_mode;
- int unit;
- unsigned int sector_size;
+ uint64_t disk_size;
char *device;
char *model;
- char description_txt[DISKDESCRIPTION_MAX];
- char description_short_txt[DISKDESCRIPTION_MAX];
const char *(*description)(disk_t *disk_car);
const char *(*description_short)(disk_t *disk_car);
int (*pread)(disk_t *disk_car, void *buf, const unsigned int count, const uint64_t offset);
@@ -327,30 +325,41 @@ struct param_disk_struct
void *wbuffer;
unsigned int rbuffer_size;
unsigned int wbuffer_size;
+ int write_used;
+ int autodetect;
+ int access_mode;
+ int unit;
+ unsigned int sector_size;
};
struct partition_struct
{
+ char fsname[80];
+ char partname[80];
+ char info[80];
uint64_t part_offset;
uint64_t part_size;
uint64_t sborg_offset;
uint64_t sb_offset;
unsigned int sb_size;
unsigned int blocksize;
+ efi_guid_t part_uuid;
+ efi_guid_t part_type_gpt;
unsigned int part_type_i386;
unsigned int part_type_sun;
unsigned int part_type_mac;
unsigned int part_type_xbox;
- efi_guid_t part_type_gpt;
- efi_guid_t part_uuid;
upart_type_t upart_type;
status_type_t status;
unsigned int order;
errcode_type_t errcode;
- char fsname[80];
- char partname[80];
- char info[80];
const arch_fnct_t *arch;
+ /* NTFS => utils_cluster_in_use */
+ /* ext2/ext3/ext4 */
+#if 0
+ int (*is_allocated)(disk_t *disk, const partition_t *partition, const uint64_t offset);
+ void *free_is_allocated(void);
+#endif
};
typedef struct my_data_struct my_data_t;
diff --git a/src/partgpt.c b/src/partgpt.c
index 1439f8a..f6987bb 100644
--- a/src/partgpt.c
+++ b/src/partgpt.c
@@ -83,6 +83,7 @@ const struct systypes_gtp gpt_sys_types[] = {
{ GPT_ENT_TYPE_FREEBSD_UFS, "FreeBSD UFS" },
{ GPT_ENT_TYPE_FREEBSD_VINUM, "FreeBSD Vinum" },
// { GPT_ENT_TYPE_FREEBSD_UFS2, "FreeBSD UFS2" },
+ { GPT_ENT_TYPE_FREEBSD_ZFS, "FreeBSD ZFS" },
{ GPT_ENT_TYPE_MS_RESERVED, "MS Reserved" },
{ GPT_ENT_TYPE_MS_BASIC_DATA, "MS Data" },
{ GPT_ENT_TYPE_MS_LDM_METADATA, "MS LDM MetaData" },
diff --git a/src/partnone.c b/src/partnone.c
index fadcb6e..692966b 100644
--- a/src/partnone.c
+++ b/src/partnone.c
@@ -118,6 +118,7 @@ static const struct systypes none_sys_types[] = {
{UP_XFS2, "XFS 2"},
{UP_XFS3, "XFS 3"},
{UP_XFS4, "XFS 4"},
+ {UP_ZFS, "ZFS"},
{ 0,NULL }
};
diff --git a/src/zfs.c b/src/zfs.c
new file mode 100644
index 0000000..cba94cd
--- /dev/null
+++ b/src/zfs.c
@@ -0,0 +1,105 @@
+/*
+
+ File: ZFS.c
+
+ 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.
+
+ */
+#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 "zfs.h"
+#include "fnctdsk.h"
+#include "log.h"
+#include "guid_cpy.h"
+
+static int test_ZFS(disk_t *disk, const struct vdev_boot_header *sb, partition_t *partition, const int dump_ind);
+static int set_ZFS_info(const struct vdev_boot_header *sb, partition_t *partition);
+
+int check_ZFS(disk_t *disk,partition_t *partition)
+{
+ unsigned char *buffer=(unsigned char*)MALLOC(DEFAULT_SECTOR_SIZE);
+ if(disk->pread(disk, buffer, DEFAULT_SECTOR_SIZE, partition->part_offset+0x2000) != DEFAULT_SECTOR_SIZE)
+ {
+ free(buffer);
+ return 1;
+ }
+ if(test_ZFS(disk, (struct vdev_boot_header*)buffer, partition, 0)!=0)
+ {
+ free(buffer);
+ return 1;
+ }
+ set_ZFS_info((struct vdev_boot_header*)buffer, partition);
+ free(buffer);
+ return 0;
+}
+
+static int set_ZFS_info(const struct vdev_boot_header *sb, partition_t *partition)
+{
+ sprintf(partition->info,"ZFS %lu (Data size unknown)", (long unsigned)le64(sb->vb_version));
+ return 0;
+}
+
+int recover_ZFS(disk_t *disk, const struct vdev_boot_header *sb,partition_t *partition,const int verbose, const int dump_ind)
+{
+ if(test_ZFS(disk, sb, partition, dump_ind)!=0)
+ return 1;
+ if(partition==NULL)
+ return 0;
+ set_ZFS_info(sb, partition);
+ partition->part_type_i386=P_LINUX;
+ partition->part_type_mac=PMAC_LINUX;
+ partition->part_type_sun=PSUN_LINUX;
+ partition->part_type_gpt=GPT_ENT_TYPE_SOLARIS_USR;
+ partition->part_size=(uint64_t)le64(sb->vb_offset);
+ partition->blocksize=0;
+ partition->sborg_offset=0;
+ partition->sb_offset=0;
+ if(verbose>0)
+ {
+ log_info("\n");
+ }
+ return 0;
+}
+
+static int test_ZFS(disk_t *disk, const struct vdev_boot_header *sb, partition_t *partition, const int dump_ind)
+{
+ if(le64(sb->vb_magic)!=VDEV_BOOT_MAGIC)
+ return 1;
+ if(dump_ind!=0)
+ {
+ if(partition!=NULL && disk!=NULL)
+ log_info("\nZFS 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_ZFS;
+ return 0;
+}
diff --git a/src/zfs.h b/src/zfs.h
new file mode 100644
index 0000000..e7541cb
--- /dev/null
+++ b/src/zfs.h
@@ -0,0 +1,45 @@
+/*
+
+ File: zfs.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 _ZFS_H
+#define _ZFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* ZFS boot block */
+#define VDEV_BOOT_MAGIC 0x2f5b007b10cULL
+#define VDEV_BOOT_VERSION 1 /* version number */
+#define VDEV_BOOT_HEADER_SIZE (8 << 10)
+
+typedef struct vdev_boot_header {
+ uint64_t vb_magic; /* VDEV_BOOT_MAGIC */
+ uint64_t vb_version; /* VDEV_BOOT_VERSION */
+ uint64_t vb_offset; /* start offset (bytes) */
+ uint64_t vb_size; /* size (bytes) */
+ char vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (uint64_t)];
+} vdev_boot_header_t;
+int check_ZFS(disk_t *disk,partition_t *partition);
+int recover_ZFS(disk_t *disk, const struct vdev_boot_header *ZFS_header,partition_t *partition,const int verbose, const int dump_ind);
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif