-
Notifications
You must be signed in to change notification settings - Fork 663
/
matcher-ac.h
185 lines (160 loc) · 6.19 KB
/
matcher-ac.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
* Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2007-2013 Sourcefire, Inc.
*
* Authors: Tomasz Kojm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef __MATCHER_AC_H
#define __MATCHER_AC_H
#include <sys/types.h>
#include "filetypes.h"
#include "clamav-types.h"
#include "fmap.h"
#include "hashtab.h"
#include "matcher-offset.h"
#define AC_CH_MAXDIST 32
#define ACPATT_ALTN_MAXNEST 15
/* AC scanning modes */
#define AC_SCAN_VIR 1
#define AC_SCAN_FT 2
/* Pattern options */
#define ACPATT_OPTION_NOOPTS 0x00
#define ACPATT_OPTION_NOCASE 0x01
#define ACPATT_OPTION_FULLWORD 0x02
#define ACPATT_OPTION_WIDE 0x04
#define ACPATT_OPTION_ASCII 0x08
#define ACPATT_OPTION_ONCE 0x80
struct cli_subsig_matches {
uint32_t last;
uint32_t next;
uint32_t offsets[16]; /* offsets[] is variable length */
};
struct cli_lsig_matches {
uint32_t subsigs;
struct cli_subsig_matches *matches[1]; /* matches[] is variable length */
};
typedef struct cli_ac_data {
uint32_t ***offmatrix;
uint32_t partsigs, lsigs, reloffsigs;
uint32_t **lsigcnt;
uint32_t **lsigsuboff_last, **lsigsuboff_first;
struct cli_lsig_matches **lsig_matches;
uint8_t *yr_matches;
uint32_t *offset;
uint32_t macro_lastmatch[32];
/** Hashset for versioninfo matching */
const struct cli_hashset *vinfo;
uint32_t min_partno;
} cli_ac_data;
struct cli_alt_node {
uint16_t *str;
uint16_t len;
uint8_t unique;
struct cli_alt_node *next;
};
struct cli_ac_special {
union {
unsigned char *byte;
unsigned char **f_str;
struct cli_alt_node *v_str;
} alt;
uint16_t len[2], num; /* 0=MIN, 1=MAX */
uint16_t type, negative;
};
struct cli_ac_patt {
uint16_t *pattern, *prefix, length[3], prefix_length[3];
uint32_t mindist, maxdist;
uint32_t sigid;
uint32_t lsigid[3];
uint16_t ch[2];
char *virname;
void *customdata;
uint16_t ch_mindist[2];
uint16_t ch_maxdist[2];
uint16_t parts, partno, special, special_pattern;
struct cli_ac_special **special_table;
pattern_offset_data *offset_data;
uint16_t rtype, type;
uint16_t boundary;
uint8_t depth;
uint8_t sigopts;
};
struct cli_ac_list {
struct cli_ac_patt *me;
union {
struct cli_ac_node *node;
struct cli_ac_list *next;
};
struct cli_ac_list *next_same;
};
struct cli_ac_node {
struct cli_ac_list *list;
struct cli_ac_node **trans, *fail;
};
#define IS_LEAF(node) (!node->trans)
#define IS_FINAL(node) (!!node->list)
struct cli_ac_result {
const char *virname;
void *customdata;
off_t offset;
struct cli_ac_result *next;
};
#include "matcher.h"
/**
* @brief Add a simple sub-pattern into the AC trie.
*
* Simple sub-patterns may not include any wildcards or [a-b] anchored byte ranges.
*/
cl_error_t cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
/**
* @brief Increment the count for a subsignature of a logical signature.
*
* This is and alternative to lsig_increment_subsig_match() for use in subsigs that don't have a specific offset,
* like byte-compare subsigs and fuzzy-hash subsigs.
*/
void lsig_increment_subsig_match(struct cli_ac_data *mdata, uint32_t lsig_id, uint32_t subsig_id);
cl_error_t cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint32_t reloffsigs, uint8_t tracklen);
/**
* @brief Increment the count for a subsignature of a logical signature.
*
* Increment a logical signature subsignature match count.
*
* @param root The root storing all pattern matching data. I.e. "the database in memory."
* @param mdata Match result data
* @param lsig_id The current logical signature id
* @param subsig_id The current subsignature id
* @param realoff Offset where the match occured
* @param partial 0 if whole pattern, or >0 for a partial-patterns. That is one split with wildcards like * or {n-m}.
* @return cl_error_t
*/
cl_error_t lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsig_id, uint32_t subsig_id, uint32_t realoff, int partial);
cl_error_t cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1);
int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigned int *cnt, uint64_t *ids, unsigned int parse_only);
void cli_ac_freedata(struct cli_ac_data *data);
cl_error_t 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, struct cli_matched_type **ftoffset, unsigned int mode, cli_ctx *ctx);
cl_error_t cli_ac_buildtrie(struct cli_matcher *root);
cl_error_t cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, uint8_t dconf_prefiltering);
cl_error_t cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, const struct cli_target_info *info);
void cli_ac_free(struct cli_matcher *root);
/**
* @brief Add a complex sub-pattern into the AC trie.
*
* Complex sub-patterns are the body content between `{n-m}` and `{*}` wildcards in content match signatures.
* And `{n}` wildcards should have already been replaced with `??` characters and are included in the patterns.
*/
cl_error_t cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint8_t sigopts, 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);
#endif