Browse code

preliminary autoit support (ea05/ea06) minor fixes coming up later

git-svn: trunk@3340

aCaB authored on 2007/10/31 03:53:25
Showing 12 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Oct 30 19:01:41 CET 2007 (acab)
2
+-----------------------------------
3
+  * libclamav: Add preliminary autoit unpacking support
4
+
1 5
 Tue Oct 30 16:35:41 GMT 2007 (njh)
2 6
 ----------------------------------
3 7
   * libclamav/mbox.c:	Now honours --max-files
... ...
@@ -583,3 +583,33 @@ AC_DEFUN([AM_MAINTAINER_MODE],
583 583
   AC_SUBST(MAINT)dnl
584 584
 ]
585 585
 )
586
+
587
+dnl AC_C_FPU_BIGENDIAN
588
+dnl Detects FPU endianess
589
+dnl FPU_WORDS_BIGENDIAN = 1 for big endian
590
+dnl FPU_WORDS_BIGENDIAN = 0 for little endian
591
+dnl FPU_WORDS_BIGENDIAN undefined when endianes cannot be determined
592
+
593
+AC_DEFUN([AC_C_FPU_BIGENDIAN],
594
+[AC_CACHE_CHECK([whether FPU byte ordering is bigendian], [ac_cv_c_fpu_bigendian],
595
+[ac_cv_c_fpu_bigendian=unknown
596
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[double d = 3815911171354501045744583353695226502220105394563506259449467213186125718792664588210662403287568710818873279842508553551908601408568128557088985172985437412593385138085986771664896.0;]])],[
597
+if grep emmeelle conftest.$ac_objext >/dev/null 2>&1 ; then
598
+	ac_cv_c_fpu_bigendian=yes
599
+fi
600
+if grep elleemme conftest.$ac_objext >/dev/null 2>&1 ; then
601
+	ac_cv_c_fpu_bigendian=no
602
+fi
603
+])])
604
+case $ac_cv_c_fpu_bigendian in
605
+	yes)
606
+		AC_DEFINE([FPU_WORDS_BIGENDIAN], 1, [FPU byte ordering is big endian])
607
+		;;
608
+	no)
609
+		AC_DEFINE([FPU_WORDS_BIGENDIAN], 0, [FPU byte ordering is little endian])
610
+		;;
611
+	*)
612
+		AC_MSG_WARN([Unable to determine FPU endianess, some features may not be available in this build])
613
+esac
614
+])
615
+
... ...
@@ -90,6 +90,9 @@
90 90
 /* file i/o buffer size */
91 91
 #undef FILEBUFF
92 92
 
93
+/* FPU byte ordering is little endian */
94
+#undef FPU_WORDS_BIGENDIAN
95
+
93 96
 /* enable workaround for broken DNS servers */
94 97
 #undef FRESHCLAM_DNS_FIX
95 98
 
... ...
@@ -26186,6 +26186,76 @@ fi
26186 26186
 { echo "$as_me:$LINENO: result: $have_signed_rightshift_extended" >&5
26187 26187
 echo "${ECHO_T}$have_signed_rightshift_extended" >&6; };
26188 26188
 
26189
+{ echo "$as_me:$LINENO: checking whether FPU byte ordering is bigendian" >&5
26190
+echo $ECHO_N "checking whether FPU byte ordering is bigendian... $ECHO_C" >&6; }
26191
+if test "${ac_cv_c_fpu_bigendian+set}" = set; then
26192
+  echo $ECHO_N "(cached) $ECHO_C" >&6
26193
+else
26194
+  ac_cv_c_fpu_bigendian=unknown
26195
+cat >conftest.$ac_ext <<_ACEOF
26196
+/* confdefs.h.  */
26197
+_ACEOF
26198
+cat confdefs.h >>conftest.$ac_ext
26199
+cat >>conftest.$ac_ext <<_ACEOF
26200
+/* end confdefs.h.  */
26201
+double d = 3815911171354501045744583353695226502220105394563506259449467213186125718792664588210662403287568710818873279842508553551908601408568128557088985172985437412593385138085986771664896.0;
26202
+_ACEOF
26203
+rm -f conftest.$ac_objext
26204
+if { (ac_try="$ac_compile"
26205
+case "(($ac_try" in
26206
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
26207
+  *) ac_try_echo=$ac_try;;
26208
+esac
26209
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
26210
+  (eval "$ac_compile") 2>conftest.er1
26211
+  ac_status=$?
26212
+  grep -v '^ *+' conftest.er1 >conftest.err
26213
+  rm -f conftest.er1
26214
+  cat conftest.err >&5
26215
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
26216
+  (exit $ac_status); } && {
26217
+	 test -z "$ac_c_werror_flag" ||
26218
+	 test ! -s conftest.err
26219
+       } && test -s conftest.$ac_objext; then
26220
+
26221
+if grep emmeelle conftest.$ac_objext >/dev/null 2>&1 ; then
26222
+	ac_cv_c_fpu_bigendian=yes
26223
+fi
26224
+if grep elleemme conftest.$ac_objext >/dev/null 2>&1 ; then
26225
+	ac_cv_c_fpu_bigendian=no
26226
+fi
26227
+
26228
+else
26229
+  echo "$as_me: failed program was:" >&5
26230
+sed 's/^/| /' conftest.$ac_ext >&5
26231
+
26232
+
26233
+fi
26234
+
26235
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
26236
+fi
26237
+{ echo "$as_me:$LINENO: result: $ac_cv_c_fpu_bigendian" >&5
26238
+echo "${ECHO_T}$ac_cv_c_fpu_bigendian" >&6; }
26239
+case $ac_cv_c_fpu_bigendian in
26240
+	yes)
26241
+
26242
+cat >>confdefs.h <<\_ACEOF
26243
+#define FPU_WORDS_BIGENDIAN 1
26244
+_ACEOF
26245
+
26246
+		;;
26247
+	no)
26248
+
26249
+cat >>confdefs.h <<\_ACEOF
26250
+#define FPU_WORDS_BIGENDIAN 0
26251
+_ACEOF
26252
+
26253
+		;;
26254
+	*)
26255
+		{ echo "$as_me:$LINENO: WARNING: Unable to determine FPU endianess, some features may not be available in this build" >&5
26256
+echo "$as_me: WARNING: Unable to determine FPU endianess, some features may not be available in this build" >&2;}
26257
+esac
26258
+
26189 26259
 
