bb4007 - adding pcre byte sequence comparison functions

pull/51/head
Mickey Sola 7 years ago committed by Micah Snyder
parent ecbdd3864f
commit 9e408e7658
  1. 109
      libclamav/matcher-pcre.c
  2. 2
      libclamav/matcher-pcre.h
  3. 4
      libclamav/str.c
  4. 4
      libclamav/str.h

@ -37,6 +37,7 @@
#include "mpool.h"
#include "readdb.h"
#include "regex_pcre.h"
#include "str.h"
#if HAVE_PCRE
#if USING_PCRE2
@ -325,7 +326,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *
case 'g': pm->flags |= CLI_PCRE_GLOBAL; break;
case 'r': pm->flags |= CLI_PCRE_ROLLING; break;
case 'e': pm->flags |= CLI_PCRE_ENCOMPASS; break;
case 'z': if(CL_SUCCESS == cli_pcre_addbytecomp(&opt, &pm->bcmp_data)) {
case 'z': if(CL_SUCCESS == cli_pcre_bcmp_add_opts(&opt, &pm->bcmp_data)) {
pm->flags |= CLI_PCRE_BCOMP;
break;
}
@ -409,7 +410,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *
return CL_SUCCESS;
}
int cli_pcre_addbytecomp (const char **opt, struct cli_pcre_bcomp *bcomp) {
int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp) {
if (!opt || !(*opt) || !bcomp)
return CL_ENULLARG;
@ -889,6 +890,14 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
/* move off to the end of the match for next match; offset is relative to adjbuffer
* NOTE: misses matches starting within the last match; TODO: start from start of last match? */
offset = p_res.match[1];
if(pm->flags & CLI_PCRE_BCOMP) {
ret = cli_pcre_bcmp_compare_check(buffer, length, offset, pm);
if (ret != CL_SUCCESS) {
break;
}
}
} while (global && rc > 0 && offset < adjlength);
/* handle error code */
@ -899,11 +908,6 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
if (ret != CL_SUCCESS)
break;
}
/* hijack pcre matches for byte comparison
if (pm.comp) {
pm_dbgmsg("cli_pcre_scanbuf: assigning lsigcnt[%d][%d], located @ %d\n",
}*/
/* free match results */
cli_pcre_results_free(&p_res);
@ -913,6 +917,97 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
return ret;
}
int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm)
{
if (!buffer || !pm) {
return CL_ENULLARG;
}
const uint32_t byte_len = pm->bcmp_data.byte_len;
unsigned char* conversion_buf[byte_len+1];
char opt = (char) pm->bcmp_data.options;
uint32_t value = 0;
const unsigned char* end_buf = NULL;
if (!(pm->flags & CLI_PCRE_BCOMP) || !(offset + pm->bcmp_data.offset + pm->bcmp_data.byte_len < length)) {
return CL_SUCCESS;
}
offset += pm->bcmp_data.offset;
memcpy(conversion_buf, buffer+offset, byte_len);
conversion_buf[byte_len] = '\0';
switch(opt) {
/*hb*/
case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_LE:
value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16);
if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
return CL_SUCCESS;
}
value = le32_to_host(value);
break;
/*hl*/
case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_BE:
value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16);
if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
return CL_SUCCESS;
}
value = be32_to_host(value);
break;
/*dl*/
case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_LE:
value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10);
if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
return CL_SUCCESS;
}
value = le32_to_host(value);
break;
/*db*/
case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_BE:
value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10);
if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) {
return CL_SUCCESS;
}
value = be32_to_host(value);
break;
default:
return CL_ENULLARG;
}
switch (pm->bcmp_data.comp_symbol) {
case '>':
if (value > pm->bcmp_data.comp_value) {
return CL_VIRUS;
}
case '<':
if (value < pm->bcmp_data.comp_value) {
return CL_VIRUS;
}
case '=':
if (value == pm->bcmp_data.comp_value) {
return CL_VIRUS;
}
default:
return CL_ENULLARG;
}
return CL_SUCCESS;
}
void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm)
{
if (!pm)

@ -96,6 +96,8 @@ void cli_pcre_freeoff(struct cli_pcre_off *data);
int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **virname, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, const struct cli_pcre_off *data, cli_ctx *ctx);
void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm);
void cli_pcre_freetable(struct cli_matcher *root);
int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm);
int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp);
#else
/* NO-PCRE DECLARATIONS - defined because encasing everything in '#if' is a pain and because dynamic library mappings are weird */
#define PCRE_BYPASS ""

@ -539,7 +539,7 @@ size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count,
* between 2 and 36 inclusive, or be the special value 0.
* @return long The signed long value.
*/
static long cli_strntol(const char* nptr, size_t n, char** endptr, register int base)
long cli_strntol(const char* nptr, size_t n, char** endptr, register int base)
{
register const char* s = nptr;
register unsigned long acc = 0;
@ -662,7 +662,7 @@ done:
* between 2 and 36 inclusive, or be the special value 0.
* @return unsigned long The unsigned long value.
*/
static unsigned long
unsigned long
cli_strntoul(const char* nptr, size_t n, char** endptr, register int base)
{
register const char* s = nptr;

@ -73,7 +73,9 @@ const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle
char *cli_strrcpy(char *dest, const char *source);
size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens);
size_t cli_ldbtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens, int token_skip);
cl_error_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result);
long cli_strntol(const char* nptr, size_t n, char** endptr, register int base);
unsigned long cli_strntoul(const char* nptr, size_t n, char** endptr, register int base);
cl_errot_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result);
cl_error_t cli_strntoul_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, unsigned long *result);
int cli_isnumber(const char *str);
char *cli_unescape(const char *str);

Loading…
Cancel
Save