예제 #1
0
파일: apm.c 프로젝트: Jyang772/clamav-devel
static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size_t sectorsize, int old_school)
{
    prtn_intxn_list_t prtncheck;
    struct apm_partition_info apentry;
    unsigned i, pitxn;
    int ret = CL_CLEAN, tmp = CL_CLEAN;
    off_t pos;
    uint32_t max_prtns = 0;

    prtn_intxn_list_init(&prtncheck);

    /* check engine maxpartitions limit */
    if (aptable->numPartitions < ctx->engine->maxpartitions) {
        max_prtns = aptable->numPartitions;
    }
    else {
        max_prtns = ctx->engine->maxpartitions;
    }

    for (i = 1; i <= max_prtns; ++i) {
        /* read partition table entry */
        pos = i * sectorsize;
        if (fmap_readn(*ctx->fmap, &apentry, pos, sizeof(apentry)) != sizeof(apentry)) {
            cli_dbgmsg("cli_scanapm: Invalid Apple partition entry\n");
            prtn_intxn_list_free(&prtncheck);
            return CL_EFORMAT;
        }

        /* convert necessary info big endian to host */
        apentry.pBlockStart = be32_to_host(apentry.pBlockStart);
        apentry.pBlockCount = be32_to_host(apentry.pBlockCount);
        /* re-calculate if old_school and aligned [512 * 4 => 2048] */
        if (old_school && ((i % 4) == 0)) {
            if (!strncmp((char*)apentry.type, "Apple_Driver",       32) ||
                    !strncmp((char*)apentry.type, "Apple_Driver43",     32) ||
                    !strncmp((char*)apentry.type, "Apple_Driver43_CD",  32) ||
                    !strncmp((char*)apentry.type, "Apple_Driver_ATA",   32) ||
                    !strncmp((char*)apentry.type, "Apple_Driver_ATAPI", 32) ||
                    !strncmp((char*)apentry.type, "Apple_Patches",      32)) {

                apentry.pBlockCount = apentry.pBlockCount * 4;;
            }
        }

        tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount);
        if (tmp != CL_CLEAN) {
            if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
                apm_parsemsg("Name: %s\n", (char*)aptable.name);
                apm_parsemsg("Type: %s\n", (char*)aptable.type);

                cli_dbgmsg("cli_scanapm: detected intersection with partitions "
                           "[%u, %u]\n", pitxn, i);
                cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                ret = tmp;
                tmp = 0;
            }
            else if (tmp == CL_VIRUS) {
                apm_parsemsg("Name: %s\n", (char*)aptable.name);
                apm_parsemsg("Type: %s\n", (char*)aptable.type);

                cli_dbgmsg("cli_scanapm: detected intersection with partitions "
                           "[%u, %u]\n", pitxn, i);
                cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                prtn_intxn_list_free(&prtncheck);
                return CL_VIRUS;
            }
            else {
                prtn_intxn_list_free(&prtncheck);
                return tmp;
            }
        }

        pos += sectorsize;
    }

    prtn_intxn_list_free(&prtncheck);
    return ret;
}
예제 #2
0
/* this includes the overall bounds of extended partitions */
static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size_t sectorsize)
{
    prtn_intxn_list_t prtncheck;
    unsigned i = 0, pitxn = 0, prtncount = 0;
    int ret = CL_CLEAN, tmp = CL_CLEAN;

    prtn_intxn_list_init(&prtncheck);

    for (i = 0; i < MBR_MAX_PARTITION_ENTRIES && prtncount < ctx->engine->maxpartitions; ++i) {
        if (mbr.entries[i].type == MBR_EMPTY) {
            /* empty partiton entry */
            prtncount++;
        }
        else {
            tmp = prtn_intxn_list_check(&prtncheck, &pitxn, mbr.entries[i].firstLBA,
                                        mbr.entries[i].numLBA);
            if (tmp != CL_CLEAN) {
                if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
                    cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
                               "[%u, %u]\n", pitxn, i);
                    cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                    ret = tmp;
                    tmp = 0;
                }
                else if (tmp == CL_VIRUS) {
                    cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
                               "[%u, %u]\n", pitxn, i);
                    cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                    prtn_intxn_list_free(&prtncheck);
                    return CL_VIRUS;
                }
                else {
                    prtn_intxn_list_free(&prtncheck);
                    return tmp;
                }
            }

            if (mbr.entries[i].type == MBR_EXTENDED) {
                /* check the logical partitions */
                tmp = mbr_extended_prtn_intxn(ctx, &prtncount, 
                                  mbr.entries[i].firstLBA, sectorsize);
                if (tmp != CL_CLEAN) {
                    if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
                        ret = tmp;
                        tmp = 0;
                    }
                    else if (tmp == CL_VIRUS) {
                        prtn_intxn_list_free(&prtncheck);
                        return CL_VIRUS;
                    }
                    else {
                        prtn_intxn_list_free(&prtncheck);
                        return tmp;
                    }
                }
            }
            else {
                prtncount++;
            }
        }
    }

    prtn_intxn_list_free(&prtncheck);
    return ret;
}
예제 #3
0
/* checks internal logical partitions */
static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extlba, size_t sectorsize)
{
    struct mbr_boot_record ebr;
    prtn_intxn_list_t prtncheck;
    unsigned i, pitxn;
    int ret = CL_CLEAN, tmp = CL_CLEAN, mbr_base = 0;
    off_t pos = 0, logiclba = 0;

    mbr_base = sectorsize - sizeof(struct mbr_boot_record);

    prtn_intxn_list_init(&prtncheck);

    logiclba = 0; i = 0;
    do {
        pos = extlba * sectorsize; /* start of extended partition */

        /* read the extended boot record */
        pos += (logiclba * sectorsize) + mbr_base;
        if (fmap_readn(*ctx->fmap, &ebr, pos, sizeof(ebr)) != sizeof(ebr)) {
            cli_dbgmsg("cli_scanebr: Invalid extended boot record\n");
            prtn_intxn_list_free(&prtncheck);
            return CL_EFORMAT;
        }

        /* convert the little endian to host */
        mbr_convert_to_host(&ebr);

        /* update state */
        (*prtncount)++;

        /* assume that logical record is first and extended is second */
        tmp = prtn_intxn_list_check(&prtncheck, &pitxn, logiclba, ebr.entries[0].numLBA);
        if (tmp != CL_CLEAN) {
            if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
                cli_dbgmsg("cli_scanebr: detected intersection with partitions "
                           "[%u, %u]\n", pitxn, i);
                cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                ret = tmp;
                tmp = 0;
            }
            else if (tmp == CL_VIRUS) {
                cli_dbgmsg("cli_scanebr: detected intersection with partitions "
                           "[%u, %u]\n", pitxn, i);
                cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                prtn_intxn_list_free(&prtncheck);
                return CL_VIRUS;
            }
            else {
                prtn_intxn_list_free(&prtncheck);
                return tmp;
            }
        }

        /* assume extended is second entry */
        if (ebr.entries[1].type != MBR_EXTENDED) {
            cli_dbgmsg("cli_scanebr: second entry for EBR is not an extended partition\n");
            break;
        }

        logiclba = ebr.entries[1].firstLBA;

        ++i;
    } while (logiclba != 0 && (*prtncount) < ctx->engine->maxpartitions);

    prtn_intxn_list_free(&prtncheck);    
    return ret;
}
예제 #4
0
파일: gpt.c 프로젝트: vrtadmin/clamav-devel
static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize)
{
    prtn_intxn_list_t prtncheck;
    struct gpt_partition_entry gpe;
    unsigned i, pitxn;
    int ret = CL_CLEAN, tmp = CL_CLEAN;
    off_t pos;
    size_t maplen;
    uint32_t max_prtns = 0;
    int virus_found = 0;

    maplen = (*ctx->fmap)->real_len;

    /* convert endian to host to check partition table */
    hdr.tableStartLBA = le64_to_host(hdr.tableStartLBA);
    hdr.tableNumEntries = le32_to_host(hdr.tableNumEntries);

    prtn_intxn_list_init(&prtncheck);    

    /* check engine maxpartitions limit */
    if (hdr.tableNumEntries < ctx->engine->maxpartitions) {
        max_prtns = hdr.tableNumEntries;
    }
    else {
        max_prtns = ctx->engine->maxpartitions;
    }

    pos = hdr.tableStartLBA * sectorsize;
    for (i = 0; i < max_prtns; ++i) {
        /* read in partition entry */
        if (fmap_readn(*ctx->fmap, &gpe, pos, sizeof(gpe)) != sizeof(gpe)) {
            cli_dbgmsg("cli_scangpt: Invalid GPT partition entry\n");
            prtn_intxn_list_free(&prtncheck);
            return CL_EFORMAT;
        }

        /* convert the endian to host */
        gpe.firstLBA = le64_to_host(gpe.firstLBA);
        gpe.lastLBA = le64_to_host(gpe.lastLBA);

        if (gpe.firstLBA == 0) {
            /* empty partition, invalid */
        }
        else if ((gpe.firstLBA > gpe.lastLBA) ||
                 (gpe.firstLBA < hdr.firstUsableLBA) || (gpe.lastLBA > hdr.lastUsableLBA)) {
            /* partition exists outside bounds specified by header or invalid */
        }
        else if (((gpe.lastLBA+1) * sectorsize) > maplen) {
            /* partition exists outside bounds of the file map */
        }
        else {
            tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1);
            if (tmp != CL_CLEAN) {
                if (tmp == CL_VIRUS) {
                    cli_dbgmsg("cli_scangpt: detected intersection with partitions "
                               "[%u, %u]\n", pitxn, i);
                    ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                    if (ret == CL_VIRUS)
                        virus_found = 1;
                    if (SCAN_ALLMATCHES || ret == CL_CLEAN)
                        tmp = 0;
                    else
                        goto leave;
                } else {
                    ret = tmp;
                    goto leave;
                }
            }
        }

        /* increment the offsets to next partition entry */
        pos += hdr.tableEntrySize;
    }

 leave:
    prtn_intxn_list_free(&prtncheck);
    if (virus_found)
        return CL_VIRUS;
    return ret;
}