|
|
|
@ -82,237 +82,6 @@ static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
|
|
|
int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *signo); |
|
|
|
|
int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo); |
|
|
|
|
|
|
|
|
|
/* TODO: clean up the code */ |
|
|
|
|
|
|
|
|
|
static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, int sigid, int parts, int partno, unsigned short type, unsigned int mindist, unsigned int maxdist, const char *offset, unsigned short target) |
|
|
|
|
{ |
|
|
|
|
struct cli_ac_patt *new; |
|
|
|
|
char *pt, *hex = NULL; |
|
|
|
|
int virlen, ret, error = 0; |
|
|
|
|
unsigned int i, j, wprefix = 0; |
|
|
|
|
|
|
|
|
|
#define FREE_ALT \ |
|
|
|
|
if(new->alt) { \
|
|
|
|
|
free(new->altn); \
|
|
|
|
|
for(i = 0; i < new->alt; i++) \
|
|
|
|
|
free(new->altc[i]); \
|
|
|
|
|
free(new->altc); \
|
|
|
|
|
free(hex); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(strlen(hexsig) / 2 < AC_DEFAULT_DEPTH) |
|
|
|
|
return CL_EPATSHORT; |
|
|
|
|
|
|
|
|
|
if((new = (struct cli_ac_patt *) cli_calloc(1, sizeof(struct cli_ac_patt))) == NULL) |
|
|
|
|
return CL_EMEM; |
|
|
|
|
|
|
|
|
|
new->type = type; |
|
|
|
|
new->sigid = sigid; |
|
|
|
|
new->parts = parts; |
|
|
|
|
new->partno = partno; |
|
|
|
|
new->mindist = mindist; |
|
|
|
|
new->maxdist = maxdist; |
|
|
|
|
new->target = target; |
|
|
|
|
if(offset) { |
|
|
|
|
new->offset = cli_strdup(offset); |
|
|
|
|
if(!new->offset) |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(strchr(hexsig, '(')) { |
|
|
|
|
char *hexcpy, *hexnew, *start, *h, *c; |
|
|
|
|
|
|
|
|
|
if(!(hexcpy = cli_strdup(hexsig))) { |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!(hexnew = (char *) cli_calloc(strlen(hexsig) + 1, 1))) { |
|
|
|
|
free(hexcpy); |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
start = pt = hexcpy; |
|
|
|
|
while((pt = strchr(start, '('))) { |
|
|
|
|
*pt++ = 0; |
|
|
|
|
|
|
|
|
|
if(!start) { |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
strcat(hexnew, start); |
|
|
|
|
strcat(hexnew, "@@"); |
|
|
|
|
|
|
|
|
|
if(!(start = strchr(pt, ')'))) { |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
*start++ = 0; |
|
|
|
|
|
|
|
|
|
new->alt++; |
|
|
|
|
new->altn = (unsigned short int *) cli_realloc(new->altn, new->alt * sizeof(unsigned short int)); |
|
|
|
|
new->altn[new->alt - 1] = 0; |
|
|
|
|
new->altc = (unsigned char **) cli_realloc(new->altc, new->alt * sizeof(char *)); |
|
|
|
|
new->altc[new->alt - 1] = NULL; |
|
|
|
|
|
|
|
|
|
for(i = 0; i < strlen(pt); i++) |
|
|
|
|
if(pt[i] == '|') |
|
|
|
|
new->altn[new->alt - 1]++; |
|
|
|
|
|
|
|
|
|
if(!new->altn[new->alt - 1]) { |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} else |
|
|
|
|
new->altn[new->alt - 1]++; |
|
|
|
|
|
|
|
|
|
if(!(new->altc[new->alt - 1] = (unsigned char *) cli_calloc(new->altn[new->alt - 1], 1))) { |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for(i = 0; i < new->altn[new->alt - 1]; i++) { |
|
|
|
|
if((h = cli_strtok(pt, i, "|")) == NULL) { |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if((c = cli_hex2str(h)) == NULL) { |
|
|
|
|
free(h); |
|
|
|
|
error = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new->altc[new->alt - 1][i] = *c; |
|
|
|
|
free(c); |
|
|
|
|
free(h); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(error) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(start) |
|
|
|
|
strcat(hexnew, start); |
|
|
|
|
|
|
|
|
|
hex = hexnew; |
|
|
|
|
free(hexcpy); |
|
|
|
|
|
|
|
|
|
if(error) { |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMALFDB; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if((new->pattern = cli_hex2ui(new->alt ? hex : hexsig)) == NULL) { |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMALFDB; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new->length = strlen(new->alt ? hex : hexsig) / 2; |
|
|
|
|
|
|
|
|
|
for(i = 0; i < AC_DEFAULT_DEPTH; i++) { |
|
|
|
|
if(new->pattern[i] & CLI_MATCH_WILDCARD) { |
|
|
|
|
wprefix = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(wprefix) { |
|
|
|
|
for(; i < (uint16_t) (new->length - AC_DEFAULT_DEPTH + 1); i++) { |
|
|
|
|
wprefix = 0; |
|
|
|
|
for(j = i; j < i + AC_DEFAULT_DEPTH; j++) { |
|
|
|
|
if(new->pattern[j] & CLI_MATCH_WILDCARD) { |
|
|
|
|
wprefix = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(!wprefix) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(wprefix) { |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new->pattern); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMALFDB; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new->prefix = new->pattern; |
|
|
|
|
new->prefix_length = i; |
|
|
|
|
new->pattern = &new->prefix[i]; |
|
|
|
|
new->length -= i; |
|
|
|
|
|
|
|
|
|
for(i = 0; i < new->prefix_length; i++) |
|
|
|
|
if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE) |
|
|
|
|
new->alt_pattern++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(new->length > root->maxpatlen) |
|
|
|
|
root->maxpatlen = new->length; |
|
|
|
|
|
|
|
|
|
if((pt = strstr(virname, "(Clam)"))) |
|
|
|
|
virlen = strlen(virname) - strlen(pt) - 1; |
|
|
|
|
else |
|
|
|
|
virlen = strlen(virname); |
|
|
|
|
|
|
|
|
|
if(virlen <= 0) { |
|
|
|
|
if(new->prefix) |
|
|
|
|
free(new->prefix); |
|
|
|
|
else |
|
|
|
|
free(new->pattern); |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMALFDB; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if((new->virname = cli_calloc(virlen + 1, sizeof(char))) == NULL) { |
|
|
|
|
if(new->prefix) |
|
|
|
|
free(new->prefix); |
|
|
|
|
else |
|
|
|
|
free(new->pattern); |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
strncpy(new->virname, virname, virlen); |
|
|
|
|
|
|
|
|
|
if((ret = cli_ac_addpatt(root, new))) { |
|
|
|
|
if(new->prefix) |
|
|
|
|
free(new->prefix); |
|
|
|
|
else |
|
|
|
|
free(new->pattern); |
|
|
|
|
free(new->virname); |
|
|
|
|
FREE_ALT; |
|
|
|
|
if(new->offset) |
|
|
|
|
free(new->offset); |
|
|
|
|
free(new); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(new->alt) |
|
|
|
|
free(hex); |
|
|
|
|
|
|
|
|
|
return CL_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, unsigned short type, const char *offset, unsigned short target) |
|
|
|
|
{ |
|
|
|
@ -570,11 +339,10 @@ static int cli_initroots(struct cl_engine *engine, unsigned int options) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cli_dbgmsg("Initialising AC pattern matcher of root[%d]\n", i); |
|
|
|
|
root->ac_root = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); |
|
|
|
|
if(!root->ac_root) { |
|
|
|
|
if((ret = cli_ac_init(root, AC_DEFAULT_MIN_DEPTH, AC_DEFAULT_MAX_DEPTH))) { |
|
|
|
|
/* no need to free previously allocated memory here */ |
|
|
|
|
cli_errmsg("Can't initialise AC pattern matcher\n"); |
|
|
|
|
return CL_EMEM; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!root->ac_only) { |
|
|
|
|