... | ... |
@@ -37,6 +37,7 @@ |
37 | 37 |
#include "mpool.h" |
38 | 38 |
#include "readdb.h" |
39 | 39 |
#include "regex_pcre.h" |
40 |
+#include "str.h" |
|
40 | 41 |
|
41 | 42 |
#if HAVE_PCRE |
42 | 43 |
#if USING_PCRE2 |
... | ... |
@@ -325,7 +326,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char * |
325 | 325 |
case 'g': pm->flags |= CLI_PCRE_GLOBAL; break; |
326 | 326 |
case 'r': pm->flags |= CLI_PCRE_ROLLING; break; |
327 | 327 |
case 'e': pm->flags |= CLI_PCRE_ENCOMPASS; break; |
328 |
- case 'z': if(CL_SUCCESS == cli_pcre_addbytecomp(&opt, &pm->bcmp_data)) { |
|
328 |
+ case 'z': if(CL_SUCCESS == cli_pcre_bcmp_add_opts(&opt, &pm->bcmp_data)) { |
|
329 | 329 |
pm->flags |= CLI_PCRE_BCOMP; |
330 | 330 |
break; |
331 | 331 |
} |
... | ... |
@@ -409,7 +410,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char * |
409 | 409 |
return CL_SUCCESS; |
410 | 410 |
} |
411 | 411 |
|
412 |
-int cli_pcre_addbytecomp (const char **opt, struct cli_pcre_bcomp *bcomp) { |
|
412 |
+int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp) { |
|
413 | 413 |
|
414 | 414 |
if (!opt || !(*opt) || !bcomp) |
415 | 415 |
return CL_ENULLARG; |
... | ... |
@@ -889,6 +890,14 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char ** |
889 | 889 |
/* move off to the end of the match for next match; offset is relative to adjbuffer |
890 | 890 |
* NOTE: misses matches starting within the last match; TODO: start from start of last match? */ |
891 | 891 |
offset = p_res.match[1]; |
892 |
+ |
|
893 |
+ if(pm->flags & CLI_PCRE_BCOMP) { |
|
894 |
+ ret = cli_pcre_bcmp_compare_check(buffer, length, offset, pm); |
|
895 |
+ if (ret != CL_SUCCESS) { |
|
896 |
+ break; |
|
897 |
+ } |
|
898 |
+ } |
|
899 |
+ |
|
892 | 900 |
} while (global && rc > 0 && offset < adjlength); |
893 | 901 |
|
894 | 902 |
/* handle error code */ |
... | ... |
@@ -899,11 +908,6 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char ** |
899 | 899 |
if (ret != CL_SUCCESS) |
900 | 900 |
break; |
901 | 901 |
} |
902 |
- |
|
903 |
- /* hijack pcre matches for byte comparison |
|
904 |
- if (pm.comp) { |
|
905 |
- pm_dbgmsg("cli_pcre_scanbuf: assigning lsigcnt[%d][%d], located @ %d\n", |
|
906 |
- }*/ |
|
907 | 902 |
|
908 | 903 |
/* free match results */ |
909 | 904 |
cli_pcre_results_free(&p_res); |
... | ... |
@@ -913,6 +917,97 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char ** |
913 | 913 |
return ret; |
914 | 914 |
} |
915 | 915 |
|
916 |
+int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm) |
|
917 |
+{ |
|
918 |
+ if (!buffer || !pm) { |
|
919 |
+ return CL_ENULLARG; |
|
920 |
+ } |
|
921 |
+ |
|
922 |
+ const uint32_t byte_len = pm->bcmp_data.byte_len; |
|
923 |
+ unsigned char* conversion_buf[byte_len+1]; |
|
924 |
+ char opt = (char) pm->bcmp_data.options; |
|
925 |
+ uint32_t value = 0; |
|
926 |
+ const unsigned char* end_buf = NULL; |
|
927 |
+ |
|
928 |
+ if (!(pm->flags & CLI_PCRE_BCOMP) || !(offset + pm->bcmp_data.offset + pm->bcmp_data.byte_len < length)) { |
|
929 |
+ return CL_SUCCESS; |
|
930 |
+ |
|
931 |
+ } |
|
932 |
+ |
|
933 |
+ offset += pm->bcmp_data.offset; |
|
934 |
+ memcpy(conversion_buf, buffer+offset, byte_len); |
|
935 |
+ conversion_buf[byte_len] = '\0'; |
|
936 |
+ |
|
937 |
+ switch(opt) { |
|
938 |
+ /*hb*/ |
|
939 |
+ case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_LE: |
|
940 |
+ value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16); |
|
941 |
+ if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) { |
|
942 |
+ return CL_SUCCESS; |
|
943 |
+ } |
|
944 |
+ |
|
945 |
+ value = le32_to_host(value); |
|
946 |
+ break; |
|
947 |
+ |
|
948 |
+ /*hl*/ |
|
949 |
+ case CLI_PCRE_BCOMP_HEX | CLI_PCRE_BCOMP_BE: |
|
950 |
+ value = cli_strntoul(buffer+offset, byte_len, &end_buf, 16); |
|
951 |
+ if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) { |
|
952 |
+ return CL_SUCCESS; |
|
953 |
+ } |
|
954 |
+ |
|
955 |
+ value = be32_to_host(value); |
|
956 |
+ break; |
|
957 |
+ |
|
958 |
+ /*dl*/ |
|
959 |
+ case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_LE: |
|
960 |
+ value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10); |
|
961 |
+ if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) { |
|
962 |
+ return CL_SUCCESS; |
|
963 |
+ } |
|
964 |
+ |
|
965 |
+ value = le32_to_host(value); |
|
966 |
+ break; |
|
967 |
+ |
|
968 |
+ /*db*/ |
|
969 |
+ case CLI_PCRE_BCOMP_DEC | CLI_PCRE_BCOMP_BE: |
|
970 |
+ value = cli_strntoul(buffer+offset, byte_len, &end_buf, 10); |
|
971 |
+ if (value < 0 || NULL == end_buf || buffer+offset+byte_len != end_buf) { |
|
972 |
+ return CL_SUCCESS; |
|
973 |
+ } |
|
974 |
+ |
|
975 |
+ value = be32_to_host(value); |
|
976 |
+ break; |
|
977 |
+ |
|
978 |
+ default: |
|
979 |
+ return CL_ENULLARG; |
|
980 |
+ } |
|
981 |
+ |
|
982 |
+ switch (pm->bcmp_data.comp_symbol) { |
|
983 |
+ |
|
984 |
+ case '>': |
|
985 |
+ if (value > pm->bcmp_data.comp_value) { |
|
986 |
+ return CL_VIRUS; |
|
987 |
+ } |
|
988 |
+ |
|
989 |
+ case '<': |
|
990 |
+ if (value < pm->bcmp_data.comp_value) { |
|
991 |
+ return CL_VIRUS; |
|
992 |
+ } |
|
993 |
+ |
|
994 |
+ case '=': |
|
995 |
+ if (value == pm->bcmp_data.comp_value) { |
|
996 |
+ return CL_VIRUS; |
|
997 |
+ } |
|
998 |
+ |
|
999 |
+ default: |
|
1000 |
+ return CL_ENULLARG; |
|
1001 |
+ } |
|
1002 |
+ |
|
1003 |
+ return CL_SUCCESS; |
|
1004 |
+} |
|
1005 |
+ |
|
1006 |
+ |
|
916 | 1007 |
void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm) |
917 | 1008 |
{ |
918 | 1009 |
if (!pm) |
... | ... |
@@ -96,6 +96,8 @@ void cli_pcre_freeoff(struct cli_pcre_off *data); |
96 | 96 |
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); |
97 | 97 |
void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm); |
98 | 98 |
void cli_pcre_freetable(struct cli_matcher *root); |
99 |
+int cli_pcre_bcmp_compare_check(const unsigned char *buffer, uint32_t length, int offset, struct cli_pcre_meta *pm); |
|
100 |
+int cli_pcre_bcmp_add_opts(const char **opt, struct cli_pcre_bcomp *bcomp); |
|
99 | 101 |
#else |
100 | 102 |
/* NO-PCRE DECLARATIONS - defined because encasing everything in '#if' is a pain and because dynamic library mappings are weird */ |
101 | 103 |
#define PCRE_BYPASS "" |
... | ... |
@@ -539,7 +539,7 @@ size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, |
539 | 539 |
* between 2 and 36 inclusive, or be the special value 0. |
540 | 540 |
* @return long The signed long value. |
541 | 541 |
*/ |
542 |
-static long cli_strntol(const char* nptr, size_t n, char** endptr, register int base) |
|
542 |
+long cli_strntol(const char* nptr, size_t n, char** endptr, register int base) |
|
543 | 543 |
{ |
544 | 544 |
register const char* s = nptr; |
545 | 545 |
register unsigned long acc = 0; |
... | ... |
@@ -662,7 +662,7 @@ done: |
662 | 662 |
* between 2 and 36 inclusive, or be the special value 0. |
663 | 663 |
* @return unsigned long The unsigned long value. |
664 | 664 |
*/ |
665 |
-static unsigned long |
|
665 |
+unsigned long |
|
666 | 666 |
cli_strntoul(const char* nptr, size_t n, char** endptr, register int base) |
667 | 667 |
{ |
668 | 668 |
register const char* s = nptr; |
... | ... |
@@ -73,7 +73,9 @@ const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle |
73 | 73 |
char *cli_strrcpy(char *dest, const char *source); |
74 | 74 |
size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens); |
75 | 75 |
size_t cli_ldbtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens, int token_skip); |
76 |
-cl_error_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result); |
|
76 |
+long cli_strntol(const char* nptr, size_t n, char** endptr, register int base); |
|
77 |
+unsigned long cli_strntoul(const char* nptr, size_t n, char** endptr, register int base); |
|
78 |
+cl_errot_t cli_strntol_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, long *result); |
|
77 | 79 |
cl_error_t cli_strntoul_wrap(const char *buf, size_t buf_size, int fail_at_nondigit, int base, unsigned long *result); |
78 | 80 |
int cli_isnumber(const char *str); |
79 | 81 |
char *cli_unescape(const char *str); |