示例#1
0
/* 
 * Load the primary partition table (MBR) into the internal
 * data structures in MM_INFO
 *
 * This will automatically call load_ext_table for extended
 * partitions
 *
 * sect_cur is the addres of the table to load
 *
 * 0 is returned if the load is successful and 1 if error
 */
static uint8_t
dos_load_prim_table(MM_INFO * mm, uint8_t test)
{
    dos_sect sect;
    int i;
    char *table_str;
    SSIZE_T cnt;
    DADDR_T taddr = mm->offset / mm->block_size + DOS_PART_SOFFSET;
    DADDR_T max_addr = (mm->img_info->size - mm->offset) / mm->block_size;	// max sector

    if (verbose)
	fprintf(stderr,
	    "dos_load_prim: Table Sector: %" PRIuDADDR "\n", taddr);

    /* Read the table */
    cnt = mm_read_block_nobuf
	(mm, (char *) &sect, sizeof(sect), DOS_PART_SOFFSET);

    if (cnt != sizeof(sect)) {
	snprintf(tsk_errstr2, TSK_ERRSTR_L,
	    "Primary DOS table sector %" PRIuDADDR, taddr);
	if (cnt != -1) {
	    tsk_errno = TSK_ERR_MM_READ;
	    tsk_errstr[0] = '\0';
	}
	return 1;
    }


    /* Sanity Check */
    if (mm_guessu16(mm, sect.magic, DOS_MAGIC)) {
	tsk_errno = TSK_ERR_MM_MAGIC;
	snprintf(tsk_errstr, TSK_ERRSTR_L,
	    "File is not a DOS partition (invalid primary magic) (Sector: %"
	    PRIuDADDR ")", taddr);
	tsk_errstr2[0] = '\0';
	return 1;
    }

    /* Because FAT and NTFS use the same magic - check for a
     * standard MS OEM name and sizes.  Not a great check, but we can't 
     * really test the table entries.  
     */
    if (test) {

	if (verbose)
	    fprintf(stderr,
		"dos_load_prim_table: Testing FAT/NTFS conditions\n");

	if (strncmp("MSDOS", sect.oemname, 5) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: MSDOS OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
	else if (strncmp("MSWIN", sect.oemname, 5) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: MSWIN OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
	else if (strncmp("NTFS", sect.oemname, 4) == 0) {
	    tsk_errno = TSK_ERR_MM_MAGIC;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: NTFS OEM name exists");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
    }

    /* Add an entry of 1 sector for the table  to the internal structure */
    if ((table_str = mymalloc(32)) == NULL)
	return 1;

    snprintf(table_str, 32, "Primary Table (#0)");
    if (NULL == mm_part_add(mm, DOS_PART_SOFFSET, (DADDR_T) 1,
	    MM_TYPE_DESC, table_str, -1, -1))
	return 1;

    /* Cycle through the partition table */
    for (i = 0; i < 4; i++) {
	dos_part *part = &sect.ptable[i];

	/* We currently ignore CHS */
	uint32_t part_start = getu32(mm, part->start_sec);
	uint32_t part_size = getu32(mm, part->size_sec);

	if (verbose)
	    fprintf(stderr,
		"load_pri:0:%d    Start: %" PRIu32 "   Size: %" PRIu32
		"  Type: %d\n", i, part_start, part_size, part->ptype);

	if (part_size == 0)
	    continue;

	if (part_start > max_addr) {
	    tsk_errno = TSK_ERR_MM_BLK_NUM;
	    snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: Starting sector too large for image");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
#if 0
// I'm not sure if this is too strict ...
	else if ((part_start + part_size) > max_addr) {
	    tsk_errno = TSK_ERR_MM_BLK_NUM
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		"dos_load_prim_table: Partition ends after image");
	    tsk_errstr2[0] = '\0';
	    return 1;
	}
#endif

	/* Add the partition to the internal structure 
	 * If it is an extended partition, process it now */
	if (dos_is_ext(part->ptype)) {
	    if (NULL == mm_part_add(mm, (DADDR_T) part_start,
		    (DADDR_T) part_size, MM_TYPE_DESC,
		    dos_get_desc(part->ptype), 0, i))
		return 1;

	    if (dos_load_ext_table(mm, part_start, part_start, 1))
		return 1;
	}
	else {
	    if (NULL == mm_part_add(mm, (DADDR_T) part_start,
		    (DADDR_T) part_size, MM_TYPE_VOL,
		    dos_get_desc(part->ptype), 0, i))
		return 1;
	}
    }
    return 0;
}
示例#2
0
/*
 * Load the primary partition table (MBR) into the internal
 * data structures in TSK_VS_INFO
 *
 * This will automatically call load_ext_table for extended
 * partitions
 *
 * sect_cur is the address of the table to load
 *
 * 0 is returned if the load is successful and 1 if error
 */
static uint8_t
dos_load_prim_table(TSK_VS_INFO * vs, uint8_t test)
{
    dos_sect *sect;
    char *sect_buf;
    int i, added = 0;
    char *table_str;
    ssize_t cnt;
    TSK_DADDR_T taddr = vs->offset / vs->block_size + DOS_PART_SOFFSET;
    TSK_DADDR_T max_addr = (vs->img_info->size - vs->offset) / vs->block_size;  // max sector

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "dos_load_prim: Table Sector: %" PRIuDADDR "\n", taddr);

    if ((sect_buf = tsk_malloc(vs->block_size)) == NULL)
        return 1;
    sect = (dos_sect *) sect_buf;

    /* Read the table */
    cnt = tsk_vs_read_block
        (vs, DOS_PART_SOFFSET, sect_buf, vs->block_size);

    if (cnt != vs->block_size) {
        if (cnt >= 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_READ);
        }
        tsk_error_set_errstr2("Primary DOS table sector %" PRIuDADDR,
            taddr);
        free(sect_buf);
        return 1;
    }


    /* Sanity Check */
    if (tsk_vs_guessu16(vs, sect->magic, DOS_MAGIC)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
        tsk_error_set_errstr
            ("File is not a DOS partition (invalid primary magic) (Sector: %"
            PRIuDADDR ")", taddr);
        if (tsk_verbose)
            fprintf(stderr,
                "File is not a DOS partition (invalid primary magic) (Sector: %"
                PRIuDADDR ")", taddr);
        free(sect_buf);
        return 1;
    }

    /* Because FAT and NTFS use the same magic - check for a
     * standard MS OEM name and sizes.  Not a great check, but we can't
     * really test the table entries.
     */
    if (test) {
        if (tsk_verbose)
            tsk_fprintf(stderr,
                "dos_load_prim_table: Testing FAT/NTFS conditions\n");

        if (strncmp("MSDOS", sect->oemname, 5) == 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
            tsk_error_set_errstr
                ("dos_load_prim_table: MSDOS OEM name exists");
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "dos_load_prim_table: MSDOS OEM name exists\n");
            free(sect_buf);
            return 1;
        }
        else if (strncmp("MSWIN", sect->oemname, 5) == 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
            tsk_error_set_errstr
                ("dos_load_prim_table: MSWIN OEM name exists");
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "dos_load_prim_table: MSWIN OEM name exists\n");
            free(sect_buf);
            return 1;
        }
        else if (strncmp("NTFS", sect->oemname, 4) == 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
            tsk_error_set_errstr
                ("dos_load_prim_table: NTFS OEM name exists");
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "dos_load_prim_table: NTFS OEM name exists\n");
            free(sect_buf);
            return 1;
        }
        else if (strncmp("FAT", sect->oemname, 4) == 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
            tsk_error_set_errstr
                ("dos_load_prim_table: FAT OEM name exists");
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "dos_load_prim_table: FAT OEM name exists\n");
            free(sect_buf);
            return 1;
        }
    }

    /* Add an entry of 1 sector for the table  to the internal structure */
    if ((table_str = tsk_malloc(32)) == NULL) {
        free(sect_buf);
        return 1;
    }

    snprintf(table_str, 32, "Primary Table (#0)");
    if (NULL == tsk_vs_part_add(vs, DOS_PART_SOFFSET, (TSK_DADDR_T) 1,
            TSK_VS_PART_FLAG_META, table_str, -1, -1)) {
        free(sect_buf);
        return 1;
    }

    /* Cycle through the partition table */
    for (i = 0; i < 4; i++) {
        dos_part *part = &sect->ptable[i];

        /* We currently ignore CHS */
        uint32_t part_start = tsk_getu32(vs->endian, part->start_sec);
        uint32_t part_size = tsk_getu32(vs->endian, part->size_sec);

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "load_pri:0:%d    Start: %" PRIu32 "   Size: %" PRIu32
                "  Type: %d\n", i, part_start, part_size, part->ptype);

        if (part_size == 0)
            continue;

        // make sure the first couple are in the image bounds
        if ((i < 2) && (part_start > max_addr)) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
            tsk_error_set_errstr
                ("dos_load_prim_table: Starting sector too large for image");
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "Starting sector %" PRIu32 " too large for image\n",
                    part_start);
            free(sect_buf);
            return 1;
        }
