git-svn: trunk@3340
aCaB authored on 2007/10/31 03:53:25... | ... |
@@ -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 |
+ |
... | ... |
@@ -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 |
|
... | ... |
@@ -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)) |