summaryrefslogtreecommitdiffstats
path: root/src/file_wpd.c
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2014-07-26 22:53:13 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2014-07-26 22:53:13 +0200
commit2d417ff85bc4df08cdcaa00542eb5de9cd6b8171 (patch)
treeaefd1f18c3c44a29231a4be781c5e2ddcf9fa396 /src/file_wpd.c
parent497b80da24e2c610e00a8a7ef5d4a5fd07bba835 (diff)
PhotoRec: stricter check for .wpd
Diffstat (limited to 'src/file_wpd.c')
-rw-r--r--src/file_wpd.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/src/file_wpd.c b/src/file_wpd.c
index 38e7c19..b2e692d 100644
--- a/src/file_wpd.c
+++ b/src/file_wpd.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include "types.h"
#include "filegen.h"
+#include "common.h"
static void register_header_check_wpd(file_stat_t *file_stat);
static int header_check_wpd(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
@@ -43,7 +44,6 @@ const file_hint_t file_hint_wpd= {
.register_header_check=&register_header_check_wpd
};
-static const unsigned char wpd_header[4]= {0xff, 'W','P','C'};
struct wpd_hdr
{
unsigned char magic[4];
@@ -53,40 +53,54 @@ struct wpd_hdr
uint8_t majorVersion;
uint8_t minorVersion;
uint16_t documentEncryption;
+ uint16_t indexHeaderOffset; /* 14 */
+ uint32_t unk;
+ uint32_t documentSize; /* 20: WP 6.1 or later ? */
} __attribute__ ((__packed__));
-static void register_header_check_wpd(file_stat_t *file_stat)
-{
- register_header_check(0, wpd_header,sizeof(wpd_header), &header_check_wpd, file_stat);
-}
-
static int header_check_wpd(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
const struct wpd_hdr *hdr=(const struct wpd_hdr *)buffer;
- if(memcmp(buffer, wpd_header, sizeof(wpd_header))==0 &&
- hdr->fileType==0x0a && hdr->majorVersion==0x02)
+ if(hdr->fileType==0x0a && hdr->majorVersion==0x02)
{
/* WP 6 */
+ if(hdr->minorVersion == 0)
+ {
+ if(le32(hdr->documentOffset) < 20)
+ return 0;
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->extension=file_hint_wpd.extension;
+ file_recovery_new->min_filesize=le32(hdr->documentOffset);
+ return 1;
+ }
+ if( le32(hdr->documentOffset) < sizeof(struct wpd_hdr) ||
+ le32(hdr->documentSize) < le32(hdr->documentOffset))
+ return 0;
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_wpd.extension;
- file_recovery_new->min_filesize=24;
- file_recovery_new->calculated_file_size=(uint64_t)buffer[20]+(((uint64_t)buffer[21])<<8)+(((uint64_t)buffer[22])<<16)+(((uint64_t)buffer[23])<<24);
+ file_recovery_new->calculated_file_size=le32(hdr->documentSize);
file_recovery_new->data_check=&data_check_size;
file_recovery_new->file_check=&file_check_size;
return 1;
}
- if(memcmp(buffer, wpd_header, sizeof(wpd_header))==0 &&
- (
- /* WP5 */
- (hdr->fileType==0x0a && hdr->majorVersion==0x00) ||
- /* WP MAC 2.x, 3.0-3.5, 3.5e */
- (hdr->fileType==0x2c && (hdr->majorVersion>=0x02 && hdr->majorVersion<=0x04))
- )
+ if( /* WP5 */
+ (hdr->fileType==0x0a && hdr->majorVersion==0x00) ||
+ /* WP MAC 2.x, 3.0-3.5, 3.5e */
+ (hdr->fileType==0x2c && (hdr->majorVersion>=0x02 && hdr->majorVersion<=0x04))
)
{
+ if(le32(hdr->documentOffset) < 20)
+ return 0;
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_wpd.extension;
+ file_recovery_new->min_filesize=le32(hdr->documentOffset);
return 1;
}
return 0;
}
+
+static void register_header_check_wpd(file_stat_t *file_stat)
+{
+ static const unsigned char wpd_header[4]= {0xff, 'W','P','C'};
+ register_header_check(0, wpd_header,sizeof(wpd_header), &header_check_wpd, file_stat);
+}