#if 0
// I'm not sure if this is too strict ...
        else if ((part_start + part_size) > max_addr) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
            tsk_error_set_errstr
                ("dos_load_prim_table: Partition ends after image");
            return 1;
        }
#endif

        added = 1;

        /* Add the partition to the internal structure
         * If it is an extended partition, process it now */
        if (dos_is_ext(part->ptype)) {
            if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) part_start,
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_META,
                    dos_get_desc(part->ptype), 0, i)) {
                free(sect_buf);
                return 1;
            }

            if (dos_load_ext_table(vs, part_start, part_start, 1)) {
                if (tsk_verbose) {
                    fprintf(stderr,
                        "Error loading extended table, moving on");
                    tsk_error_print(stderr);
                }
                tsk_error_reset();
            }
        }
        else {
            if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) part_start,
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_ALLOC,
                    dos_get_desc(part->ptype), 0, i)) {
                free(sect_buf);
                return 1;
            }
        }
    }
    free(sect_buf);

    if (added == 0) {
        if (tsk_verbose)
            tsk_fprintf(stderr, "dos_load_prim: No valid entries\n");

        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
        tsk_error_set_errstr
            ("dos_load_prim_table: No valid entries in primary table");
        return 1;
    }
    return 0;
}
示例#3
0
/* 
 * Load an extended partition table into the structure in MM_INFO.
 *
 * sect_cur: The sector where the extended table is located
 * sect_ext_base: The sector of the primary extended table (this does
 *   not change for recursive calls)
 * table: a counter that identifies the table depth 
 *   (increases by 1 for each recursive call)
 * 
 * For the primary extended table, sect_cur == sect_ext_base 
 *
 * Return 1 on error and 0 on success
 *
 */
