hyperscan 多模匹配 示例代码

代码

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
[root@localhost ]# cat   main.c
// gcc -Wall hyperscan_example.c -l m -l stdc++ -l hs && ./a.out

#include "stdio.h"
#include <string.h>

#include "hs/hs.h"

hs_database_t*
do_compile(const char **expr, int *flags, int *ids, int cnt)
{
hs_database_t *hs_db = NULL;
hs_compile_error_t *compile_err = NULL;
hs_error_t hs_error = 0;

hs_error = hs_compile_multi((const char *const *)expr, (const unsigned int *)flags, (const unsigned int *)ids, (unsigned int)cnt, HS_MODE_BLOCK,
NULL, &hs_db, &compile_err);

if (hs_error)
{
printf("hs_compile_multi ERR_CODE[%d]: Pattern[%u]:\"%s\" with error:\"%s\"",
hs_error,
ids[compile_err->expression],
expr[compile_err->expression],
compile_err->message);
goto ERR;
}

return hs_db;

ERR:
hs_free_compile_error(compile_err);
abort(); // TODO
return NULL;
}


hs_scratch_t*
get_scratch(const hs_database_t *hs_db)
{
hs_error_t hs_error = 0;
hs_scratch_t *hs_scratch = NULL;
hs_error = hs_alloc_scratch(hs_db, &hs_scratch);
if (hs_error)
{
printf("hs_alloc_scratch ERR_CODE[%d]\n", hs_error);
goto ERR;
}

return hs_scratch;

ERR:
abort(); // TODO
return NULL;
}



static int
callbackOnMatch(unsigned int node_index, unsigned long long from, unsigned long long to, unsigned int flags, void *user)
{
((void)from);
((void)to);
((void)flags);

printf("callbackOnMatch id=%u\n", node_index);

return 0; // continue matching
return 1; // stop matching
}

int
do_scan(const char *payload, int payloadLen, const hs_database_t *hs_db, hs_scratch_t* hs_scratch)
{
printf("do_scan %s\n", payload);
hs_error_t hs_err = 0;
hs_err = hs_scan(hs_db, payload, payloadLen, 0, hs_scratch, callbackOnMatch, NULL);
if (hs_err)
{
printf("ERR_CODE[%d] hs_scan\n", hs_err);
abort(); // TODO
}

printf("\n");
return 0;
}

int main()
{
struct
{
const char *str;
int id;
} list[] =
{
{"Hello", 100},
{"HelloWorld", 101},
{NULL, 0},
};

#define ELEMENTS 255

const char *expr[ELEMENTS];
int flag[ELEMENTS];
int id [ELEMENTS];
int i = 0;

for(i = 0; list[i].str; i++)
{
expr[i] = strdup(list[i].str);
flag[i] = HS_FLAG_ALLOWEMPTY|HS_FLAG_SINGLEMATCH;
id [i] = 100 + i;
}

hs_database_t *hs_db = do_compile(expr, flag, id, i);
if(NULL == hs_db)
{
return -1;
}

hs_scratch_t* hs_scratch = get_scratch(hs_db);
if(NULL == hs_scratch)
{
return -1;
}

const char *packet[] =
{
"AHello",
"BHelloWorld",
NULL,
};

for(i = 0; packet[i]; i++)
{
do_scan(packet[i], (int)strlen(packet[i]),hs_db, hs_scratch);
}

hs_free_scratch(hs_scratch);
hs_free_database(hs_db);

return 0;
}
[root@localhost ]#

编译 && 运行

1
2
3
4
5
6
7
8
9
[root@localhost ]# gcc -Wall  hyperscan_example.c  -l m -l stdc++ -l hs && ./a.out
do_scan AHello
callbackOnMatch id=100

do_scan BHelloWorld
callbackOnMatch id=100
callbackOnMatch id=101

[root@localhost ]#

受限的功能

启用 HS_FLAG_UTF8

二进制数据 种的 ASCII 明文匹配受到影响。

