378
* In parse_only mode this function returns -1 on error or the max subsig id
380
int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigned int *cnt, uint64_t *ids, unsigned int parse_only)
382
unsigned int i, len = end - expr, pth = 0, opoff = 0, op1off = 0, val;
383
unsigned int blkend = 0, id, modval1, modval2 = 0, lcnt = 0, rcnt = 0, tcnt, modoff = 0;
384
uint64_t lids = 0, rids = 0, tids;
386
char op = 0, op1 = 0, mod = 0, blkmod = 0;
387
const char *lstart = expr, *lend = NULL, *rstart = NULL, *rend = end, *pt;
390
for(i = 0; i < len; i++) {
398
cli_errmsg("cli_ac_chklsig: Syntax error: Missing opening parenthesis\n");
411
if(strchr("&|", expr[i])) {
415
} else if(pth == 1) {
427
if(expr[i + 1] == '>' || expr[i + 1] == '<' || expr[i + 1] == '=') {
428
blkmod = expr[i + 1];
429
ret = sscanf(&expr[i + 2], "%u,%u", &modval1, &modval2);
431
ret = sscanf(&expr[i + 2], "%u", &modval1);
432
if(!ret || ret == EOF) {
433
cli_errmsg("chklexpr: Syntax error: Missing number after '%c'\n", expr[i + 1]);
436
for(i += 2; i + 1 < len && (isdigit(expr[i + 1]) || expr[i + 1] == ','); i++);
439
if(&expr[i + 1] == rend)
447
cli_errmsg("cli_ac_chklsig: Syntax error: Missing closing parenthesis\n");
453
return cli_ac_chklsig(++expr, --end, lsigcnt, cnt, ids, parse_only);
455
ret = sscanf(expr, "%u", &id);
456
if(!ret || ret == EOF) {
457
cli_errmsg("cli_ac_chklsig: Can't parse %s\n", expr);
467
pt = strchr(expr, mod) + modoff;
468
ret = sscanf(pt, "%u", &modval1);
469
if(!ret || ret == EOF) {
470
cli_errmsg("chklexpr: Syntax error: Missing number after '%c'\n", mod);
491
*ids |= (uint64_t) 1 << id;
501
*ids |= (uint64_t) 1 << id;
513
rend = &expr[blkend];
517
cli_errmsg("cli_ac_chklsig: Syntax error: Missing left argument\n");
521
if(opoff + 1 == len) {
522
cli_errmsg("cli_ac_chklsig: Syntax error: Missing right argument\n");
525
rstart = &expr[opoff + 1];
527
lval = cli_ac_chklsig(lstart, lend, lsigcnt, &lcnt, &lids, parse_only);
529
cli_errmsg("cli_ac_chklsig: Calculation of lval failed\n");
533
rval = cli_ac_chklsig(rstart, rend, lsigcnt, &rcnt, &rids, parse_only);
535
cli_errmsg("cli_ac_chklsig: Calculation of rval failed\n");
543
return MAX(lval, rval);
545
cli_errmsg("cli_ac_chklsig: Incorrect operator type\n");
557
cli_errmsg("cli_ac_chklsig: Incorrect operator type\n");
596
val += tids & (uint64_t) 1;
376
609
* FIXME: the current support for string alternatives uses a brute-force
377
610
* approach and doesn't perform any kind of verification and
511
746
data->partsigs = partsigs;
516
data->offmatrix = (int32_t ***) cli_calloc(partsigs, sizeof(int32_t **));
517
if(!data->offmatrix) {
518
cli_errmsg("cli_ac_init: Can't allocate memory for data->offmatrix\n");
749
data->offmatrix = (int32_t ***) cli_calloc(partsigs, sizeof(int32_t **));
750
if(!data->offmatrix) {
751
cli_errmsg("cli_ac_init: Can't allocate memory for data->offmatrix\n");
758
data->lsigcnt = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
761
free(data->offmatrix);
762
cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigcnt\n");
765
data->lsigcnt[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
766
if(!data->lsigcnt[0]) {
769
free(data->offmatrix);
770
cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigcnt[0]\n");
773
for(i = 1; i < lsigs; i++)
774
data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
522
777
return CL_SUCCESS;
570
832
return CL_SUCCESS;
573
int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx)
835
int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx)
575
837
struct cli_ac_node *current;
576
838
struct cli_ac_patt *patt, *pt;
762
1078
/* FIXME: clean up the code */
763
int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, uint8_t target)
1079
int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, const uint32_t *lsigid, unsigned int options)
765
1081
struct cli_ac_patt *new;
766
1082
char *pt, *pt2, *hex = NULL, *hexcpy = NULL;
767
1083
uint16_t i, j, ppos = 0, pend, *dec;
768
uint8_t wprefix = 0, zprefix = 1, namelen, plen = 0;
1084
uint8_t wprefix = 0, zprefix = 1, plen = 0;
769
1085
struct cli_ac_alt *newalt, *altpt, **newtable;
770
1086
int ret, error = CL_SUCCESS;
1090
cli_errmsg("cli_ac_addsig: root == NULL\n");
773
1094
if(strlen(hexsig) / 2 < root->ac_mindepth)
774
1095
return CL_EPATSHORT;
1059
1384
if(new->length > root->maxpatlen)
1060
1385
root->maxpatlen = new->length;
1062
if((pt = strstr(virname, " (Clam)")))
1063
namelen = strlen(virname) - strlen(pt);
1065
namelen = strlen(virname);
1068
cli_errmsg("cli_ac_addsig: No virus name\n");
1069
new->prefix ? free(new->prefix) : free(new->pattern);
1075
if((new->virname = cli_calloc(namelen + 1, sizeof(char))) == NULL) {
1387
new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0);
1076
1389
new->prefix ? free(new->prefix) : free(new->pattern);
1077
1390
ac_free_alt(new);
1079
1392
return CL_EMEM;
1081
strncpy(new->virname, virname, namelen);
1082
new->virname[namelen]='\0';
1396
root->ac_lsigtable[new->lsigid[1]]->virname = new->virname;
1085
1399
new->offset = cli_strdup(offset);