Browse code

mbr: adjusted filetype checks and changed to type 1 filetype sig

Kevin Lin authored on 2014/03/14 04:25:33
Showing 5 changed files
... ...
@@ -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--;