代码:

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
[root@localhost source]# cat hyperscan.c
#include "stdio.h"
#include <string.h>
#include "hs/hs.h"

#define ELEMENTS 255

hs_database_t*
do_compile(const char **expr, int *flags, int *ids, int cnt)
{
hs_database_t *hs_db = NULL;
hs_compile_error_t *compile_err = NULL;
hs_error_t hs_error = 0;

hs_error = hs_compile_multi((const char *const *)expr, (const unsigned int *)flags, (const unsigned int *)ids, (unsigned int)cnt, HS_MODE_BLOCK,
NULL, &hs_db, &compile_err);

if (hs_error)
{
printf("hs_compile_multi ERR_CODE[%d]: Pattern[%u]:\"%s\" with error:\"%s\"",
hs_error,
ids[compile_err->expression],
expr[compile_err->expression],
compile_err->message);
goto ERR;
}

return hs_db;

ERR:
hs_free_compile_error(compile_err);
abort(); // TODO
return NULL;
}


hs_scratch_t*
get_scratch(const hs_database_t *hs_db)
{
hs_error_t hs_error = 0;
hs_scratch_t *hs_scratch = NULL;
hs_error = hs_alloc_scratch(hs_db, &hs_scratch);
if (hs_error)
{
printf("hs_alloc_scratch ERR_CODE[%d]\n", hs_error);
goto ERR;
}

return hs_scratch;

ERR:
abort(); // TODO
return NULL;
}



static int
callbackOnMatch(unsigned int node_index, unsigned long long from, unsigned long long to, unsigned int flags, void *user)
{
((void)from);
((void)to);
((void)flags);

printf("Hit! id=%u\n", node_index);

return 0; // continue matching
return 1; // stop matching
}

int
do_scan(const char *payload, int payloadLen, const hs_database_t *hs_db, hs_scratch_t* hs_scratch)
{
hs_error_t hs_err = 0;
hs_err = hs_scan(hs_db, payload, payloadLen, 0, hs_scratch, callbackOnMatch, NULL);
if (hs_err)
{
printf("ERR_CODE[%d] hs_scan\n", hs_err);
abort(); // TODO
}
return 0;
}

int main()
{
//模式
struct
{
const char *str;
int id;
} list[] =
{
{"ANS", 101},
{"^..........ANSI", 102},
{NULL, 0},
};

//数据 内容
//?ú'??e?ú?ANSI?e
char packet_bytes[] = {
0xff, 0xfa, 0x27, 0x00, 0xff, 0xf0, 0xff, 0xfa,
0x18, 0x00, 0x41, 0x4e, 0x53, 0x49, 0xff, 0xf0
};

const char *expr[ELEMENTS];
int flag[ELEMENTS];
int id [ELEMENTS];
int i = 0;

for(i = 0; list[i].str; i++)
{
expr[i] = strdup(list[i].str);
//flag[i] = HS_FLAG_SINGLEMATCH | HS_FLAG_DOTALL | HS_FLAG_MULTILINE | HS_FLAG_UTF8; //无法匹配
flag[i] = HS_FLAG_SINGLEMATCH | HS_FLAG_DOTALL | HS_FLAG_MULTILINE; //可以匹配
id [i] = 100 + i;
}

hs_database_t *hs_db = do_compile(expr, flag, id, i);
if(NULL == hs_db)
{
return -1;
}

hs_scratch_t* hs_scratch = get_scratch(hs_db);
if(NULL == hs_scratch)
{
return -1;
}

do_scan(packet_bytes, (int)sizeof(packet_bytes), hs_db, hs_scratch);

hs_free_scratch(hs_scratch);
hs_free_database(hs_db);

return 0;
}

[root@localhost source]#

编译运行

1
2
3
4
5
[root@localhost source]# 
[root@localhost source]# gcc -Wall hyperscan_example.c -l m -l stdc++ -l hs && ./a.out
Hit! id=100
Hit! id=101
[root@localhost source]#