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