예제 #1
0
void cli_pcre_perf_print()
{
    struct sigperf_elem stats[MAX_TRACKED_PCRE], *elem = stats;
    int i, elems = 0, max_name_len = 0, name_len;

    if (!p_sigid || !p_sigevents) {
        cli_warnmsg("cli_pcre_perf_print: statistics requested but no PCREs were loaded!\n");
        return;
    }

    memset(stats, 0, sizeof(stats));
    for (i=0;i<MAX_TRACKED_PCRE;i++) {
        union ev_val val;
        uint32_t count;
        const char * name = cli_event_get_name(p_sigevents, i*PCRE_EVENTS_PER_SIG);
        cli_event_get(p_sigevents, i*PCRE_EVENTS_PER_SIG, &val, &count);
        if (!count) {
            if (name)
                cli_dbgmsg("No event triggered for %s\n", name);
            continue;
        }
        if (name)
            name_len = strlen(name);
        else
            name_len = 0;
        if (name_len > max_name_len)
            max_name_len = name_len;
        elem->name = name?name:"\"noname\"";
        elem->usecs = val.v_int;
        elem->run_count = count;
        cli_event_get(p_sigevents, i*PCRE_EVENTS_PER_SIG+1, &val, &count);
        elem->match_count = count;
        elem++;
        elems++;
    }
    if (max_name_len < strlen("PCRE Expression"))
        max_name_len = strlen("PCRE Expression");

    cli_qsort(stats, elems, sizeof(struct sigperf_elem), sigelem_comp);

    elem = stats;
    /* name runs matches microsecs avg */
    cli_infomsg (NULL, "%-*s %*s %*s %*s %*s\n", max_name_len, "PCRE Expression",
                 8, "#runs", 8, "#matches", 12, "usecs total", 9, "usecs avg");
    cli_infomsg (NULL, "%-*s %*s %*s %*s %*s\n", max_name_len, "===============",
                 8, "=====", 8, "========", 12, "===========", 9, "=========");
    while (elem->run_count) {
        cli_infomsg (NULL, "%-*s %*lu %*lu %*llu %*.2f\n", max_name_len, elem->name,
                     8, elem->run_count, 8, elem->match_count,
                     12, (long long unsigned)elem->usecs, 9, (double)elem->usecs/elem->run_count);
        elem++;
    }
}
예제 #2
0
int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, const struct cli_target_info *info)
{
	int ret;
	unsigned int i;
	struct cli_bm_patt *patt;


    if(!root->bm_patterns) {
	data->offtab = data->offset = NULL;
	data->cnt = data->pos = 0;
	return CL_SUCCESS;
    }

    data->cnt = data->pos = 0;
    data->offtab = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t));
    if(!data->offtab) {
	cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offtab\n");
	return CL_EMEM;
    }
    data->offset = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t));
    if(!data->offset) {
	cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offset\n");
	free(data->offtab);
	return CL_EMEM;
    }
    for(i = 0; i < root->bm_patterns; i++) {
	patt = root->bm_pattab[i];
	if(patt->offdata[0] == CLI_OFF_ABSOLUTE) {
	    data->offtab[data->cnt] = patt->offset_min + patt->prefix_length;
	    if(data->offtab[data->cnt] >= info->fsize)
		continue;
	    data->cnt++;
	} else if((ret = cli_caloff(NULL, info, root->type, patt->offdata, &data->offset[patt->offset_min], NULL))) {
	    cli_errmsg("cli_bm_initoff: Can't calculate relative offset in signature for %s\n", patt->virname);
	    free(data->offtab);
	    free(data->offset);
	    return ret;
	} else if((data->offset[patt->offset_min] != CLI_OFF_NONE) && (data->offset[patt->offset_min] + patt->length <= info->fsize)) {
	    if(!data->cnt || (data->offset[patt->offset_min] + patt->prefix_length != data->offtab[data->cnt - 1])) {
		data->offtab[data->cnt] = data->offset[patt->offset_min] + patt->prefix_length;
		if(data->offtab[data->cnt] >= info->fsize)
		    continue;
		data->cnt++;
	    }
	}
    }

    cli_qsort(data->offtab, data->cnt, sizeof(uint32_t), NULL);
    return CL_SUCCESS;
}
예제 #3
0
파일: dmg.c 프로젝트: sikopet/clamav-devel
/* Given mish data, reconstruct the partition details */
static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
                           uint64_t xmlOffset, struct dmg_mish_with_stripes *mish_set)
{
    struct dmg_block_data *blocklist = mish_set->stripes;
    uint64_t totalSectors = 0;
    uint32_t i;
    unsigned long projected_size;
    int ret = CL_CLEAN, ofd;
    uint8_t sorted = 1, writeable_data = 0;
    char outfile[NAME_MAX + 1];

    /* First loop, fix endian-ness and check if already sorted */
    for (i = 0; i < mish_set->mish->blockDataCount; i++) {
        blocklist[i].type = be32_to_host(blocklist[i].type);
        // blocklist[i].reserved = be32_to_host(blocklist[i].reserved);
        blocklist[i].startSector = be64_to_host(blocklist[i].startSector);
        blocklist[i].sectorCount = be64_to_host(blocklist[i].sectorCount);
        blocklist[i].dataOffset = be64_to_host(blocklist[i].dataOffset);
        blocklist[i].dataLength = be64_to_host(blocklist[i].dataLength);
        cli_dbgmsg("mish %u stripe " STDu32 " type " STDx32 " start " STDu64
                   " count " STDu64 " source " STDu64 " length " STDu64 "\n",
                   mishblocknum, i, blocklist[i].type, blocklist[i].startSector, blocklist[i].sectorCount,
                   blocklist[i].dataOffset, blocklist[i].dataLength);
        if ((blocklist[i].dataOffset > xmlOffset) ||
                (blocklist[i].dataOffset + blocklist[i].dataLength > xmlOffset)) {
            cli_dbgmsg("dmg_handle_mish: invalid stripe offset and/or length\n");
            return CL_EFORMAT;
        }
        if ((i > 0) && sorted && (blocklist[i].startSector < blocklist[i-1].startSector)) {
            cli_dbgmsg("dmg_handle_mish: stripes not in order, will have to sort\n");
            sorted = 0;
        }
        if (dmg_track_sectors(&totalSectors, &writeable_data, i, blocklist[i].type, blocklist[i].sectorCount)) {
            /* reason was logged from dmg_track_sector_count */
            return CL_EFORMAT;
        }
    }

    if (!sorted) {
        cli_qsort(blocklist, mish_set->mish->blockDataCount, sizeof(struct dmg_block_data), cmp_mish_stripes);
    }
    cli_dbgmsg("dmg_handle_mish: stripes in order!\n");

    /* Size checks */
    if ((writeable_data == 0) || (totalSectors == 0)) {
        cli_dbgmsg("dmg_handle_mish: no data to output\n");
        return CL_CLEAN;
    }
    else if (totalSectors > (ULONG_MAX / DMG_SECTOR_SIZE)) {
        /* cli_checklimits only takes unsigned long for now */
        cli_warnmsg("dmg_handle_mish: mish block %u too big to handle (for now)", mishblocknum);
        return CL_CLEAN;
    }
    projected_size = (unsigned long)(totalSectors * DMG_SECTOR_SIZE);
    ret = cli_checklimits("cli_scandmg", ctx, projected_size, 0, 0);
    if (ret != CL_CLEAN) {
        /* limits exceeded */
        cli_dbgmsg("dmg_handle_mish: skipping block %u, limits exceeded\n", mishblocknum);
        return ret;
    }

    /* Prepare for file */
    snprintf(outfile, sizeof(outfile)-1, "%s"PATHSEP"dmg%02u", dir, mishblocknum);
    outfile[sizeof(outfile)-1] = '\0';
    ofd = open(outfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
    if (ofd < 0) {
        char err[128];
        cli_errmsg("cli_scandmg: Can't create temporary file %s: %s\n",
                   outfile, cli_strerror(errno, err, sizeof(err)));
        return CL_ETMPFILE;
    }
    cli_dbgmsg("dmg_handle_mish: extracting block %u to %s\n", mishblocknum, outfile);

    /* Push data, stripe by stripe */
    for(i=0; i < mish_set->mish->blockDataCount && ret == CL_CLEAN; i++) {
        switch (blocklist[i].type) {
        case DMG_STRIPE_EMPTY:
        case DMG_STRIPE_ZEROES:
            ret = dmg_stripe_zeroes(ctx, ofd, i, mish_set);
            break;
        case DMG_STRIPE_STORED:
            ret = dmg_stripe_store(ctx, ofd, i, mish_set);
            break;
        case DMG_STRIPE_ADC:
            ret = dmg_stripe_adc(ctx, ofd, i, mish_set);
            break;
        case DMG_STRIPE_DEFLATE:
            ret = dmg_stripe_inflate(ctx, ofd, i, mish_set);
            break;
        case DMG_STRIPE_BZ:
            ret = dmg_stripe_bzip(ctx, ofd, i, mish_set);
            break;
        case DMG_STRIPE_SKIP:
        case DMG_STRIPE_END:
        default:
            cli_dbgmsg("dmg_handle_mish: stripe " STDu32 ", skipped\n", i);
            break;
        }
    }

    /* If okay so far, scan rebuilt partition */
    if (ret == CL_CLEAN) {
        ret = cli_partition_scandesc(ofd, ctx);
    }

    close(ofd);
    if (!ctx->engine->keeptmp)
        if (cli_unlink(outfile)) return CL_EUNLINK;

    return ret;
}