static uint8_t
dos_load_ext_table(MM_INFO * mm, DADDR_T sect_cur, DADDR_T sect_ext_base,
    int table)
{
    dos_sect sect;
    int i;
    char *table_str;
    SSIZE_T cnt;
    DADDR_T max_addr = (mm->img_info->size - mm->offset) / mm->block_size;	// max sector

    if (verbose)
	fprintf(stderr,
	    "dos_load_ext: Table Sector: %" PRIuDADDR
	    ", Primary Base Sector: %" PRIuDADDR "\n", sect_cur,
	    sect_ext_base);

    /* Read the partition table sector */
    cnt = mm_read_block_nobuf
	(mm, (char *) &sect, sizeof(sect), (DADDR_T) sect_cur);
    if (cnt != sizeof(sect)) {
	snprintf(tsk_errstr2, TSK_ERRSTR_L,
	    "Extended DOS table sector %" PRIuDADDR, sect_cur);
	if (cnt != -1) {
	    tsk_errno = TSK_ERR_MM_READ;
	    tsk_errstr[0] = '\0';
	}
	return 1;
    }

    /* Sanity Check */
    if (getu16(mm, sect.magic) != DOS_MAGIC) {
	tsk_errno = TSK_ERR_MM_MAGIC;
	snprintf(tsk_errstr, TSK_ERRSTR_L,
	    "Extended DOS partition table in sector %"
	    PRIuDADDR, sect_cur);
	tsk_errstr2[0] = '\0';
	return 1;
    }

    /* Add an entry of 1 length for the table  to the internal structure */
    if ((table_str = mymalloc(32)) == NULL)
	return 1;

    snprintf(table_str, 32, "Extended Table (#%d)", table);
    if (NULL == mm_part_add(mm, (DADDR_T) sect_cur, (DADDR_T) 1,
	    MM_TYPE_DESC, table_str, table, -1)) {
	return 1;
    }

    /* Cycle through the four partitions in the table 
     *
     * When another extended partition is found, it is processed
     * inside of the loop
     */
    for (i = 0; i < 4; i++) {
	dos_part *part = &sect.ptable[i];

	/* Get the starting sector and size, we currently
	 * ignore CHS */
	uint32_t part_start = getu32(mm, part->start_sec);
	uint32_t part_size = getu32(mm, part->size_sec);

	if (verbose)
	    fprintf(stderr,
		"load_ext: %d:%d    Start: %" PRIu32 "   Size: %"
		PRIu32 "  Type: %d\n", table, i, part_start, part_size,
		part->ptype);

	if (part_size == 0)
	    continue;

	/* partitions are addressed differently 
	 * in extended partitions */
	if (dos_is_ext(part->ptype)) {

	    /* part start is added to the start of the
	     * first extended partition (the primary
	     * extended partition) */

	    if (sect_ext_base + part_start > max_addr) {
		tsk_errno = TSK_ERR_MM_BLK_NUM;
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		    "dos_load_ext_table: Starting sector too large for image");
		tsk_errstr2[0] = '\0';
		return 1;
	    }

	    if (NULL == mm_part_add(mm,
		    (DADDR_T) (sect_ext_base + part_start),
		    (DADDR_T) part_size, MM_TYPE_DESC,
		    dos_get_desc(part->ptype), table, i))
		return 1;


	    /* Process the extended partition */
	    if (dos_load_ext_table(mm, sect_ext_base + part_start,
		    sect_ext_base, table + 1))
		return 1;
	}

	else {
	    /* part_start is added to the start of the 
	     * current partition for the actual
	     * starting location */

	    if (sect_cur + part_start > max_addr) {
		tsk_errno = TSK_ERR_MM_BLK_NUM;
		snprintf(tsk_errstr, TSK_ERRSTR_L,
		    "dos_load_ext_table: Starting sector too large for image");
		tsk_errstr2[0] = '\0';
		return 1;
	    }
	    if (NULL == mm_part_add(mm, (DADDR_T) (sect_cur + part_start),
		    (DADDR_T) part_size, MM_TYPE_VOL,
		    dos_get_desc(part->ptype), table, i))
		return 1;
	}
    }

    return 0;
}
示例#4
0
/*
 * Load an extended partition table into the structure in TSK_VS_INFO.
 *
 * sect_cur: The sector where the extended table is located
 * sect_ext_base: The sector of the primary extended table (this does
 *   not change for recursive calls)
 * table: a counter that identifies the table depth
 *   (increases by 1 for each recursive call)
 *
 * For the primary extended table, sect_cur == sect_ext_base
 *
 * Return 1 on error and 0 on success
 *
 */
