1 /*
2 etterfilter -- test module
3
4 Copyright (C) ALoR & NaGA
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 #include <ef.h>
23 #include <ec_filter.h>
24
25 #ifndef OS_WINDOWS
26 #include <sys/mman.h>
27 #endif
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32
33 /* protos */
34
35 void test_filter(char *filename);
36
37 void print_fop(struct filter_op *fop, u_int32 eip);
38 static void print_test(struct filter_op *fop, u_int32 eip);
39 static void print_assign(struct filter_op *fop, u_int32 eip);
40 static void print_inc(struct filter_op *fop, u_int32 eip);
41 static void print_dec(struct filter_op *fop, u_int32 eip);
42 static void print_function(struct filter_op *fop, u_int32 eip);
43
44 /*******************************************/
45
46 /*
47 * test a binary filter against a given file
48 */
test_filter(char * filename)49 void test_filter(char *filename)
50 {
51 struct filter_op *fop;
52 struct filter_env *fenv;
53 struct filter_list *flist;
54 flist = NULL;
55 u_int32 eip = 0;
56
57 /*memset(fenv, 0, sizeof(struct filter_env));*/
58
59 /* load the file */
60 if (filter_load_file(filename, &flist, 1) != E_SUCCESS) {
61 ef_exit(-1);
62 }
63 fenv = &flist->env;
64
65 /* skip the header in the file */
66 fop = fenv->chain;
67
68 USER_MSG("Disassebling \"%s\" content...\n\n", filename);
69
70 /* loop all the instructions and print their content */
71 while (eip < (fenv->len / sizeof(struct filter_op)) ) {
72
73 /* print the instruction */
74 print_fop(&fop[eip], eip);
75
76 /* autoincrement the instruction pointer */
77 eip++;
78 }
79
80 USER_MSG("\n %d instructions decoded.\n\n", (int)(fenv->len / sizeof(struct filter_op)));
81
82 ef_exit(0);
83 }
84
85 /*
86 * helper functions to print instructions
87 */
print_fop(struct filter_op * fop,u_int32 eip)88 void print_fop(struct filter_op *fop, u_int32 eip)
89 {
90 switch (fop->opcode) {
91 case FOP_TEST:
92 print_test(fop, eip);
93 break;
94
95 case FOP_ASSIGN:
96 print_assign(fop, eip);
97 break;
98
99 case FOP_INC:
100 print_inc(fop, eip);
101 break;
102
103 case FOP_DEC:
104 print_dec(fop, eip);
105 break;
106
107 case FOP_FUNC:
108 print_function(fop, eip);
109 break;
110
111 case FOP_JMP:
112 USER_MSG("%04lu: JUMP ALWAYS to %04d\n", (unsigned long)eip, fop->op.jmp);
113 break;
114
115 case FOP_JTRUE:
116 USER_MSG("%04lu: JUMP IF TRUE to %04d\n", (unsigned long)eip, fop->op.jmp);
117 break;
118
119 case FOP_JFALSE:
120 USER_MSG("%04lu: JUMP IF FALSE to %04d\n", (unsigned long)eip, fop->op.jmp);
121 break;
122
123 case FOP_EXIT:
124 USER_MSG("%04lu: EXIT\n", (unsigned long)eip);
125 break;
126
127 default:
128 USER_MSG("UNDEFINED OPCODE (%d) !!\n", fop->opcode);
129 ef_exit(-1);
130 break;
131 }
132 }
133
print_test(struct filter_op * fop,u_int32 eip)134 void print_test(struct filter_op *fop, u_int32 eip)
135 {
136 switch(fop->op.test.op) {
137 case FTEST_EQ:
138 if (fop->op.test.size != 0)
139 USER_MSG("%04lu: TEST level %d, offset %d, size %d, == %lu [%#x]\n", (unsigned long)eip,
140 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
141 else
142 USER_MSG("%04lu: TEST level %d, offset %d, \"%s\"\n", (unsigned long)eip,
143 fop->op.test.level, fop->op.test.offset, fop->op.test.string);
144 break;
145
146 case FTEST_NEQ:
147 if (fop->op.test.size != 0)
148 USER_MSG("%04lu: TEST level %d, offset %d, size %d, != %lu [%#x]\n", (unsigned long)eip,
149 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
150 else
151 USER_MSG("%04lu: TEST level %d, offset %d, not \"%s\"\n", (unsigned long)eip,
152 fop->op.test.level, fop->op.test.offset, fop->op.test.string);
153 break;
154
155 case FTEST_LT:
156 USER_MSG("%04lu: TEST level %d, offset %d, size %d, < %lu [%#x]\n", (unsigned long)eip,
157 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
158 break;
159
160 case FTEST_GT:
161 USER_MSG("%04lu: TEST level %d, offset %d, size %d, > %lu [%#x]\n", (unsigned long)eip,
162 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
163 break;
164
165 case FTEST_LEQ:
166 USER_MSG("%04lu: TEST level %d, offset %d, size %d, <= %lu [%#x]\n", (unsigned long)eip,
167 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
168 break;
169
170 case FTEST_GEQ:
171 USER_MSG("%04lu: TEST level %d, offset %d, size %d, >= %lu [%#x]\n", (unsigned long)eip,
172 fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value);
173 break;
174
175 default:
176 USER_MSG("%04lu: UNDEFINED TEST OPCODE (%d) !!\n", (unsigned long)eip, fop->op.test.op);
177 break;
178
179 }
180 }
181
print_assign(struct filter_op * fop,u_int32 eip)182 void print_assign(struct filter_op *fop, u_int32 eip)
183 {
184 if (fop->op.assign.size != 0)
185 USER_MSG("%04lu: ASSIGNMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip,
186 fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value);
187 else
188 USER_MSG("%04lu: ASSIGNMENT level %d, offset %d, string \"%s\"\n", (unsigned long)eip,
189 fop->op.assign.level, fop->op.assign.offset, fop->op.assign.string);
190
191 }
192
print_inc(struct filter_op * fop,u_int32 eip)193 void print_inc(struct filter_op *fop, u_int32 eip)
194 {
195 USER_MSG("%04lu: INCREMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip,
196 fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value);
197 }
198
print_dec(struct filter_op * fop,u_int32 eip)199 void print_dec(struct filter_op *fop, u_int32 eip)
200 {
201 USER_MSG("%04lu: DECREMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip,
202 fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value);
203 }
204
print_function(struct filter_op * fop,u_int32 eip)205 void print_function(struct filter_op *fop, u_int32 eip)
206 {
207 switch (fop->op.func.op) {
208 case FFUNC_SEARCH:
209 USER_MSG("%04lu: SEARCH level %d, string \"%s\"\n", (unsigned long)eip,
210 fop->op.func.level, fop->op.func.string);
211 break;
212
213 case FFUNC_REGEX:
214 USER_MSG("%04lu: REGEX level %d, string \"%s\"\n", (unsigned long)eip,
215 fop->op.func.level, fop->op.func.string);
216 break;
217
218 case FFUNC_PCRE:
219 if (fop->op.func.replace)
220 USER_MSG("%04lu: PCRE_REGEX level %d, string \"%s\", replace \"%s\"\n", (unsigned long)eip,
221 fop->op.func.level, fop->op.func.string, fop->op.func.replace);
222 else
223 USER_MSG("%04lu: PCRE_REGEX level %d, string \"%s\"\n", (unsigned long)eip,
224 fop->op.func.level, fop->op.func.string);
225 break;
226
227 case FFUNC_REPLACE:
228 USER_MSG("%04lu: REPLACE \"%s\" --> \"%s\"\n", (unsigned long)eip,
229 fop->op.func.string, fop->op.func.replace);
230 break;
231
232 case FFUNC_INJECT:
233 USER_MSG("%04lu: INJECT \"%s\"\n", (unsigned long)eip,
234 fop->op.func.string);
235 break;
236
237 case FFUNC_EXECINJECT:
238 USER_MSG("%04lu: EXECINJECT \"%s\"\n", (unsigned long)eip,
239 fop->op.func.string);
240 break;
241
242 case FFUNC_LOG:
243 USER_MSG("%04lu: LOG to \"%s\"\n", (unsigned long)eip, fop->op.func.string);
244 break;
245
246 case FFUNC_DROP:
247 USER_MSG("%04lu: DROP\n", (unsigned long)eip);
248 break;
249
250 case FFUNC_KILL:
251 USER_MSG("%04lu: KILL\n", (unsigned long)eip);
252 break;
253
254 case FFUNC_MSG:
255 USER_MSG("%04lu: MSG \"%s\"\n", (unsigned long)eip, fop->op.func.string);
256 break;
257
258 case FFUNC_EXEC:
259 USER_MSG("%04lu: EXEC \"%s\"\n", (unsigned long)eip, fop->op.func.string);
260 break;
261
262 default:
263 USER_MSG("%04lu: UNDEFINED FUNCTION OPCODE (%d)!!\n", (unsigned long)eip, fop->op.func.op);
264 break;
265 }
266
267 }
268
269
270 /* EOF */
271
272 // vim:ts=3:expandtab
273
274