26190 26260
 ac_config_files="$ac_config_files libclamunrar/Makefile libclamav/Makefile clamscan/Makefile database/Makefile docs/Makefile clamd/Makefile clamdscan/Makefile clamav-milter/Makefile freshclam/Makefile sigtool/Makefile clamconf/Makefile etc/Makefile Makefile clamav-config libclamav.pc docs/man/clamav-milter.8 docs/man/clamconf.1 docs/man/clamd.8 docs/man/clamd.conf.5 docs/man/clamdscan.1 docs/man/clamscan.1 docs/man/freshclam.1 docs/man/freshclam.conf.5 docs/man/sigtool.1"
26191 26261
 
... ...
@@ -1210,6 +1210,7 @@ if test $have_signed_rightshift_extended = yes; then
1210 1210
 fi
1211 1211
 AC_MSG_RESULT($have_signed_rightshift_extended);
1212 1212
 
1213
+AC_C_FPU_BIGENDIAN
1213 1214
 
1214 1215
 AC_OUTPUT([
1215 1216
 libclamunrar/Makefile
... ...
@@ -115,6 +115,8 @@ libclamav_la_SOURCES = \
115 115
 	is_tar.h \
116 116
 	tnef.c \
117 117
 	tnef.h \
118
+	autoit.c \
119
+	autoit.h \
118 120
 	regex/strlcpy.c \
119 121
 	regex/regcomp.c \
120 122
 	regex/regerror.c \
... ...
@@ -84,10 +84,10 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \
84 84
 	pe.lo upx.lo htmlnorm.lo chmunpack.lo rebuildpe.lo petite.lo \
85 85
 	wwunpack.lo unsp.lo aspack.lo packlibs.lo fsg.lo mew.lo \
86 86
 	upack.lo line.lo untar.lo unzip.lo special.lo binhex.lo \
87
-	is_tar.lo tnef.lo strlcpy.lo regcomp.lo regerror.lo regexec.lo \
88
-	regfree.lo unarj.lo LZMADecode.lo bzlib.lo infblock.lo \
89
-	nulsft.lo pdf.lo spin.lo yc.lo elf.lo sis.lo uuencode.lo \
90
-	pst.lo phishcheck.lo phish_domaincheck_db.lo \
87
+	is_tar.lo tnef.lo autoit.lo strlcpy.lo regcomp.lo regerror.lo \
88
+	regexec.lo regfree.lo unarj.lo LZMADecode.lo bzlib.lo \
89
+	infblock.lo nulsft.lo pdf.lo spin.lo yc.lo elf.lo sis.lo \
90
+	uuencode.lo pst.lo phishcheck.lo phish_domaincheck_db.lo \
91 91
 	phish_whitelist.lo regex_list.lo mspack.lo cab.lo entconv.lo \
92 92
 	hashtab.lo dconf.lo lockdb.lo
93 93
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
... ...
@@ -327,6 +327,8 @@ libclamav_la_SOURCES = \
327 327
 	is_tar.h \
328 328
 	tnef.c \
329 329
 	tnef.h \
330
+	autoit.c \
331
+	autoit.h \
330 332
 	regex/strlcpy.c \
331 333
 	regex/regcomp.c \
332 334
 	regex/regerror.c \
... ...
@@ -462,6 +464,7 @@ distclean-compile:
462 462
 
463 463
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LZMADecode.Plo@am__quote@
464 464
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aspack.Plo@am__quote@
465
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoit.Plo@am__quote@
465 466
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binhex.Plo@am__quote@
466 467
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blob.Plo@am__quote@
467 468
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bzlib.Plo@am__quote@
468 469
new file mode 100644
... ...
@@ -0,0 +1,901 @@
0
+/*
1
+ *  Copyright (C) 2007 Sourcefire Inc.
2
+ *  Author: aCaB <acab@clamav.net>
3
+ *
4
+ *  This program is free software; you can redistribute it and/or modify
5
+ *  it under the terms of the GNU General Public License version 2 as
6
+ *  published by the Free Software Foundation.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+ *  MA 02110-1301, USA.
17
+ */
18
+
19
+#if HAVE_CONFIG_H
20
+#include "clamav-config.h"
21
+#endif
22
+
23
+#include <sys/types.h>
24
+#include <sys/stat.h>
25
+#include <fcntl.h>
26
+#include <stdio.h>
27
+/* Gianluigi, you may want to include winsuck here or just make ntohl a macro */
28
+#include <arpa/inet.h>
29
+#include <string.h>
30
+
31
+#ifdef HAVE_UNISTD_H
32
+#include <unistd.h>
33
+#endif
34
+
35
+#ifndef O_BINARY
36
+#define O_BINARY        0
37
+#endif
38
+
39
+#include "others.h"
40
+#include "scanners.h"
41
+
42
+
43
+/* FIXME: use unicode detection and normalization from edwin */
44
+static unsigned int u2a(uint8_t *d, unsigned int l) {
45
+  unsigned int i=l;
46
+  uint8_t *s = d;
47
+  if(l<2) return l;
48
+  if(d[0] == 0xff && d[1] == 0xfe) {
49
+    s += 2;
50
+    l -= 2;
51
+  } else if (d[1] != 0) {
52
+    return l;
53
+  }
54
+    
55
+  if(l<2) return i;
56
+
57
+  for (i = 0 ; i < l; i += 2)
58
+    *d++ = s[i];
59
+  *d = '\0';
60
+  return (unsigned int)(d-s);
61
+}
62
+    
63
+
64
+/*********************
65
+   MT realted stuff 
66
+*********************/
67
+
68
+struct MT {
69
+  uint32_t mt[624];
70
+  uint32_t items;
71
+  uint32_t *next;
72
+};
73
+
74
+static uint8_t MT_getnext(struct MT *MT) {
75
+  uint32_t r;
76
+
77
+  if (!--MT->items) {
78
+    uint32_t *mt = MT->mt;
79
+    unsigned int i;
80
+
81
+    MT->items = 624;
82
+    MT->next = mt;
83
+
84
+    for (i=0; i<227; i++)
85
+      mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i+397];
86
+    for (; i<623; i++)
87
+      mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i-227];
88
+    mt[623] = ((((mt[623] ^ mt[0])&0x7ffffffe)^mt[623])>>1)^((0-(mt[0]&1))&0x9908b0df)^mt[i-227];
89
+  }
90
+
91
+  r = *(MT->next++);
92
+  r ^= (r >> 11);
93
+  r ^= ((r & 0xff3a58ad) << 7);
94
+  r ^= ((r & 0xffffdf8c) << 15);
95
+  r ^= (r >> 18);
96
+  return (uint8_t)(r >> 1);
97
+}
98
+
99
+static void MT_decrypt(uint8_t *buf, unsigned int size, uint32_t seed) {
100
+  struct MT MT;
101
+  unsigned int i;
102
+  uint32_t *mt = MT.mt;
103
+
104
+  *mt=seed;
105
+  for(i=1; i<624; i++)
106
+    mt[i] = i+0x6c078965*((mt[i-1]>>30)^mt[i-1]);
107
+  MT.items = 1;
108
+
109
+  while(size--)
110
+    *buf++ ^= MT_getnext(&MT);
111
+}
112
+
113
+
114
+/*********************
115
+     inflate stuff 
116
+*********************/
117
+
118
+struct UNP {
119
+  uint8_t *outputbuf;
120
+  uint8_t *inputbuf;
121
+  uint32_t cur_output;
122
+  uint32_t cur_input;
123
+  uint32_t usize;
124
+  uint32_t csize;
125
+  uint32_t bits_avail;
126
+  union {
127
+    uint32_t full;
128
+    struct {
129
+#if WORDS_BIGENDIAN != 0
130
+      uint16_t h; /* BE */
131
+      uint16_t l;
132
+#else
133
+      uint16_t l; /* LE */
134
+      uint16_t h;
135
+#endif
136
+    } half;
137
+  } bitmap;
138
+  uint32_t error;
139
+};
140
+
141
+
142
+static uint32_t getbits(struct UNP *UNP, uint32_t size) {
143
+  UNP->bitmap.half.h = 0;
144
+  if (size > UNP->bits_avail && ((size - UNP->bits_avail - 1)/16+1)*2 > UNP->csize - UNP->cur_input) {
145
+    cli_dbgmsg("autoit: getbits() - not enough bits available");
146
+    UNP->error = 1;
147
+    return 0; /* won't infloop nor spam */
148
+  }
149
+  while (size) {
150
+    if (!UNP->bits_avail) {
151
+      UNP->bitmap.half.l |= UNP->inputbuf[UNP->cur_input++]<<8;
152
+      UNP->bitmap.half.l |= UNP->inputbuf[UNP->cur_input++];
153
+      UNP->bits_avail = 16;
154
+    }
155
+    UNP->bitmap.full<<=1;
156
+    UNP->bits_avail--;
157
+    size--;
158
+  }
159
+  return (uint32_t)UNP->bitmap.half.h;
160
+}
161
+
162
+
163
+/*********************
164
+ autoit3 EA05 handler 
165
+*********************/
166
+
167
+
168
+static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
169
+  uint8_t b[300], comp;
170
+  uint8_t *buf = b;
171
+  uint32_t s, m4sum=0;
172
+  int i;
173
+  unsigned int files=0;
174
+  char tempfile[1024];
175
+  struct UNP UNP;
176
+
177
+  if (cli_readn(desc, buf, 16)!=16)
178
+    return CL_CLEAN;
179
+
180
+  for (i=0; i<16; i++)
181
+    m4sum += buf[i];
182
+
183
+  while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) {
184
+    buf = b;
185
+    if (cli_readn(desc, buf, 8)!=8)
186
+      return CL_CLEAN;
187
+
188
+    /*     MT_decrypt(buf,4,0x16fa);  waste of time */
189
+    if((uint32_t)cli_readint32((char *)buf) != 0xceb06dff) {
190
+      cli_dbgmsg("autoit: no FILE magic found, extraction complete\n");
191
+      return CL_CLEAN;
192
+    }
193
+
194
+    s = cli_readint32((char *)buf+4) ^ 0x29bc;
195
+    buf=b;
196
+    if(cli_debug_flag && s<300) {
197
+      if (cli_readn(desc, buf, s)!=(int)s)
198
+	return CL_CLEAN;
199
+      buf[s]='\0';
200
+      MT_decrypt(buf,s,s+0xa25e);
201
+      cli_dbgmsg("autoit: magic string '%s'\n", buf);
202
+    } else {
203
+      lseek(desc, s, SEEK_CUR);
204
+    }
205
+
206
+    if (cli_readn(desc, buf, 4)!=4)
207
+      return CL_CLEAN;
208
+    s = cli_readint32((char *)buf) ^ 0x29ac;
209
+    if ((int32_t)s<0)
210
+      return CL_CLEAN; /* the original code wouldn't seek back here */
211
+    if (cli_debug_flag && s<300) {
212
+      if (cli_readn(desc, buf, s)!=(int)s)
213
+	return CL_CLEAN;
214
+      MT_decrypt(buf,s,s+0xf25e);
215
+      buf[s]='\0';
216
+      cli_dbgmsg("autoit: original filename '%s'\n", buf);
217
+    } else {
218
+      lseek(desc, s, SEEK_CUR);
219
+    }
220
+
221
+    if (cli_readn(desc, buf, 13)!=13)
222
+      return CL_CLEAN;
223
+    comp = *buf;
224
+    UNP.csize = cli_readint32((char *)buf+1) ^ 0x45aa;
225
+    cli_dbgmsg("autoit: compressed size: %x\n", UNP.csize);
226
+    cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x45aa);
227
+    cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xc3d2);
228
+
229
+    lseek(desc, 16, SEEK_CUR);
230
+
231
+    if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) {
232
+      cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
233
+      lseek(desc, UNP.csize, SEEK_CUR);
234
+      continue;
235
+    }
236
+
237
+    if (!(buf = cli_malloc(UNP.csize)))
238
+      return CL_EMEM;
239
+    if (cli_readn(desc, buf, UNP.csize)!=(int)UNP.csize) {
240
+      cli_dbgmsg("autoit: failed to read compressed stream. broken/truncated file?\n");
241
+      free(buf);
242
+      return CL_CLEAN;
243
+    }
244
+    MT_decrypt(buf,UNP.csize,0x22af+m4sum);
245
+
246
+    if (comp == 1) {
247
+      cli_dbgmsg("autoit: file is compressed\n");
248
+      if (cli_readint32((char *)buf)!=0x35304145) {
249
+	cli_dbgmsg("autoit: bad magic or unsupported version\n");
250
+	free(buf);
251
+	continue;
252
+      }
253
+
254
+      UNP.usize = ntohl(*(uint32_t *)(buf+4));
255
+      if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) {
256
+	cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
257
+	free(buf);
258
+	continue;
259
+      }
260
+
261
+      if (!(UNP.outputbuf = cli_malloc(UNP.usize))) {
262
+	free(buf);
263
+	return CL_EMEM;
264
+      }
265
+      cli_dbgmsg("autoit: uncompressed size again: %x\n", UNP.usize);
266
+
267
+      UNP.inputbuf = buf;
268
+      UNP.cur_output = 0;
269
+      UNP.cur_input = 8;
270
+      UNP.bitmap.full = 0;
271
+      UNP.bits_avail = 0;
272
+      UNP.error = 0;
273
+  
274
+      while (!UNP.error && UNP.cur_output < UNP.usize) {
275
+	if (getbits(&UNP, 1)) {
276
+	  uint32_t bb, bs, addme=0;
277
+	  bb = getbits(&UNP, 15);
278
+      
279
+	  if ((bs = getbits(&UNP, 2))==3) {
280
+	    addme = 3;
281
+	    if((bs = getbits(&UNP, 3))==7) {
282
+	      addme = 10;
283
+	      if((bs = getbits(&UNP, 5))==31) {
284
+		addme = 41;
285
+		if((bs = getbits(&UNP, 8))==255) {
286
+		  addme = 296;
287
+		  while((bs = getbits(&UNP, 8))==255) {
288
+		    addme+=255;
289
+		  }
290
+		}
291
+	      }
292
+	    }
293
+	  }
294
+	  bs += 3+addme;
295
+
296
+	  if(!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
297
+	     !CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output-bb], bs)) {
298
+	    UNP.error = 1;
299
+	    break;
300
+	  }
301
+	  while(bs--) {
302
+	    UNP.outputbuf[UNP.cur_output]=UNP.outputbuf[UNP.cur_output-bb];
303
+	    UNP.cur_output++;
304
+	  }
305
+	} else {
306
+	  UNP.outputbuf[UNP.cur_output] = (uint8_t)getbits(&UNP, 8);
307
+	  UNP.cur_output++;
308
+	}
309
+      }
310
+
311
+      free(buf);
312
+      if (UNP.error) {
313
+	cli_dbgmsg("autoit: decompression error\n");
314
+	free(UNP.outputbuf);
315
+	continue;
316
+      }
317
+    } else {
318
+      cli_dbgmsg("autoit: file is not compressed\n");
319
+      UNP.outputbuf = buf;
320
+      UNP.usize = UNP.csize;
321
+    }
322
+
323
+    files++;
324
+
325
+    /* FIXME: TODO send to text notmalization */
326
+
327
+    /* FIXME: ad-interim solution. ideally we should only u2a unicode scripts */
328
+    UNP.usize = u2a(UNP.outputbuf, UNP.usize);
329
+
330
+    snprintf(tempfile, 1023, "%s/autoit.%.3u", tmpd, files);
331
+    tempfile[1023]='\0';
332
+    if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
333
+      cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
334
+      free(UNP.outputbuf);
335
+      return CL_EIO;
336
+    }
337
+    if(cli_writen(i, UNP.outputbuf, UNP.usize) != (int32_t)UNP.usize) {
338
+      cli_dbgmsg("autoit: cannot write %d bytes\n", UNP.usize);
339
+      close(i);
340
+      free(UNP.outputbuf);
341
+      return CL_EIO;
342
+    }
343
+    free(UNP.outputbuf);
344
+    if(cli_leavetemps_flag)
345
+      cli_dbgmsg("autoit: file extracted to %s\n", tempfile);
346
+    else 
347
+      cli_dbgmsg("autoit: file successfully extracted\n");
348
+    fsync(i);
349
+    lseek(i, 0, SEEK_SET);
350
+    if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
351
+      close(i);
352
+      if(!cli_leavetemps_flag) unlink(tempfile);
353
+      return CL_VIRUS;
354
+    }
355
+    close(i);
356
+    if(!cli_leavetemps_flag) unlink(tempfile);
357
+  }
358
+  cli_dbgmsg("autoit: files limit reached (max: %u)\n", ctx->limits->maxfiles);
359
+  return CL_EMAXFILES;
360
+}
361
+
362
+
363
+/*********************
364
+  LAME realted stuff 
365
+*********************/
366
+
367
+#ifdef FPU_WORDS_BIGENDIAN
368
+#define ROFL(a,b) (( a << (b % (sizeof(a)<<3) ))  |  (a >> (  (sizeof(a)<<3)  -  (b % (sizeof(a)<<3 )) ) ))
369
+
370
+struct LAME {
371
+  uint32_t c0;
372
+  uint32_t c1;
373
+  uint32_t grp1[17];
374
+};
375
+
376
+
377
+static double LAME_fpusht(struct LAME *l) {
378
+  union {
379
+    double as_double;
380
+    struct {
381
+#if FPU_WORDS_BIGENDIAN == 0
382
+      uint32_t lo;
383
+      uint32_t hi;
384
+#else
385
+      uint32_t hi;
386
+      uint32_t lo;
387
+#endif
388
+    } as_uint;
389
+  } ret;
390
+
391
+  uint32_t rolled = ROFL(l->grp1[l->c0],9) +  ROFL(l->grp1[l->c1],13);
392
+
393
+  l->grp1[l->c0] = rolled;
394
+
395
+  if (!l->c0--) l->c0 = 16;
396
+  if (!l->c1--) l->c1 = 16;
397
+
398
+/*   if (l->grp1[l->c0] == l->grp2[0]) { */
399
+/*     if (!memcmp(l->grp1, (uint32_t *)l + 0x24 - l->c0, 0x44)) */
400
+/*       return 0.0; */
401
+/*   } */
402
+
403
+#if WORDS_BIGENDIAN == FPU_WORDS_BIGENDIAN
404
+  ret.as_uint.lo = rolled << 0x14;
405
+  ret.as_uint.hi = 0x3ff00000 | (rolled >> 0xc);
406
+#else
407
+  do {
408
+    uint32_t tmp = rolled << 0x14;
409
+  
410
+    ret.as_uint.lo = ((tmp&0xff)<<24) | (((tmp>>8)&0xff)<<16) | (((tmp>>16)&0xff)<<8) | ((tmp>>24)&0xff);
411
+    tmp = 0x3ff00000 | (rolled >> 0xc);
412
+    ret.as_uint.hi = ((tmp&0xff)<<24) | (((tmp>>8)&0xff)<<16) | (((tmp>>16)&0xff)<<8) | ((tmp>>24)&0xff);
413
+  } while(0);
414
+#endif
415
+  return ret.as_double - 1.0;
416
+}
417
+
418
+
419
+static void LAME_srand(struct LAME *l, uint32_t seed) {
420
+  unsigned int i;
421
+
422
+  for (i=0; i<17; i++) {
423
+    seed *= 0x53A9B4FB; /*1403630843*/
424
+    seed = 1 - seed;
425
+    l->grp1[i] = seed;
426
+  }
427
+
428
+  l->c0 = 0;
429
+  l->c1 = 10;
430
+
431
+  for (i = 0; i < 9; i++)
432
+    LAME_fpusht(l);
433
+}
434
+
435
+static uint8_t LAME_getnext(struct LAME *l) {
436
+  double x;
437
+  uint8_t ret;
438
+
439
+  LAME_fpusht(l);
440
+  x = LAME_fpusht(l) * 256.0;
441
+  if ((int32_t)x < 256) ret = (uint8_t)x;
442
+  else ret=0xff;
443
+  return ret;
444
+}
445
+
446
+static void LAME_decrypt (uint8_t *cypher, uint32_t size, uint16_t seed) {
447
+  struct LAME lame;
448
+  /* mt_srand_timewrap(struct srand_struc bufDC); */
449
+
450
+  LAME_srand(&lame, (uint32_t)seed);
451
+  while(size--)
452
+    *cypher++^=LAME_getnext(&lame);
453
+}
454
+
455
+
456
+/*********************
457
+ autoit3 EA06 handler 
458
+*********************/
459
+
460
+static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
461
+  uint8_t b[600], comp, script;
462
+  uint8_t *buf;
463
+  uint32_t s;
464
+  int i;
465
+  unsigned int files=0;
466
+  char tempfile[1024];
467
+  const char prefixes[] = { '\0', '\0', '@', '$', '\0', '.', '"', '#' };
468
+  const char *opers[] = { ",", "=", ">", "<", "<>", ">=", "<=", "(", ")", "+", "-", "/", "*", "&", "[", "]", "==", "^", "+=", "-=", "/=", "*=", "&=" };
469
+  struct UNP UNP;
470
+
471
+  UNP.error = 0;
472
+
473
+  /* Useless due to a bug in CRC calculation - LMAO!!1 */
474
+  /*   if (cli_readn(desc, buf, 24)!=24) */
475
+  /*     return CL_CLEAN; */
476
+  /*   LAME_decrypt(buf, 0x10, 0x99f2); */
477
+  /*   buf+=0x10; */
478
+  lseek(desc, 16, SEEK_CUR);   /* for now we just skip the garbage */
479
+
480
+  while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) {
481
+    /* FIXME: count files here */
482
+    buf = b;
483
+    if (cli_readn(desc, buf, 8)!=8)
484
+      return CL_CLEAN;
485
+    /*     LAME_decrypt(buf, 4, 0x18ee); FIXME: waste of time */
486
+    if(cli_readint32((char *)buf) != 0x52ca436b) {
487
+      cli_dbgmsg("autoit: no FILE magic found, giving up\n");
488
+      return CL_CLEAN;
489
+    }
490
+
491
+    s = cli_readint32((char *)buf+4) ^ 0xadbc;
492
+    script = 0;
493
+    if(s<300) {
494
+      if (cli_readn(desc, buf, s*2)!=(int)s*2)
495
+	return CL_CLEAN;
496
+      LAME_decrypt(buf,s*2,s+0xb33f);
497
+      buf[s*2]='\0'; buf[s*2+1]='\0';
498
+      u2a(buf,s*2); /* FIXME: GET RID OF THIS */
499
+      cli_dbgmsg("autoit: magic string '%s'\n", buf);
500
+      if (s==19 && !memcmp(">>>AUTOIT SCRIPT<<<", buf, 19))
501
+	script = 1;
502
+    } else {
503
+      cli_dbgmsg("autoit: magic string too long to print\n");
504
+      lseek(desc, s*2, SEEK_CUR);
505
+    }
506
+
507
+    if (cli_readn(desc, buf, 4)!=4)
508
+      return CL_CLEAN;
509
+    s = cli_readint32((char *)buf) ^ 0xf820;
510
+    if(cli_debug_flag && s<300) {
511
+      if (cli_readn(desc, buf, s*2)!=(int)s*2)
512
+	return CL_CLEAN;
513
+      LAME_decrypt(buf,s*2,s+0xf479);
514
+      buf[s*2]='\0'; buf[s*2+1]='\0';
515
+      u2a(buf,s*2); /* FIXME: GET RID OF THIS */
516
+      cli_dbgmsg("autoit: original filename '%s'\n", buf);
517
+    } else {
518
+      lseek(desc, s*2, SEEK_CUR);
519
+    }
520
+
521
+    if (cli_readn(desc, buf, 13)!=13)
522
+      return CL_CLEAN;
523
+    comp = *buf;
524
+    UNP.csize = cli_readint32((char *)buf+1) ^ 0x87bc;
525
+    cli_dbgmsg("autoit: compressed size: %x\n", UNP.csize);
526
+    cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x87bc);
527
+    cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xa685);
528
+
529
+    lseek(desc, 16, SEEK_CUR);
530
+
531
+    if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) {
532
+      cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
533
+      lseek(desc, UNP.csize, SEEK_CUR);
534
+      continue;
535
+    }
536
+
537
+    files++;
538
+    if (!(buf = cli_malloc(UNP.csize)))
539
+      return CL_EMEM;
540
+    if (cli_readn(desc, buf, UNP.csize)!=(int)UNP.csize) {
541
+      cli_dbgmsg("autoit: failed to read compressed stream. broken/truncated file?\n");
542
+      free(buf);
543
+      return CL_CLEAN;
544
+    }
545
+    LAME_decrypt(buf,UNP.csize,0x2477 /* + m4sum (broken by design) */ );
546
+
547
+    if (comp == 1) {
548
+      cli_dbgmsg("autoit: file is compressed\n");
549
+      if (cli_readint32((char *)buf)!=0x36304145) {
550
+	cli_dbgmsg("autoit: bad magic or unsupported version\n");
551
+	free(buf);
552
+	continue;
553
+      }
554
+
555
+      UNP.usize = ntohl(*(uint32_t *)(buf+4));
556
+      if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) {
557
+	free(buf);
558
+	continue;
559
+      }
560
+      if (!(UNP.outputbuf = cli_malloc(UNP.usize))) {
561
+	free(buf);
562
+	return CL_EMEM;
563
+      }
564
+      cli_dbgmsg("autoit: uncompressed size again: %x\n", UNP.usize);
565
+
566
+      UNP.inputbuf = buf;
567
+      UNP.cur_output = 0;
568
+      UNP.cur_input = 8;
569
+      UNP.bitmap.full = 0;
570
+      UNP.bits_avail = 0;
571
+  
572
+      while (!UNP.error && UNP.cur_output < UNP.usize) {
573
+	if (!getbits(&UNP, 1)) {
574
+	  uint32_t bb, bs, addme=0;
575
+	  bb = getbits(&UNP, 15);
576
+      
577
+	  if ((bs = getbits(&UNP, 2))==3) {
578
+	    addme = 3;
579
+	    if((bs = getbits(&UNP, 3))==7) {
580
+	      addme = 10;
581
+	      if((bs = getbits(&UNP, 5))==31) {
582
+		addme = 41;
583
+		if((bs = getbits(&UNP, 8))==255) {
584
+		  addme = 296;
585
+		  while((bs = getbits(&UNP, 8))==255) {
586
+		    addme+=255;
587
+		  }
588
+		}
589
+	      }
590
+	    }
591
+	  }
592
+	  bs += 3+addme;
593
+
594
+	  if(!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
595
+	     !CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output-bb], bs)) {
596
+	    UNP.error = 1;
597
+	    break;
598
+	  }
599
+	  while(bs--) {
600
+	    UNP.outputbuf[UNP.cur_output]=UNP.outputbuf[UNP.cur_output-bb];
601
+	    UNP.cur_output++;
602
+	  }
603
+	} else {
604
+	  UNP.outputbuf[UNP.cur_output] = (uint8_t)getbits(&UNP, 8);
605
+	  UNP.cur_output++;
606
+	}
607
+      }
608
+
609
+      free(buf);
610
+      if (UNP.error) {
611
+	cli_dbgmsg("autoit: decompression error\n");
612
+	free(UNP.outputbuf);
613
+	continue;
614
+      }
615
+    } else {
616
+      cli_dbgmsg("autoit: file is not compressed\n");
617
+      UNP.outputbuf = buf;
618
+      UNP.usize = UNP.csize;
619
+    }
620
+
621
+    if (UNP.usize<4) {
622
+      cli_dbgmsg("autoit: file is too short\n");
623
+      free(UNP.outputbuf);
624
+      continue;
625
+    }
626
+
627
+    if (script) {
628
+      UNP.csize = UNP.usize;
629
+      if (!(buf = cli_malloc(UNP.csize))) {
630
+	free(UNP.outputbuf);
631
+	return CL_EMEM;
632
+      }
633
+      UNP.cur_output = 0;
634
+      UNP.cur_input = 4;
635
+      UNP.bits_avail = cli_readint32((char *)UNP.outputbuf);
636
+      cli_dbgmsg("autoit: script has got %u lines\n", UNP.bits_avail);
637
+
638
+      while (!UNP.error && UNP.bits_avail && UNP.cur_input < UNP.usize) {
639
+	uint8_t op;
640
+
641
+	switch((op = UNP.outputbuf[UNP.cur_input++])) {
642
+	case 5: /* <INT> */
643
+	  if (UNP.cur_input >= UNP.usize-4) {
644
+	    UNP.error = 1;
645
+	    cli_dbgmsg("autoit: not enough space for an int\n");
646
+	    break;
647
+	  }
648
+	  if (UNP.cur_output+12 >= UNP.csize) {
649
+	    uint8_t *newout;
650
+	    UNP.csize += 512;
651
+	    if (!(newout = cli_realloc(buf, UNP.csize))) {
652
+	      UNP.error = 1;
653
+	      break;
654
+	    }
655
+	    buf = newout;
656
+	  }
657
+	  UNP.cur_output += snprintf((char *)&buf[UNP.cur_output], 12, "0x%08x ", cli_readint32((char *)&UNP.outputbuf[UNP.cur_input]));
658
+	  UNP.cur_input += 4;
659
+	  break;
660
+
661
+	case 0x20: /* <DOUBLE> */
662
+	  if (UNP.usize < 8 || UNP.cur_input >= UNP.usize-8) {
663
+	    UNP.error = 1;
664
+	    cli_dbgmsg("autoit: not enough space for a double\n");
665
+	    break;
666
+	  }
667
+	  if (UNP.cur_output+40 >= UNP.csize) {
668
+	    uint8_t *newout;
669
+	    UNP.csize += 512;
670
+	    if (!(newout = cli_realloc(buf, UNP.csize))) {
671
+	      UNP.error = 1;
672
+	      break;
673
+	    }
674
+	    buf = newout;
675
+	  }
676
+#if FPU_WORDS_BIGENDIAN == 0
677
+	  snprintf((char *)&buf[UNP.cur_output], 39, "%g ", *(double *)&UNP.outputbuf[UNP.cur_input]);
678
+#else
679
+	  do {
680
+	    double x;
681
+	    uint8_t *j = (uint8_t *)&x;
682
+	    unsigned int i;
683
+
684
+	    for(i=0; i<8; i++)
685
+	      j[7-i]=UNP.outputbuf[UNP.cur_input+i];
686
+	    snprintf((char *)&buf[UNP.cur_output], 39, "%g ", x); /* FIXME: check */
687
+	  } while(0);
688
+#endif
689
+	  buf[UNP.cur_output+38]=' ';
690
+	  buf[UNP.cur_output+39]='\0';
691
+	  UNP.cur_output += strlen((char *)&buf[UNP.cur_output]);
692
+	  UNP.cur_input += 8;
693
+	  break;
694
+
695
+	case 0x30: /* COSTRUCT */
696
+	case 0x31: /* COMMAND */
697
+	case 0x32: /* MACRO */
698
+	case 0x33: /* VAR */
699
+	case 0x34: /* FUNC */
700
+	case 0x35: /* OBJECT */
701
+	case 0x36: /* STRING */
702
+	case 0x37: /* DIRECTIVE */
703
+	  {
704
+	    uint32_t chars, dchars, i;
705
+
706
+	    if (UNP.cur_input >= UNP.usize-4) {
707
+	      UNP.error = 1;
708
+	      cli_dbgmsg("autoit: not enough space for size\n");
709
+	      break;
710
+	    }
711
+	    chars = cli_readint32((char *)&UNP.outputbuf[UNP.cur_input]);
712
+	    dchars = chars*2;
713
+	    UNP.cur_input+=4;
714
+
715
+	    if (UNP.usize < dchars || UNP.cur_input >= UNP.usize-dchars) {
716
+	      UNP.error = 1;
717
+	      cli_dbgmsg("autoit: size too big - needed %d, total %d, avail %d\n", dchars, UNP.usize, UNP.usize - UNP.cur_input);
718
+	      break;
719
+	    }
720
+	    if (UNP.cur_output+chars+3 >= UNP.csize) {
721
+	      uint8_t *newout;
722
+	      UNP.csize += chars + 512;
723
+	      if (!(newout = cli_realloc(buf, UNP.csize))) {
724
+		UNP.error = 1;
725
+		break;
726
+	      }
727
+	      buf = newout;
728
+	    }
729
+
730
+	    if(prefixes[op-0x30])
731
+	      buf[UNP.cur_output++] = prefixes[op-0x30];
732
+
733
+	    if (chars) {
734
+	      for (i = 0; i<dchars; i+=2) {
735
+		UNP.outputbuf[UNP.cur_input+i] ^= (uint8_t)chars;
736
+		UNP.outputbuf[UNP.cur_input+i+1] ^= (uint8_t)(chars>>8);
737
+	      }
738
+	      u2a(&UNP.outputbuf[UNP.cur_input], dchars);
739
+	      memcpy(&buf[UNP.cur_output], &UNP.outputbuf[UNP.cur_input], chars);
740
+	      UNP.cur_output += chars;
741
+	      UNP.cur_input += dchars;
742
+	    }
743
+	    if (op==0x36)
744
+	      buf[UNP.cur_output++] = '"';
745
+	    if (op!=0x34)
746
+	      buf[UNP.cur_output++] = ' ';
747
+	  }
748
+	  break;
749
+
750
+	case 0x40: /* , */
751
+	case 0x41: /* = */
752
+	case 0x42: /* > */
753
+	case 0x43: /* < */
754
+	case 0x44: /* <> */
755
+	case 0x45: /* >= */
756
+	case 0x46: /* <= */
757
+	case 0x47: /* ( */
758
+	case 0x48: /* ) */
759
+	case 0x49: /* + */
760
+	case 0x4a: /* - */
761
+	case 0x4b: /* / */
762
+	case 0x4c: /* * */
763
+	case 0x4d: /* & */
764
+	case 0x4e: /* [ */
765
+	case 0x4f: /* ] */
766
+	case 0x50: /* == */
767
+	case 0x51: /* ^ */
768
+	case 0x52: /* += */
769
+	case 0x53: /* -= */
770
+	case 0x54: /* /= */
771
+	case 0x55: /* *= */
772
+	case 0x56: /* &= */
773
+	  if (UNP.cur_output+4 >= UNP.csize) {
774
+	    uint8_t *newout;
775
+	    UNP.csize += 512;
776
+	    if (!(newout = cli_realloc(buf, UNP.csize))) {
777
+	      UNP.error = 1;
778
+	      break;
779
+	    }
780
+	    buf = newout;
781
+	  }
782
+	  UNP.cur_output += snprintf((char *)&buf[UNP.cur_output], 4, "%s ", opers[op-0x40]);
783
+	  break;
784
+
785
+	case 0x7f:
786
+	  UNP.bits_avail--;
787
+	  if (UNP.cur_output+1 >= UNP.csize) {
788
+	    uint8_t *newout;
789
+	    UNP.csize += 512;
790
+	    if (!(newout = cli_realloc(buf, UNP.csize))) {
791
+	      UNP.error = 1;
792
+	      break;
793
+	    }
794
+	    buf = newout;
795
+	  }
796
+	  buf[UNP.cur_output++]='\n';
797
+	  break;
798
+
799
+	default:
800
+	  cli_dbgmsg("autoit: found unknown op (%x)\n", op);
801
+	  UNP.error = 1;
802
+	}
803
+      }
804
+
805
+      if (UNP.error)
806
+	cli_dbgmsg("autoit: decompilation aborted - partial script may exist\n");
807
+
808
+      free(UNP.outputbuf);
809
+    } else {
810
+      buf = UNP.outputbuf;
811
+      UNP.cur_output = UNP.usize ;
812
+    }
813
+
814
+    /* FIXME: TODO send to text notmalization */
815
+
816
+    snprintf(tempfile, 1023, "%s/autoit.%.3u", tmpd, files);
817
+    tempfile[1023]='\0';
818
+    if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
819
+      cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
820
+      free(buf);
821
+      return CL_EIO;
822
+    }
823
+    if(cli_writen(i, buf, UNP.cur_output) != (int32_t)UNP.cur_output) {
824
+      cli_dbgmsg("autoit: cannot write %d bytes\n", UNP.usize);
825
+      close(i);
826
+      free(buf);
827
+      return CL_EIO;
828
+    }
829
+    free(buf);
830
+    if(cli_leavetemps_flag)
831
+      cli_dbgmsg("autoit: %s extracted to %s\n", (script)?"script":"file", tempfile);
832
+    else 
833
+      cli_dbgmsg("autoit: %s successfully extracted\n", (script)?"script":"file");
834
+    fsync(i);
835
+    lseek(i, 0, SEEK_SET);
836
+    if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
837
+      close(i);
838
+      if(!cli_leavetemps_flag) unlink(tempfile);
839
+      return CL_VIRUS;
840
+    }
841
+    close(i);
842
+    if(!cli_leavetemps_flag) unlink(tempfile);
843
+  }
844
+  cli_dbgmsg("autoit: Files limit reached (max: %u)\n", ctx->limits->maxfiles);
845
+  return CL_EMAXFILES;
846
+}
847
+
848
+#endif /* FPU_WORDS_BIGENDIAN */
849
+
850
+/*********************
851
+   autoit3 wrapper 
852
+*********************/
853
+
854
+int cli_scanautoit(int desc, cli_ctx *ctx, off_t offset) {
855
+  uint8_t version;
856
+  int (*func)(int desc, cli_ctx *ctx, char *), r;
857
+  char *tmpd;
858
+
859
+  lseek(desc, offset, SEEK_SET);
860
+  if (cli_readn(desc, &version, 1)!=1)
861
+    return CL_EIO;
862
+
863
+  cli_dbgmsg("in scanautoit()\n");
864
+
865
+  if (!(tmpd = cli_gentemp(NULL)))    
866
+    return CL_ETMPDIR;
867
+  if (mkdir(tmpd, 0700)) {
868
+    cli_dbgmsg("autoit: Can't create temporary directory %s\n", tmpd);
869
+    free(tmpd);
870
+    return CL_ETMPDIR;
871
+  }
872
+  if (cli_leavetemps_flag)
873
+    cli_dbgmsg("autoit: Extracting files to %s\n", tmpd);
874
+
875
+  switch(version) {
876
+  case 0x35:
877
+    func = ea05;
878
+    break;
879
+  case 0x36:
880
+#ifdef FPU_WORDS_BIGENDIAN
881
+    func = ea06;
882
+    break;
883
+#else
884
+    cli_dbgmsg("autoit: EA06 support not available\n");
885
+    return CL_CLEAN;
886
+#endif
887
+  default:
888
+    /* NOT REACHED */
889
+    cli_dbgmsg("autoit: unknown method\n");
890
+    return CL_CLEAN;
891
+  }
892
+
893
+  r = func(desc, ctx, tmpd);
894
+
895
+  if (!cli_leavetemps_flag)
896
+    cli_rmdirs(tmpd);
897
+
898
+  free(tmpd);
899
+  return r;
900
+}
0 901
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+/*
1
+ *  Copyright (C) 2007 Sourcefire Inc.
2
+ *  Author: aCaB <acab@clamav.net>
3
+ *
4
+ *  This program is free software; you can redistribute it and/or modify
5
+ *  it under the terms of the GNU General Public License version 2 as
6
+ *  published by the Free Software Foundation.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+ *  MA 02110-1301, USA.
17
+ */
18
+
19
+#ifndef __AUTOIT_H
20
+#define __AUTOIT_H
21
+
22
+#include "others.h"
23
+int cli_scanautoit(int desc, cli_ctx *ctx, off_t offset);
24
+#endif
... ...
@@ -195,6 +195,7 @@ static const struct cli_smagic_s cli_smagic[] = {
195 195
     {"60ea{7}0102", "ARJ-SFX", CL_TYPE_ARJSFX},
196 196
     {"60ea{7}0202", "ARJ-SFX", CL_TYPE_ARJSFX},
197 197
     {"efbeadde4e756c6c736f6674496e7374", "NSIS", CL_TYPE_NULSFT},
198
+    {"a3484bbe986c4aa9994c530a86d6487d41553321454130(35|36)", "AUTOIT", CL_TYPE_AUTOIT},
198 199
 
199 200
     {"4d5a{60-300}50450000", "PE", CL_TYPE_MSEXE},
200 201
 
... ...
@@ -64,7 +64,8 @@ typedef enum {
64 64
     CL_TYPE_RARSFX, /* on the fly */
65 65
     CL_TYPE_CABSFX,
66 66
     CL_TYPE_ARJSFX,
67
-    CL_TYPE_NULSFT /* on the fly */
67
+    CL_TYPE_NULSFT, /* on the fly */
68
+    CL_TYPE_AUTOIT /* FIXME_AUTOIT: Tomasz, good nuff? */
68 69
 } cli_file_t;
69 70
 
70 71
 struct cli_matched_type {
... ...
@@ -85,6 +85,7 @@
85 85
 #include "rtf.h"
86 86
 #include "unarj.h"
87 87
 #include "nulsft.h"
88
+#include "autoit.h"
88 89
 
89 90
 #ifdef HAVE_ZLIB_H
90 91
 #include <zlib.h>
... ...
@@ -1927,6 +1928,13 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg)
1927 1927
 			}
1928 1928
 			break;
1929 1929
 
1930
+		    case CL_TYPE_AUTOIT:
1931
+		        if(1 && type == CL_TYPE_MSEXE /* FIXME_AUTOIT: Tomasz, pls DCONF THIS */) {
1932
+			    cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset);
1933
+			    nret = cli_scanautoit(desc, ctx, fpt->offset + 23);
1934
+			}
1935
+			break;
1936
+
1930 1937
 		    case CL_TYPE_MSEXE:
1931 1938
 			if(SCAN_PE && ctx->dconf->pe && fpt->offset) {
1932 1939
 			    cli_dbgmsg("PE signature found at %u\n", (unsigned int) fpt->offset);
... ...
@@ -2086,6 +2094,11 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2086 2086
 	    if(SCAN_ARCHIVE)
2087 2087
 		ret = cli_scannulsft(desc, ctx, 0);
2088 2088
 	    break;
2089
+
2090
+        case CL_TYPE_AUTOIT:
2091
+	    if(1 /* FIXME_AUTOIT: DCONF THIS */)
2092
+		ret = cli_scanautoit(desc, ctx, 23);
2093
+	    break;
2089 2094
 /*
2090 2095
 	case CL_TYPE_MSSZDD:
2091 2096
 	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SZDD))