summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2011-01-07 20:52:33 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2011-01-07 20:52:33 +0100
commit2c4b6dcbb956f43b07ecb0d1f6ab661c934693bc (patch)
treef07d624b136400bb6b0336af74ee548089655ed4 /src
parent26f724eacd72e64f48db2aa6dda6718b6c446a6b (diff)
Fix exFAT recovery using backup boot sector
Diffstat (limited to 'src')
-rw-r--r--src/analyse.c4
-rw-r--r--src/exfat.c23
-rw-r--r--src/exfat.h6
-rw-r--r--src/godmode.c4
4 files changed, 23 insertions, 14 deletions
diff --git a/src/analyse.c b/src/analyse.c
index bfe9fc8..5aeae0b 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -108,9 +108,7 @@ int search_EXFAT_backup(unsigned char *buffer, disk_t *disk, partition_t *partit
if(le16(exfat_header->signature)==0xAA55 &&
recover_EXFAT(disk, exfat_header, partition)==0)
{
- strncpy(partition->info,"EXFAT found using backup sector!",sizeof(partition->info));
- partition->sb_offset=6*512;
- partition->part_offset-=partition->sb_offset; /* backup sector */
+ /* part_offset has already been updated if found using backup sector */
return 1;
}
}
diff --git a/src/exfat.c b/src/exfat.c
index 02a11c2..f0611c9 100644
--- a/src/exfat.c
+++ b/src/exfat.c
@@ -33,20 +33,21 @@
#include "types.h"
#include "common.h"
#include "exfat.h"
-static int test_EXFAT(const struct exfat_super_block *exfat_header, partition_t *partition);
-#define EXFAT_SIZE 512
static int set_EXFAT_info(partition_t *partition)
{
partition->fsname[0]='\0';
- strncpy(partition->info,"EXFAT",sizeof(partition->info));
+ if(partition->sb_offset==0)
+ strncpy(partition->info,"exFAT",sizeof(partition->info));
+ else
+ strncpy(partition->info,"exFAT found using backup sector!",sizeof(partition->info));
return 0;
}
int check_EXFAT(disk_t *disk_car, partition_t *partition)
{
- unsigned char *buffer=(unsigned char*)MALLOC(EXFAT_SIZE);
- if(disk_car->pread(disk_car, buffer, EXFAT_SIZE, partition->part_offset) != EXFAT_SIZE)
+ unsigned char *buffer=(unsigned char*)MALLOC(EXFAT_BS_SIZE);
+ if(disk_car->pread(disk_car, buffer, EXFAT_BS_SIZE, partition->part_offset) != EXFAT_BS_SIZE)
{
free(buffer);
return 1;
@@ -61,7 +62,7 @@ int check_EXFAT(disk_t *disk_car, partition_t *partition)
return 0;
}
-static int test_EXFAT(const struct exfat_super_block *exfat_header, partition_t *partition)
+int test_EXFAT(const struct exfat_super_block *exfat_header, partition_t *partition)
{
if(le16(exfat_header->signature)!=0xAA55)
return 1;
@@ -75,9 +76,17 @@ int recover_EXFAT(const disk_t *disk, const struct exfat_super_block *exfat_head
{
if(test_EXFAT(exfat_header, partition)!=0)
return 1;
- set_EXFAT_info(partition);
+ partition->sborg_offset=0;
+ partition->sb_size=12 << exfat_header->blocksize_bits;
partition->part_type_i386=P_EXFAT;
partition->part_type_gpt=GPT_ENT_TYPE_MS_BASIC_DATA;
partition->part_size=(uint64_t)le64(exfat_header->nr_sectors) * disk->sector_size;
+ if(le64(exfat_header->start_sector) +
+ (12 << exfat_header->blocksize_bits) == partition->part_offset)
+ {
+ partition->sb_offset=12 << exfat_header->blocksize_bits;
+ partition->part_offset-=partition->sb_offset;
+ }
+ set_EXFAT_info(partition);
return 0;
}
diff --git a/src/exfat.h b/src/exfat.h
index 02dfe1d..1753c5a 100644
--- a/src/exfat.h
+++ b/src/exfat.h
@@ -22,6 +22,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#define EXFAT_BS_SIZE 512
struct exfat_super_block {
unsigned char jmp_boot[3]; /* boot strap short or near jump */
@@ -41,8 +42,8 @@ struct exfat_super_block {
uint16_t state; /* state of this volume */
unsigned char blocksize_bits; /* bits of block size */
unsigned char block_per_clus_bits; /* bits of blocks per cluster */
- unsigned char xxxx03; /* ??? (0x01 or 0x00 (?)) */
- unsigned char xxxx04; /* ??? (0x80 or any value (?)) */
+ unsigned char number_of_fats;
+ unsigned char drive_select; /* Used by INT 13 */
unsigned char allocated_percent; /* 0x70 percentage of allocated space (?) */
unsigned char xxxx05[397]; /* ??? (0x00...) */
uint16_t signature; /* 0xaa55 */
@@ -50,6 +51,7 @@ struct exfat_super_block {
int check_EXFAT(disk_t *disk_car, partition_t *partition);
int recover_EXFAT(const disk_t *disk, const struct exfat_super_block *exfat_header, partition_t *partition);
+int test_EXFAT(const struct exfat_super_block *exfat_header, partition_t *partition);
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/src/godmode.c b/src/godmode.c
index 2c12865..640d1c0 100644
--- a/src/godmode.c
+++ b/src/godmode.c
@@ -578,8 +578,8 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
{
if((disk_car->arch==&arch_i386 &&
((start.sector==13 && (start.head<=2 || fast_mode>1)) ||
- (search_vista_part>0 && search_location%(2048*512)==(13-1)*512))) ||
- (disk_car->arch!=&arch_i386 && (search_location%location_boundary==(13-1)*512)))
+ (search_vista_part>0 && search_location%(2048*512)==(13-1)*disk_car->sector_size))) ||
+ (disk_car->arch!=&arch_i386 && (search_location%location_boundary==(13-1)*disk_car->sector_size)))
res=search_EXFAT_backup(buffer_disk, disk_car, partition);
test_nbr++;
}