1 /*
2
3 File: file_mig.c
4
5 Copyright (C) 2012 Christophe GRENIER <grenier@cgsecurity.org>
6
7 This software is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write the Free Software Foundation, Inc., 51
19 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29 #include <stdio.h>
30 #include "types.h"
31 #include "filegen.h"
32 #include "common.h"
33 #ifdef DEBUG_MIG
34 #include "log.h"
35 #endif
36
37 static void register_header_check_mig(file_stat_t *file_stat);
38
39 const file_hint_t file_hint_mig= {
40 .extension="mig",
41 .description="Windows Migration Backup",
42 .max_filesize=PHOTOREC_MAX_FILE_SIZE,
43 .recover=1,
44 .enable_by_default=1,
45 .register_header_check=®ister_header_check_mig
46 };
47
48 struct MIG_HDR
49 {
50 uint32_t magic;
51 uint32_t fn_size;
52 uint32_t s_size;
53 uint32_t unk1;
54 uint32_t unk2;
55 uint32_t unk3;
56 unsigned char fn[0];
57 } __attribute__ ((gcc_struct, __packed__));
58
file_check_mig(file_recovery_t * file_recovery)59 static void file_check_mig(file_recovery_t *file_recovery)
60 {
61 struct MIG_HDR h;
62 uint64_t offset=0x34;
63 file_recovery->file_size=0;
64 while(1)
65 {
66 size_t res;
67 if(my_fseek(file_recovery->handle, offset, SEEK_SET) < 0)
68 {
69 #ifdef DEBUG_MIG
70 log_info("0x%lx fseek failed\n", (long unsigned)offset);
71 #endif
72 return ;
73 }
74 res=fread(&h, 1, sizeof(h), file_recovery->handle);
75 if(res < 8)
76 {
77 #ifdef DEBUG_MIG
78 log_info("0x%lx not enough data\n", (long unsigned)offset);
79 #endif
80 return ;
81 }
82 if(res < sizeof(h) || le32(h.magic)!=0x5354524d) /* STRM=stream */
83 {
84 #ifdef DEBUG_MIG
85 log_info("0x%lx no magic %x\n", (long unsigned)offset, le32(h.magic));
86 #endif
87 file_recovery->file_size=offset+8;
88 return ;
89 }
90 #ifdef DEBUG_MIG
91 log_info("0x%lx magic s_size=0x%u\n", (long unsigned)offset, le32(h.s_size));
92 #endif
93 offset+=sizeof(h)+le32(h.s_size);
94 }
95 }
96
header_check_mig(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)97 static int header_check_mig(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)
98 {
99 if(memcmp(&buffer[0x34], "MRTS", 4)!=0)
100 return 0;
101 reset_file_recovery(file_recovery_new);
102 file_recovery_new->extension=file_hint_mig.extension;
103 file_recovery_new->file_check=&file_check_mig;
104 return 1;
105 }
106
register_header_check_mig(file_stat_t * file_stat)107 static void register_header_check_mig(file_stat_t *file_stat)
108 {
109 static const unsigned char mig_header[8]= {
110 '1' , 'g' , 'i' , 'M' , 0x02, 0x00, 0x00, 0x00
111 };
112 register_header_check(0, mig_header, sizeof(mig_header), &header_check_mig, file_stat);
113 }
114