static uint8_t
dos_load_ext_table(TSK_VS_INFO * vs, TSK_DADDR_T sect_cur,
    TSK_DADDR_T sect_ext_base, int table)
{
    dos_sect *sect;
    char *sect_buf;
    int i;
    char *table_str;
    ssize_t cnt;
    TSK_DADDR_T max_addr = (vs->img_info->size - vs->offset) / vs->block_size;  // max sector

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "dos_load_ext: Table Sector: %" PRIuDADDR
            ", Primary Base Sector: %" PRIuDADDR "\n", sect_cur,
            sect_ext_base);

    if ((sect_buf = tsk_malloc(vs->block_size)) == NULL)
        return 1;
    sect = (dos_sect *) sect_buf;

    /* Read the partition table sector */
    cnt = tsk_vs_read_block(vs, sect_cur, sect_buf, vs->block_size);
    if (cnt != vs->block_size) {
        if (cnt >= 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_READ);
        }
        tsk_error_set_errstr2("Extended DOS table sector %" PRIuDADDR,
            sect_cur);
        free(sect_buf);
        return 1;
    }

    /* Sanity Check */
    if (tsk_getu16(vs->endian, sect->magic) != DOS_MAGIC) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
        tsk_error_set_errstr("Extended DOS partition table in sector %"
            PRIuDADDR, sect_cur);
        free(sect_buf);
        return 1;
    }

    /* Add an entry of 1 length for the table  to the internal structure */
    if ((table_str = tsk_malloc(32)) == NULL) {
        free(sect_buf);
        return 1;
    }

    snprintf(table_str, 32, "Extended Table (#%d)", table);
    if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) sect_cur,
            (TSK_DADDR_T) 1, TSK_VS_PART_FLAG_META, table_str, table,
            -1)) {
        free(sect_buf);
        return 1;
    }

    /* Cycle through the four partitions in the table
     *
     * When another extended partition is found, it is processed
     * inside of the loop
     */
    for (i = 0; i < 4; i++) {
        dos_part *part = &sect->ptable[i];

        /* Get the starting sector and size, we currently
         * ignore CHS */
        uint32_t part_start = tsk_getu32(vs->endian, part->start_sec);
        uint32_t part_size = tsk_getu32(vs->endian, part->size_sec);

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "load_ext: %d:%d    Start: %" PRIu32 "   Size: %"
                PRIu32 "  Type: %d\n", table, i, part_start, part_size,
                part->ptype);

        if (part_size == 0)
            continue;

        /* partitions are addressed differently
         * in extended partitions */
        if (dos_is_ext(part->ptype)) {

            /* part start is added to the start of the
             * first extended partition (the primary
             * extended partition) */

            if (NULL == tsk_vs_part_add(vs,
                    (TSK_DADDR_T) (sect_ext_base + part_start),
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_META,
                    dos_get_desc(part->ptype), table, i)) {
                free(sect_buf);
                return 1;
            }

            if (sect_ext_base + part_start > max_addr) {
                if (tsk_verbose)
                    tsk_fprintf(stderr,
                        "Starting sector %" PRIuDADDR
                        " of extended partition too large for image\n",
                        sect_ext_base + part_start);
            }
            /* Process the extended partition */
            else if (dos_load_ext_table(vs, sect_ext_base + part_start,
                    sect_ext_base, table + 1)) {
                free(sect_buf);
                return 1;
            }
        }

        else {
            /* part_start is added to the start of the
             * current partition for the actual
             * starting location */

            // we ignore the max_addr checks on extended partitions...

            if (NULL == tsk_vs_part_add(vs,
                    (TSK_DADDR_T) (sect_cur + part_start),
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_ALLOC,
                    dos_get_desc(part->ptype), table, i)) {
                free(sect_buf);
                return 1;
            }
        }
    }

    free(sect_buf);
    return 0;
}