... | ... |
@@ -311,21 +311,14 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t |
311 | 311 |
} |
312 | 312 |
} |
313 | 313 |
} else if (ret == CL_TYPE_MBR) { |
314 |
- const unsigned char *rbuff = buff+512; |
|
315 |
- int ri; |
|
316 |
- |
|
317 |
- /* raw dmgs must be a multiple of 512 */ |
|
318 |
- if ((map->len % 512) == 0 && map->len > 512) { |
|
319 |
- /* check if the MBR is a valid configuration */ |
|
320 |
- if (cli_mbr_check(buff, bread, map->len) == 0) { |
|
321 |
- return CL_TYPE_MBR; |
|
322 |
- } |
|
323 |
- |
|
324 |
- /* check if detected MBR is protective or hybridon GPT */ |
|
325 |
- if (cli_mbr_check_gpt(buff, bread) != 0) { |
|
326 |
- cli_dbgmsg("Recognized GUID Partition Table file\n"); |
|
327 |
- return CL_TYPE_GPT; |
|
328 |
- } |
|
314 |
+ /* given filetype sig type 0 */ |
|
315 |
+ int iret = cli_mbr_check(buff, bread, map->len); |
|
316 |
+ if (iret == CL_TYPE_GPT) { |
|
317 |
+ cli_dbgmsg("Recognized GUID Partition Table file\n"); |
|
318 |
+ return CL_TYPE_GPT; |
|
319 |
+ } |
|
320 |
+ else if (iret == CL_CLEAN) { |
|
321 |
+ return CL_TYPE_MBR; |
|
329 | 322 |
} |
330 | 323 |
|
331 | 324 |
/* re-detect type */ |
... | ... |
@@ -177,7 +177,7 @@ static const char *ftypes_int[] = { |
177 | 177 |
"4:1024:482B0004:HFS+ partition:CL_TYPE_PART_ANY:CL_TYPE_PART_HFSPLUS:75", |
178 | 178 |
"4:1024:48580005:HFSX partition:CL_TYPE_PART_ANY:CL_TYPE_PART_HFSPLUS:75", |
179 | 179 |
"0:0:FD377A585A00:XZ container file:CL_TYPE_ANY:CL_TYPE_XZ:75", |
180 |
- "0:510:55AA:Disk Image - Master Boot Record:CL_TYPE_ANY:CL_TYPE_MBR:77", |
|
180 |
+ "1:510:55AA:Disk Image - Master Boot Record:CL_TYPE_ANY:CL_TYPE_MBR:77", |
|
181 | 181 |
"0:512:4546492050415254:Disk Image - GUID Partition Table:CL_TYPE_ANY:CL_TYPE_GPT:77", |
182 | 182 |
"1:0:4552{510}504D0000:Disk Image - Apple Partition Map:CL_TYPE_ANY:CL_TYPE_APM:77", |
183 | 183 |
NULL |
... | ... |
@@ -89,26 +89,49 @@ int cli_mbr_check(const unsigned char *buff, size_t len, size_t maplen) { |
89 | 89 |
memcpy(&mbr, buff+mbr_base, sizeof(mbr)); |
90 | 90 |
mbr_convert_to_host(&mbr); |
91 | 91 |
|
92 |
- //mbr_printbr(&mbr); |
|
92 |
+ if ((mbr.entries[0].type == MBR_PROTECTIVE) || (mbr.entries[0].type == MBR_HYBRID)) |
|
93 |
+ return CL_TYPE_GPT; |
|
93 | 94 |
|
94 | 95 |
return mbr_check_mbr(&mbr, maplen, sectorsize); |
95 | 96 |
} |
96 | 97 |
|
97 |
-int cli_mbr_check_gpt(const unsigned char *buff, size_t len) { |
|
98 |
+int cli_mbr_check2(cli_ctx *ctx, size_t sectorsize) { |
|
98 | 99 |
struct mbr_boot_record mbr; |
99 |
- off_t mbr_base = 0; |
|
100 |
- size_t sectorsize = 512; |
|
100 |
+ off_t pos = 0, mbr_base = 0; |
|
101 |
+ size_t maplen; |
|
101 | 102 |
|
102 |
- if (len < sectorsize) { |
|
103 |
- return CL_EFORMAT; |
|
103 |
+ if (!ctx || !ctx->fmap) { |
|
104 |
+ cli_errmsg("cli_scanmbr: Invalid context\n"); |
|
105 |
+ return CL_ENULLARG; |
|
104 | 106 |
} |
105 | 107 |
|
108 |
+ /* sector size calculation, actual value is OS dependent */ |
|
109 |
+ if (sectorsize == 0) |
|
110 |
+ sectorsize = MBR_SECTOR_SIZE; |
|
111 |
+ |
|
106 | 112 |
mbr_base = sectorsize - sizeof(struct mbr_boot_record); |
107 |
- memcpy(&mbr, buff+mbr_base, sizeof(mbr)); |
|
108 |
- mbr_convert_to_host(&mbr); |
|
109 | 113 |
|
110 |
- return ((mbr.entries[0].type == MBR_PROTECTIVE) || |
|
111 |
- (mbr.entries[0].type == MBR_HYBRID)); |
|
114 |
+ /* size of total file must be a multiple of the sector size */ |
|
115 |
+ maplen = (*ctx->fmap)->real_len; |
|
116 |
+ if ((maplen % sectorsize) != 0) { |
|
117 |
+ cli_dbgmsg("cli_scanmbr: File sized %u is not a multiple of sector size %u\n", |
|
118 |
+ maplen, sectorsize); |
|
119 |
+ return CL_EFORMAT; |
|
120 |
+ } |
|
121 |
+ |
|
122 |
+ /* sector 0 (first sector) is the master boot record */ |
|
123 |
+ pos = (MBR_SECTOR * sectorsize) + mbr_base; |
|
124 |
+ |
|
125 |
+ /* read the master boot record */ |
|
126 |
+ if (fmap_readn(*ctx->fmap, &mbr, pos, sizeof(mbr)) != sizeof(mbr)) { |
|
127 |
+ cli_dbgmsg("cli_scanmbr: Invalid master boot record\n"); |
|
128 |
+ return CL_EFORMAT; |
|
129 |
+ } |
|
130 |
+ |
|
131 |
+ if ((mbr.entries[0].type == MBR_PROTECTIVE) || (mbr.entries[0].type == MBR_HYBRID)) |
|
132 |
+ return CL_TYPE_GPT; |
|
133 |
+ |
|
134 |
+ return mbr_check_mbr(&mbr, maplen, sectorsize); |
|
112 | 135 |
} |
113 | 136 |
|
114 | 137 |
/* sets sectorsize to default value if specfied to be 0 */ |
... | ... |
@@ -448,6 +471,12 @@ static int mbr_check_mbr(struct mbr_boot_record *record, size_t maplen, size_t s |
448 | 448 |
return CL_EFORMAT; |
449 | 449 |
} |
450 | 450 |
|
451 |
+ /* check the maplen */ |
|
452 |
+ if ((maplen / sectorsize) < 2) { |
|
453 |
+ cli_dbgmsg("cli_scanmbr: file is too small to hold disk image\n"); |
|
454 |
+ return CL_EFORMAT; |
|
455 |
+ } |
|
456 |
+ |
|
451 | 457 |
return CL_CLEAN; |
452 | 458 |
} |
453 | 459 |
|
... | ... |
@@ -85,7 +85,7 @@ struct mbr_boot_record { |
85 | 85 |
#endif |
86 | 86 |
|
87 | 87 |
int cli_mbr_check(const unsigned char *buff, size_t len, size_t maplen); |
88 |
-int cli_mbr_check_gpt(const unsigned char *buff, size_t len); |
|
88 |
+int cli_mbr_check2(cli_ctx *ctx, size_t sectorsize); |
|
89 | 89 |
int cli_scanmbr(cli_ctx *ctx, size_t sectorsize); |
90 | 90 |
void mbr_convert_to_host(struct mbr_boot_record *record); |
91 | 91 |
|
... | ... |
@@ -2280,6 +2280,23 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2280 | 2280 |
} |
2281 | 2281 |
break; |
2282 | 2282 |
|
2283 |
+ case CL_TYPE_MBR: |
|
2284 |
+ { |
|
2285 |
+ int iret = cli_mbr_check2(ctx, 0); |
|
2286 |
+ if (iret == CL_TYPE_GPT) { |
|
2287 |
+ cli_dbgmsg("Recognized GUID Partition Table file\n"); |
|
2288 |
+ ctx->container_type = CL_TYPE_GPT; |
|
2289 |
+ nret = cli_scangpt(ctx, 0); |
|
2290 |
+ cli_dbgmsg("GPT signature found at %u\n", (unsigned int) fpt->offset); |
|
2291 |
+ } |
|
2292 |
+ else if (iret == CL_CLEAN) { |
|
2293 |
+ ctx->container_type = CL_TYPE_MBR; |
|
2294 |
+ nret = cli_scanmbr(ctx, 0); |
|
2295 |
+ cli_dbgmsg("MBR signature found at %u\n", (unsigned int) fpt->offset); |
|
2296 |
+ } |
|
2297 |
+ } |
|
2298 |
+ break; |
|
2299 |
+ |
|
2283 | 2300 |
case CL_TYPE_PDF: |
2284 | 2301 |
if(type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { |
2285 | 2302 |
ctx->container_type = CL_TYPE_PDF; |
... | ... |
@@ -3137,8 +3154,8 @@ int cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx, |
3137 | 3137 |
long long len1, len2; |
3138 | 3138 |
len1 = old_off + old_len; |
3139 | 3139 |
len2 = map->nested_offset + map->len; |
3140 |
- cli_warnmsg("internal map error: %ld, %lld; %ld, %lld\n", old_off, |
|
3141 |
- len1, map->offset, len2); |
|
3140 |
+ cli_warnmsg("internal map error: %lu, %llu; %lu, %llu\n", (long unsigned)old_off, |
|
3141 |
+ (long long unsigned)len1, (long unsigned)map->offset, (long long unsigned)len2); |
|
3142 | 3142 |
} |
3143 | 3143 |
|
3144 | 3144 |
ctx->fmap--; |