Browse code

General "tidy" and some algo hacks. Old and inefficient sue cryptor replaced with a signature.

git-svn: trunk@3202

aCaB authored on 2007/09/04 09:38:30
Showing 6 changed files
... ...
@@ -1,3 +1,8 @@
1
+Tue Sep  4 01:31:23 CEST 2007 (acab)
2
+------------------------------------
3
+  * libclamav:pe.c  General "tidy" and some algo hacks. Old and inefficient
4
+  			sue cryptor replaced with a signature.
5
+
1 6
 Sun Sep  2 12:41:46 BST 2007 (njh)
2 7
 ----------------------------------
3 8
   * clamav-milter:	Fix compilation error from fix to bug 577
... ...
@@ -86,8 +86,6 @@ libclamav_la_SOURCES = \
86 86
 	petite.h \
87 87
 	wwunpack.c \
88 88
 	wwunpack.h \
89
-	suecrypt.c \
90
-	suecrypt.h \
91 89
 	unsp.c \
92 90
 	unsp.h \
93 91
 	aspack.c \
... ...
@@ -82,12 +82,12 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher-ncore.lo \
82 82
 	scanners.lo filetypes.lo rtf.lo blob.lo mbox.lo message.lo \
83 83
 	snprintf.lo table.lo text.lo ole2_extract.lo vba_extract.lo \
84 84
 	msexpand.lo pe.lo upx.lo htmlnorm.lo chmunpack.lo rebuildpe.lo \
85
-	petite.lo wwunpack.lo suecrypt.lo unsp.lo aspack.lo \
86
-	packlibs.lo fsg.lo mew.lo upack.lo line.lo untar.lo unzip.lo \
87
-	special.lo binhex.lo is_tar.lo tnef.lo unrar15.lo unrarvm.lo \
88
-	unrar.lo unrarfilter.lo unrarppm.lo unrar20.lo unrarcmd.lo \
89
-	unarj.lo LZMADecode.lo bzlib.lo infblock.lo nulsft.lo pdf.lo \
90
-	spin.lo yc.lo elf.lo sis.lo uuencode.lo pst.lo phishcheck.lo \
85
+	petite.lo wwunpack.lo unsp.lo aspack.lo packlibs.lo fsg.lo \
86
+	mew.lo upack.lo line.lo untar.lo unzip.lo special.lo binhex.lo \
87
+	is_tar.lo tnef.lo unrar15.lo unrarvm.lo unrar.lo \
88
+	unrarfilter.lo unrarppm.lo unrar20.lo unrarcmd.lo unarj.lo \
89
+	LZMADecode.lo bzlib.lo infblock.lo nulsft.lo pdf.lo spin.lo \
90
+	yc.lo elf.lo sis.lo uuencode.lo pst.lo phishcheck.lo \
91 91
 	phish_domaincheck_db.lo phish_whitelist.lo regex_list.lo \
92 92
 	sha256.lo mspack.lo cab.lo entconv.lo hashtab.lo dconf.lo \
93 93
 	lockdb.lo
... ...
@@ -149,6 +149,7 @@ F77 = @F77@
149 149
 FFLAGS = @FFLAGS@
150 150
 FRESHCLAM_LIBS = @FRESHCLAM_LIBS@
151 151
 GETENT = @GETENT@
152
+GREP = @GREP@
152 153
 HAVE_MILTER_FALSE = @HAVE_MILTER_FALSE@
153 154
 HAVE_MILTER_TRUE = @HAVE_MILTER_TRUE@
154 155
 INSTALL_DATA = @INSTALL_DATA@
... ...
@@ -182,12 +183,9 @@ STRIP = @STRIP@
182 182
 THREAD_LIBS = @THREAD_LIBS@
183 183
 TH_SAFE = @TH_SAFE@
184 184
 VERSION = @VERSION@
185
-ac_ct_AR = @ac_ct_AR@
186 185
 ac_ct_CC = @ac_ct_CC@
187 186
 ac_ct_CXX = @ac_ct_CXX@
188 187
 ac_ct_F77 = @ac_ct_F77@
189
-ac_ct_RANLIB = @ac_ct_RANLIB@
190
-ac_ct_STRIP = @ac_ct_STRIP@
191 188
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
192 189
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
193 190
 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
... ...
@@ -204,23 +202,30 @@ build_cpu = @build_cpu@
204 204
 build_os = @build_os@
205 205
 build_vendor = @build_vendor@
206 206
 datadir = @datadir@
207
+datarootdir = @datarootdir@
208
+docdir = @docdir@
209
+dvidir = @dvidir@
207 210
 exec_prefix = @exec_prefix@
208 211
 host = @host@
209 212
 host_alias = @host_alias@
210 213
 host_cpu = @host_cpu@
211 214
 host_os = @host_os@
212 215
 host_vendor = @host_vendor@
216
+htmldir = @htmldir@
213 217
 includedir = @includedir@
214 218
 infodir = @infodir@
215 219
 install_sh = @install_sh@
216 220
 libdir = @libdir@
217 221
 libexecdir = @libexecdir@
222
+localedir = @localedir@
218 223
 localstatedir = @localstatedir@
219 224
 mandir = @mandir@
220 225
 mkdir_p = @mkdir_p@
221 226
 oldincludedir = @oldincludedir@
227
+pdfdir = @pdfdir@
222 228
 prefix = @prefix@
223 229
 program_transform_name = @program_transform_name@
230
+psdir = @psdir@
224 231
 sbindir = @sbindir@
225 232
 sendmailprog = @sendmailprog@
226 233
 sharedstatedir = @sharedstatedir@
... ...
@@ -295,8 +300,6 @@ libclamav_la_SOURCES = \
295 295
 	petite.h \
296 296
 	wwunpack.c \
297 297
 	wwunpack.h \
298
-	suecrypt.c \
299
-	suecrypt.h \
300 298
 	unsp.c \
301 299
 	unsp.h \
302 300
 	aspack.c \
... ...
@@ -513,7 +516,6 @@ distclean-compile:
513 513
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/special.Plo@am__quote@
514 514
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spin.Plo@am__quote@
515 515
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@
516
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/suecrypt.Plo@am__quote@
517 516
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Plo@am__quote@
518 517
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text.Plo@am__quote@
519 518
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnef.Plo@am__quote@
... ...
@@ -55,8 +55,6 @@ static struct dconf_module modules[] = {
55 55
     { "PE",	    "UPX",	    PE_CONF_UPX,	    1 },
56 56
     { "PE",	    "FSG",	    PE_CONF_FSG,	    1 },
57 57
 
58
-    { "PE",	    "SUE",	    PE_CONF_SUE,	    1 },
59
-
60 58
     { "PE",	    "PETITE",	    PE_CONF_PETITE,	    1 },
61 59
     { "PE",	    "PESPIN",	    PE_CONF_PESPIN,	    1 },
62 60
     { "PE",	    "YC",	    PE_CONF_YC,		    1 },
... ...
@@ -42,7 +42,7 @@ struct cli_dconf {
42 42
 #define PE_CONF_MD5SECT	    0x10
43 43
 #define PE_CONF_UPX	    0x20
44 44
 #define PE_CONF_FSG	    0x40
45
-#define PE_CONF_SUE	    0x80
45
+/*#define PE_CONF_REUSEME	    0x80 */
46 46
 #define PE_CONF_PETITE	    0x100
47 47
 #define PE_CONF_PESPIN	    0x200
48 48
 #define PE_CONF_YC	    0x400
... ...
@@ -32,6 +32,7 @@
32 32
 #include <unistd.h>
33 33
 #endif
34 34
 #include <time.h>
35
+#include <stdarg.h>
35 36
 
36 37
 #include "cltypes.h"
37 38
 #include "clamav.h"
... ...
@@ -44,7 +45,6 @@
44 44
 #include "yc.h"
45 45
 #include "aspack.h"
46 46
 #include "wwunpack.h"
47
-#include "suecrypt.h"
48 47
 #include "unsp.h"
49 48
 #include "scanners.h"
50 49
 #include "str.h"
... ...
@@ -80,19 +80,114 @@
80 80
 #define PEALIGN(o,a) (((a))?(((o)/(a))*(a)):(o))
81 81
 #define PESALIGN(o,a) (((a))?(((o)/(a)+((o)%(a)!=0))*(a)):(o))
82 82
 
83
+#define CLI_UNPSIZELIMITS(NAME,CHK) \
84
+if(ctx->limits && ctx->limits->maxfilesize && (CHK) > ctx->limits->maxfilesize) { \
85
+    cli_dbgmsg(NAME": Sizes exceeded (%lu > %lu)\n", (CHK), ctx->limits->maxfilesize); \
86
+    free(exe_sections); \
87
+    if(BLOCKMAX) { \
88
+        *ctx->virname = "PE."NAME".ExceededFileSize"; \
89
+        return CL_VIRUS; \
90
+    } else { \
91
+        return CL_CLEAN; \
92
+    } \
93
+}
94
+
95
+#define CLI_UNPTEMP(NAME,...) \
96
+if(!(tempfile = cli_gentemp(NULL))) { \
97
+    cli_multifree(__VA_ARGS__,0); \
98
+    return CL_EMEM; \
99
+} \
100
+if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { \
101
+    cli_dbgmsg(NAME": Can't create file %s\n", tempfile); \
102
+    cli_multifree(tempfile,__VA_ARGS__,0); \
103
+    return CL_EIO; \
104
+}
105
+
106
+#define CLI_TMPUNLK() if(!cli_leavetemps_flag) unlink(tempfile)
107
+
108
+#define FSGCASE(NAME,FREESEC) \
109
+    case 0: /* Unpacked and NOT rebuilt */ \
110
+	cli_dbgmsg(NAME": Successfully decompressed\n"); \
111
+	close(ndesc); \
112
+	unlink(tempfile); \
113
+	free(tempfile); \
114
+	FREESEC; \
115
+	found = 0; \
116
+	upx_success = 1; \
117
+	break; /* FSG ONLY! - scan raw data after upx block */
118
+
119
+#define SPINCASE() \
120
+    case 2: \
121
+	free(spinned); \
122
+	close(ndesc); \
123
+	unlink(tempfile); \
124
+	cli_dbgmsg("PESpin: Size exceeded\n"); \
125
+	if(BLOCKMAX) { \
126
+	    free(tempfile); \
127
+	    free(exe_sections); \
128
+	    *ctx->virname = "PE.Pespin.ExceededFileSize"; \
129
+	    return CL_VIRUS; \
130
+	} \
131
+	free(tempfile); \
132
+	break; \
133
+
134
+#define CLI_UNPRESULTS_(NAME,FSGSTUFF,EXPR,GOOD,...) \
135
+    switch(EXPR) { \
136
+    case GOOD: /* Unpacked and rebuilt */ \
137
+	if(cli_leavetemps_flag) \
138
+	    cli_dbgmsg(NAME": Unpacked and rebuilt executable saved in %s\n", tempfile); \
139
+	else \
140
+	    cli_dbgmsg(NAME": Unpacked and rebuilt executable\n"); \
141
+	cli_multifree(__VA_ARGS__,exe_sections,0); \
142
+	fsync(ndesc); \
143
+	lseek(ndesc, 0, SEEK_SET); \
144
+	cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); \
145
+	if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { \
146
+	    close(ndesc); \
147
+	    CLI_TMPUNLK(); \
148
+	    free(tempfile); \
149
+	    return CL_VIRUS; \
150
+	} \
151
+	close(ndesc); \
152
+	CLI_TMPUNLK(); \
153
+	free(tempfile); \
154
+	return CL_CLEAN; \
155
+\
156
+FSGSTUFF \
157
+\
158
+    default: \
159
+	cli_dbgmsg(NAME": Unpacking failed\n"); \
160
+	close(ndesc); \
161
+	unlink(tempfile); \
162
+	cli_multifree(__VA_ARGS__,tempfile,0); \
163
+    }
164
+
165
+
166
+#define CLI_UNPRESULTS(NAME,EXPR,GOOD,...) CLI_UNPRESULTS_(NAME,,EXPR,GOOD,__VA_ARGS__)
167
+#define CLI_UNPRESULTSFSG1(NAME,EXPR,GOOD,...) CLI_UNPRESULTS_(NAME,FSGCASE(NAME,free(sections)),EXPR,GOOD,__VA_ARGS__)
168
+#define CLI_UNPRESULTSFSG2(NAME,EXPR,GOOD,...) CLI_UNPRESULTS_(NAME,FSGCASE(NAME,),EXPR,GOOD,__VA_ARGS__)
83 169
 
84 170
 struct offset_list {
85 171
     uint32_t offset;
86 172
     struct offset_list *next;
87 173
 };
88 174
 
175
+static void cli_multifree(void *f, ...) {
176
+    void *ff;
177
+    va_list ap;
178
+    free(f);
179
+    va_start(ap, f);
180
+    while((ff=va_arg(ap, void*))) free(ff);
181
+    va_end(ap);
182
+}
183
+
89 184
 static uint32_t cli_rawaddr(uint32_t rva, struct cli_exe_section *shp, uint16_t nos, unsigned int *err,	size_t fsize, uint32_t hdr_size)
90 185
 {
91
-	int i, found = 0;
92
-	uint32_t ret;
186
+    int i, found = 0;
187
+    uint32_t ret;
93 188
 
94 189
     if (rva<hdr_size) { /* Out of section EP - mapped to imagebase+rva */
95
-        if (rva >= fsize) {
190
+	if (rva >= fsize) {
96 191
 	    *err=1;
97 192
 	    return 0;
98 193
 	}
... ...
@@ -117,33 +212,9 @@ static uint32_t cli_rawaddr(uint32_t rva, struct cli_exe_section *shp, uint16_t
117 117
     return ret;
118 118
 }
119 119
 
120
-static void xckriz(char **opcode, int *len, int checksize, int reg) {
121
-    while(*len>6) {
122
-        if (**opcode>='\x48' && **opcode<='\x4f' && **opcode!='\x4c') {
123
-	    if ((char)(**opcode-reg)=='\x48') break;
124
-	    (*len)--;
125
-	    (*opcode)++;
126
-	    continue;
127
-	}
128
-	if (**opcode>='\xb8' && **opcode<='\xbf' && **opcode!='\xbc') {
129
-	    if (checksize && cli_readint32(*opcode+1)==0x0fd2) break;
130
-	    (*len)-=5;
131
-	    (*opcode)+=5;
132
-	    continue;
133
-	}
134
-	if (**opcode=='\x81') {
135
-	    (*len)-=6;
136
-	    (*opcode)+=6;
137
-	    continue;
138
-	}
139
-	break;
140
-    }
141
-}
142
-
143 120
 
144 121
 /*
145
-static int cli_ddump(int desc, int offset, int size, const char *file)
146
-{
122
+static int cli_ddump(int desc, int offset, int size, const char *file) {
147 123
 	int pos, ndesc, bread, sum = 0;
148 124
 	char buff[FILEBUFF];
149 125
 
... ...
@@ -195,39 +266,40 @@ static int cli_ddump(int desc, int offset, int size, const char *file)
195 195
 }
196 196
 */
197 197
 
198
-static unsigned int cli_md5sect(int fd, uint32_t offset, uint32_t size, unsigned char *digest)
199
-{
200
-	size_t bread, sum = 0;
201
-	off_t pos;
202
-	char buff[FILEBUFF];
203
-	cli_md5_ctx md5ctx;
198
+static off_t cli_seeksect(int fd, struct cli_exe_section *s) {
199
+    off_t ret;
204 200
 
201
+    if(!s->rsz) return 0;
202
+    if((ret=lseek(fd, s->raw, SEEK_SET)) == -1)
203
+	cli_dbgmsg("cli_seeksect: lseek() failed\n");
204
+    return ret+1;
205
+}
206
+
207
+static unsigned int cli_md5sect(int fd, struct cli_exe_section *s, unsigned char *digest) {
208
+    void *hashme;
209
+    cli_md5_ctx md5;
205 210
 
206
-    if((pos = lseek(fd, 0, SEEK_CUR)) == -1) {
207
-	cli_dbgmsg("cli_md5sect: Invalid descriptor %d\n", fd);
211
+    if (s->rsz > CLI_MAX_ALLOCATION) {
212
+	cli_dbgmsg("cli_md5sect: skipping md5 calculation for too big section\n");
208 213
 	return 0;
209 214
     }
210 215
 
211
-    if(lseek(fd, offset, SEEK_SET) == -1) {
212
-	cli_dbgmsg("cli_md5sect: lseek() failed\n");
213
-	lseek(fd, pos, SEEK_SET);
216
+    if(!cli_seeksect(fd, s)) return 0;
217
+
218
+    if(!(hashme=cli_malloc(s->rsz))) {
219
+	cli_dbgmsg("cli_md5sect: out of memory\n");
214 220
 	return 0;
215 221
     }
216 222
 
217
-    cli_md5_init(&md5ctx);
218
-
219
-    while((bread = cli_readn(fd, buff, FILEBUFF)) > 0) {
220
-	if(sum + bread >= size) {
221
-	    cli_md5_update(&md5ctx, buff, size - sum);
222
-	    break;
223
-	} else {
224
-	    cli_md5_update(&md5ctx, buff, bread);
225
-	    sum += bread;
226
-	}
223
+    if(cli_readn(fd, hashme, s->rsz)!=s->rsz) {
224
+	cli_dbgmsg("cli_md5sect: unable to read section data\n");
225
+	return 0;
227 226
     }
228 227
 
229
-    cli_md5_final(digest, &md5ctx);
230
-    lseek(fd, pos, SEEK_SET);
228
+    cli_md5_init(&md5);
229
+    cli_md5_update(&md5, hashme, s->rsz);
230
+    free(hashme);
231
+    cli_md5_final(digest, &md5);
231 232
     return 1;
232 233
 }
233 234
 
... ...
@@ -246,7 +318,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
246 246
 	} pe_opt;
247 247
 	struct pe_image_section_hdr *section_hdr;
248 248
 	struct stat sb;
249
-	char sname[9], buff[4096], *tempfile;
249
+	char sname[9], buff[4096], epbuff[4096], *tempfile;
250
+	uint32_t epsize;
250 251
 	unsigned char *ubuff;
251 252
 	ssize_t bytes;
252 253
 	unsigned int i, found, upx_success = 0, min = 0, max = 0, err;
... ...
@@ -317,6 +390,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
317 317
     switch(EC16(file_hdr.Machine)) {
318 318
 	case 0x0:
319 319
 	    cli_dbgmsg("Machine type: Unknown\n");
320
+	    break;
320 321
 	case 0x14c:
321 322
 	    cli_dbgmsg("Machine type: 80386\n");
322 323
 	    break;
... ...
@@ -700,7 +774,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
700 700
 	}
701 701
 
702 702
 	if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
703
-	    unsigned char md5_dig[16];
704 703
 	    if (exe_sections[i].raw >= fsize) { /* really broken */
705 704
 	        cli_dbgmsg("Broken PE file - Section %d starts beyond the end of file (Offset@ %d, Total filesize %d)\n", i, exe_sections[i].raw, fsize);
706 705
 		free(section_hdr);
... ...
@@ -713,26 +786,21 @@ int cli_scanpe(int desc, cli_ctx *ctx)
713 713
 		return CL_CLEAN; /* no ninjas to see here! move along! */
714 714
 	    }
715 715
 
716
+	    if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
717
+
716 718
 	    /* check MD5 section sigs */
717 719
 	    md5_sect = ctx->engine->md5_sect;
718 720
 	    if((DCONF & PE_CONF_MD5SECT) && md5_sect) {
719 721
 		found = 0;
720 722
 		for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) {
721 723
 		    if(md5_sect->soff[j] == exe_sections[i].rsz) {
722
-			found = 1;
723
-			break;
724
-		    }
725
-		}
726
-
727
-		if(found) {
728
-		    if(!cli_md5sect(desc, exe_sections[i].raw, exe_sections[i].rsz, md5_dig)) {
729
-			cli_errmsg("PE: Can't calculate MD5 for section %u\n", i);
730
-		    } else {
731
-			if(cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_sect, 0, 0, -1) == CL_VIRUS) {
732
-			    free(section_hdr);
733
-			    free(exe_sections);
734
-			    return CL_VIRUS;
724
+			unsigned char md5_dig[16];
725
+			if(cli_md5sect(desc, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_sect, 0, 0, -1) == CL_VIRUS) {
726
+				free(section_hdr);
727
+				free(exe_sections);
728
+				return CL_VIRUS;
735 729
 			}
730
+			break;
736 731
 		    }
737 732
 		}
738 733
 	    }
... ...
@@ -764,15 +832,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
764 764
 	    if(exe_sections[i].rva + exe_sections[i].rsz > max)
765 765
 	        max = exe_sections[i].rva + exe_sections[i].rsz;
766 766
 	}
767
-
768
-	if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !strlen(sname)) {
769
-	    if(exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000) {
770
-		if(exe_sections[i].chr == 0xe0000060) {
771
-		    polipos = i;
772
-		}
773
-	    }
774
-	}
775
-
776 767
     }
777 768
 
778 769
     free(section_hdr);
... ...
@@ -795,91 +854,113 @@ int cli_scanpe(int desc, cli_ctx *ctx)
795 795
 	return CL_CLEAN;
796 796
     }
797 797
 
798
+    lseek(desc, ep, SEEK_SET);
799
+    epsize = cli_readn(desc, epbuff, 4096);
798 800
 
799 801
     /* Attempt to detect some popular polymorphic viruses */
800 802
 
801 803
     /* W32.Parite.B */
802
-    if(SCAN_ALGO && (DCONF & PE_CONF_PARITE) && !dll && ep == exe_sections[nsections - 1].raw) {
803
-	lseek(desc, ep, SEEK_SET);
804
-	if(cli_readn(desc, buff, 4096) == 4096) {
805
-		const char *pt = cli_memstr(buff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
806
-	    if(pt) {
807
-		    uint32_t dw1, dw2;
808
-
809
-		pt += 15;
810
-		if(((dw1 = cli_readint32(pt)) ^ (dw2 = cli_readint32(pt + 4))) == 0x505a4f && ((dw1 = cli_readint32(pt + 8)) ^ (dw2 = cli_readint32(pt + 12))) == 0xffffb && ((dw1 = cli_readint32(pt + 16)) ^ (dw2 = cli_readint32(pt + 20))) == 0xb8) {
811
-		    *ctx->virname = "W32.Parite.B";
812
-		    free(exe_sections);
813
-		    return CL_VIRUS;
814
-		}
804
+    if(SCAN_ALGO && (DCONF & PE_CONF_PARITE) && !dll && epsize == 4096 && ep == exe_sections[nsections - 1].raw) {
805
+        const char *pt = cli_memstr(epbuff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
806
+	if(pt) {
807
+	    pt += 15;
808
+	    if( (uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4) == 0x505a4f && (uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12) == 0xffffb && (uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20) == 0xb8) {
809
+	        *ctx->virname = "W32.Parite.B";
810
+		free(exe_sections);
811
+		return CL_VIRUS;
815 812
 	    }
816 813
 	}
817 814
     }
818 815
 
819 816
     /* Kriz */
820
-    if(SCAN_ALGO && (DCONF & PE_CONF_KRIZ) && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2)) {
817
+    if(SCAN_ALGO && (DCONF & PE_CONF_KRIZ) && epsize >= 200 && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2) && epbuff[1]=='\x9c' || epbuff[2]=='\x60') {
818
+	enum {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSXORPRFX,KZSXOR,KZSDDELTA,KZSLOOP,KZSTOP};
819
+	uint8_t kzs[] = {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSTRASH,KZSXORPRFX,KZSXOR,KZSTRASH,KZSDDELTA,KZSTRASH,KZSLOOP,KZSTOP};
820
+	uint8_t *kzstate = kzs;
821
+	uint8_t *kzcode = epbuff + 3;
822
+	uint8_t kzdptr=0xff, kzdsize=0xff;
823
+	int kzlen = 197, kzinitlen=0xffff, kzxorlen=-1;
821 824
 	cli_dbgmsg("in kriz\n");
822
-	lseek(desc, ep, SEEK_SET);
823
-	if(cli_readn(desc, buff, 200) == 200) {
824
-	    while (1) {
825
-		char *krizpos=buff+3;
826
-		char *krizmov, *krizxor;
827
-		int krizleft = 200-3;
828
-		int krizrega,krizregb;
829
-
830
-		if (buff[1]!='\x9c' || buff[2]!='\x60') break; /* EP+1 */
831
-		xckriz(&krizpos, &krizleft, 0, 8);
832
-		if (krizleft < 6 || *krizpos!='\xe8' || krizpos[2] || krizpos[3] || krizpos[4]) break; /* call DELTA */
833
-		krizleft-=5+(unsigned char)krizpos[1];
834
-		if (krizleft < 2) break;
835
-		krizpos+=5+(unsigned char)krizpos[1];
836
-		if (*krizpos<'\x58' || *krizpos>'\x5f' || *krizpos=='\x5c') break; /* pop DELTA */
837
-		krizrega=*krizpos-'\x58';
838
-		cli_dbgmsg("kriz: pop delta using %d\n", krizrega);
839
-		krizpos+=1;
840
-		krizleft-=1;
841
-		xckriz(&krizpos, &krizleft, 1, 8);
842
-		if (krizleft <6 || *krizpos<'\xb8' || *krizpos>'\xbf' || *krizpos=='\xbc' || cli_readint32(krizpos+1)!=0x0fd2) break;
843
-		krizregb=*krizpos-'\xb8';
844
-		if (krizrega==krizregb) break;
845
-		cli_dbgmsg("kriz: using %d for size\n", krizregb);
846
-		krizpos+=5;
847
-		krizleft-=5;
848
-		krizmov = krizpos;
849
-		xckriz(&krizpos, &krizleft, 0, 8);
850
-		krizxor=krizpos;
851
-		if (krizleft && *krizpos=='\x3e') {
852
-		    /* strip ds: */
853
-		    krizpos++;
854
-		    krizleft--;
855
-		}
856
-		if (krizleft<8 || *krizpos!='\x80' || (char)(krizpos[1]-krizrega)!='\xb0') {
857
-		    cli_dbgmsg("kriz: bogus opcode or register\n");
825
+
826
+	while(*kzstate!=KZSTOP) {
827
+	    uint8_t op;
828
+	    if(kzlen<=6) break;
829
+	    op = *kzcode++;
830
+	    kzlen--;
831
+	    switch (*kzstate) {
832
+	    case KZSTRASH: case KZSGETSIZE: {
833
+		int opsz=0;
834
+		switch(op) {
835
+		case 0x81:
836
+		    kzcode+=5;
837
+		    kzlen-=5;
858 838
 		    break;
839
+		case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbd: case 0xbe: case 0xbf:
840
+		    if(*kzstate==KZSGETSIZE && cli_readint32(kzcode)==0x0fd2) {
841
+			kzinitlen = kzlen-5;
842
+			kzdsize=op-0xb8;
843
+			kzstate++;
844
+			op=4; /* fake the register to avoid breaking out */
845
+			cli_dbgmsg("kriz: using #%d as size counter\n", kzdsize);
846
+		    }
847
+		    opsz=4;
848
+		case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4d: case 0x4e: case 0x4f:
849
+		    op&=7;
850
+		    if(op!=kzdptr && op!=kzdsize) {
851
+			kzcode+=opsz;
852
+			kzlen-=opsz;
853
+			break;
854
+		    }
855
+		default:
856
+		    kzcode--;
857
+		    kzlen++;
858
+		    kzstate++;
859 859
 		}
860
-		krizpos+=7;
861
-		krizleft-=7;
862
-		xckriz(&krizpos, &krizleft, 0, krizrega);
863
-		if (! krizleft || (char)(*krizpos-krizrega)!='\x48') break; /* dec delta */
864
-		krizpos++;
865
-		krizleft--;
866
-		cli_dbgmsg("kriz: dec delta found\n");
867
-		xckriz(&krizpos, &krizleft, 0, krizregb);
868
-		if (krizleft <4 || (char)(*krizpos-krizregb)!='\x48' || krizpos[1]!='\x75') break; /* dec size + jne loop */
869
-		if (krizpos+3+(int)krizpos[2]<krizmov || krizpos+3+(int)krizpos[2]>krizxor) {
870
-		    cli_dbgmsg("kriz: jmp back out of range (%d>%d>%d)\n", krizmov-(krizpos+3), (int)krizpos[2], krizxor-(krizpos+3));
871
-		    break;
860
+		break;
861
+	    }
862
+	    case KZSCDELTA:
863
+		if(op==0xe8 && (uint32_t)cli_readint32(kzcode) < 0xff) {
864
+		    kzlen-=*kzcode+4;
865
+		    kzcode+=*kzcode+4;
866
+		    kzstate++;
867
+		} else *kzstate=KZSTOP;
868
+		break;
869
+	    case KZSPDELTA:
870
+		if((op&0xf8)==0x58 && (kzdptr=op-0x58)!=4) {
871
+		    kzstate++;
872
+		    cli_dbgmsg("kriz: using #%d as pointer\n", kzdptr);
873
+		} else *kzstate=KZSTOP;
874
+		break;
875
+	    case KZSXORPRFX:
876
+		kzstate++;
877
+		if(op==0x3e) break;
878
+	    case KZSXOR:
879
+		if (op==0x80 && *kzcode==kzdptr+0xb0) {
880
+		    kzxorlen=kzlen;
881
+		    kzcode+=+6;
882
+		    kzlen-=+6;
883
+		    kzstate++;
884
+		} else *kzstate=KZSTOP;
885
+		break;
886
+	    case KZSDDELTA:
887
+		if (op==kzdptr+0x48) kzstate++;
888
+		else *kzstate=KZSTOP;
889
+		break;
890
+	    case KZSLOOP:
891
+		if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
892
+		    *ctx->virname = "W32.Kriz";
893
+		    free(exe_sections);
894
+		    return CL_VIRUS;
872 895
 		}
873
-		*ctx->virname = "Win32.Kriz";
874
-		free(exe_sections);
875
-		return CL_VIRUS;
896
+		cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
897
+		kzstate++;
876 898
 	    }
877 899
 	}
878 900
     }
879 901
 
880 902
     /* W32.Magistr.A/B */
881 903
     if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) {
882
-	    uint32_t rsize, vsize, dam = 0;
904
+        uint32_t rsize, vsize, dam = 0;
883 905
 
884 906
 	vsize = exe_sections[nsections - 1].uvsz;
885 907
 	rsize = exe_sections[nsections - 1].rsz;
... ...
@@ -915,169 +996,64 @@ int cli_scanpe(int desc, cli_ctx *ctx)
915 915
     }
916 916
 
917 917
     /* W32.Polipos.A */
918
-   if(polipos && !dll && nsections > 2 && nsections < 13 && e_lfanew <= 0x800 && (EC16(optional_hdr32.Subsystem) == 2 || EC16(optional_hdr32.Subsystem) == 3) && EC16(file_hdr.Machine) == 0x14c && optional_hdr32.SizeOfStackReserve >= 0x80000) {
919
-		uint32_t remaining = exe_sections[0].rsz;
920
-		uint32_t chunk = sizeof(buff);
921
-		uint32_t val, shift, raddr, total = 0;
922
-		const char *jpt;
923
-		struct offset_list *offlist = NULL, *offnode;
924
-
925
-
926
-	cli_dbgmsg("Detected W32.Polipos.A characteristics\n");
927
-
928
-	if(remaining < chunk)
929
-	    chunk = remaining;
930
-
931
-	lseek(desc, exe_sections[0].raw, SEEK_SET);
932
-	while((bytes = cli_readn(desc, buff, chunk)) > 0) {
933
-	    shift = 0;
934
-	    while((uint32_t)bytes - 5 > shift) {
935
-		jpt = buff + shift;
936
-		if(*jpt!='\xe9' && *jpt!='\xe8') {
937
-		    shift++;
938
-		    continue;
939
-		}
940
-		val = cli_readint32(jpt + 1);
941
-		val += 5 + exe_sections[0].rva + total + shift;
942
-		raddr = cli_rawaddr(val, exe_sections, nsections, &err, fsize, hdr_size);
943
-
944
-		if(!err && (raddr >= exe_sections[polipos].raw && raddr < exe_sections[polipos].raw + exe_sections[polipos].rsz) && (!offlist || (raddr != offlist->offset))) {
945
-		    offnode = (struct offset_list *) cli_malloc(sizeof(struct offset_list));
946
-		    if(!offnode) {
947
-			free(exe_sections);
948
-			while(offlist) {
949
-			    offnode = offlist;
950
-			    offlist = offlist->next;
951
-			    free(offnode);
952
-			}
953
-			return CL_EMEM;
954
-		    }
955
-		    offnode->offset = raddr;
956
-		    offnode->next = offlist;
957
-		    offlist = offnode;
958
-		}
959
-
960
-		shift++;
961
-	    }
962
-
963
-	    if(remaining < chunk) {
964
-		chunk = remaining;
965
-	    } else {
966
-		remaining -= bytes;
967
-		if(remaining < chunk) {
968
-		    chunk = remaining;
918
+    while(polipos && !dll && nsections > 2 && nsections < 13 && e_lfanew <= 0x800 && (EC16(optional_hdr32.Subsystem) == 2 || EC16(optional_hdr32.Subsystem) == 3) && EC16(file_hdr.Machine) == 0x14c && optional_hdr32.SizeOfStackReserve >= 0x80000) {
919
+	uint32_t jump, jold, *jumps = NULL;
920
+	uint8_t *code;
921
+	unsigned int xsjs = 0;
922
+
923
+	if(exe_sections[0].rsz > CLI_MAX_ALLOCATION) break;
924
+	if(!cli_seeksect(desc, &exe_sections[0])) break;
925
+	if(!(code=cli_malloc(exe_sections[0].rsz))) {
926
+	    free(exe_sections);
927
+	    return CL_EMEM;
928
+	}
929
+	if(cli_readn(desc, code, exe_sections[0].rsz)!=exe_sections[0].rsz) {
930
+	    free(exe_sections);
931
+	    return CL_EIO;
932
+	}
933
+	for(i=0; i<exe_sections[0].rsz - 5; i++) {
934
+	    if((uint8_t)(code[i]-0xe8) > 1) continue;
935
+	    jump = cli_rawaddr(exe_sections[0].rva+i+5+cli_readint32(&code[i+1]), exe_sections, nsections, &err, fsize, hdr_size);
936
+	    if(err || !CLI_ISCONTAINED(exe_sections[polipos].raw, exe_sections[polipos].rsz, jump, 9)) continue;
937
+	    if(xsjs % 128 == 0) {
938
+		if(xsjs == 1280) break;
939
+		if(!(jumps=(uint32_t *)cli_realloc2(jumps, (xsjs+128)*sizeof(uint32_t)))) {
940
+		    free(code);
941
+		    free(exe_sections);
942
+		    return CL_EMEM;
969 943
 		}
970 944
 	    }
971
-
972
-	    if(!remaining)
973
-		break;
974
-
975
-	    total += bytes;
976
-	}
977
-
978
-	offnode = offlist;
979
-	while(offnode) {
980
-	    cli_dbgmsg("Polipos: Checking offset 0x%x (%u)", offnode->offset, offnode->offset);
981
-	    lseek(desc, offnode->offset, SEEK_SET);
982
-	    if(cli_readn(desc, buff, 9) == 9) {
983
-		ubuff = (unsigned char *) buff;
984
-		if(ubuff[0] == 0x55 && ubuff[1] == 0x8b && ubuff[2] == 0xec &&
985
-		   ((ubuff[3] == 0x83 && ubuff[4] == 0xec && ubuff[6] == 0x60) ||  ubuff[3] == 0x60 ||
986
-		     (ubuff[3] == 0x81 && ubuff[4] == 0xec && ubuff[7] == 0x00 && ubuff[8] == 0x00))) {
987
-		    ret = CL_VIRUS;
988
-		    *ctx->virname = "W32.Polipos.A";
945
+	    j=0;
946
+	    for(; j<xsjs; j++) {
947
+		if(jumps[j]<jump) continue;
948
+		if(jumps[j]==jump) {
949
+		    xsjs--;
989 950
 		    break;
990 951
 		}
952
+		jold=jumps[j];
953
+		jumps[j]=jump;
954
+		jump=jold;
955
+	    }
956
+	    jumps[j]=jump;
957
+	    xsjs++;
958
+	}
959
+	free(code);
960
+	if(!xsjs) break;
961
+	cli_dbgmsg("Polipos: Checking %d xsect jump(s)\n", xsjs);
962
+	for(i=0;i<xsjs;i++) {
963
+	    lseek(desc, jumps[i], SEEK_SET);
964
+	    if(cli_readn(desc, buff, 9) != 9) continue;
965
+	    if((jump=cli_readint32(buff))==0x60ec8b55 || (buff[4]=='\xec' && ((jump==0x83ec8b55 && buff[6]=='\x60') || (jump==0x81ec8b55 && !buff[7] && !buff[8])))) {
966
+		*ctx->virname = "W32.Polipos.A";
967
+		free(jumps);
968
+		free(exe_sections);
969
+		return CL_VIRUS;
991 970
 	    }
992
-
993
-	    offnode = offnode->next;
994
-	}
995
-
996
-	while(offlist) {
997
-	    offnode = offlist;
998
-	    offlist = offlist->next;
999
-	    free(offnode);
1000
-	}
1001
-
1002
-	if(ret == CL_VIRUS) {
1003
-	    free(exe_sections);
1004
-	    return CL_VIRUS;
1005 971
 	}
972
+	free(jumps);
973
+	break;
1006 974
     }
1007 975
 
1008
-    /* SUE */
1009
-    
1010
-    if((DCONF & PE_CONF_SUE) && nsections > 2 && vep == exe_sections[nsections - 1].rva && exe_sections[nsections - 1].rsz > 0x350 && exe_sections[nsections - 1].rsz < 0x292+0x350+1000) {
1011
-  
1012
-      
1013
-      char *sue=buff+0x74;
1014
-      uint32_t key = 0;
1015
-      
1016
-      if(lseek(desc, ep-4, SEEK_SET) == -1) {
1017
-	cli_dbgmsg("SUE: lseek() failed\n");
1018
-	free(exe_sections);
1019
-	return CL_EIO;
1020
-      }
1021
-      if((unsigned int) cli_readn(desc, buff, exe_sections[nsections - 1].rsz+4) == exe_sections[nsections - 1].rsz+4) {
1022
-	found=0;
1023
-	while(CLI_ISCONTAINED(buff+4, exe_sections[nsections - 1].rsz, sue, 4*3)) {
1024
-	  if((cli_readint32(sue)^cli_readint32(sue+4))==0x5c41090e && (cli_readint32(sue)^cli_readint32(sue+8))==0x021e0145) {
1025
-	    found=1;
1026
-	    key=(cli_readint32(sue)^0x6e72656b);
1027
-	    break;
1028
-	  }
1029
-	  sue++;
1030
-	}
1031
-	cli_dbgmsg("SUE: key(%x) found @%x\n", key, sue-buff);
1032
-	if (found && CLI_ISCONTAINED(buff, exe_sections[nsections - 1].rsz, sue-0x74, 0xbe) &&
1033
-	    (sue=sudecrypt(desc, fsize, exe_sections, nsections-1, sue, key, cli_readint32(buff), e_lfanew))) {
1034
-	  if(!(tempfile = cli_gentemp(NULL))) {
1035
-	    free(sue);
1036
-	    free(exe_sections);
1037
-	    return CL_EMEM;
1038
-	  }
1039
-
1040
-	  if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1041
-	    cli_dbgmsg("sue: Can't create file %s\n", tempfile);
1042
-	    free(tempfile);
1043
-	    free(sue);
1044
-	    free(exe_sections);
1045
-	    return CL_EIO;
1046
-	  }
1047
-	  
1048
-	  if((unsigned int) cli_writen(ndesc, sue, ep) != ep) {
1049
-	    cli_dbgmsg("sue: Can't write %d bytes\n", ep);
1050
-	    close(ndesc);
1051
-	    free(tempfile);
1052
-	    free(sue);
1053
-	    free(exe_sections);
1054
-	    return CL_EIO;
1055
-	  }
1056
-
1057
-	  free(sue);
1058
-	  if (cli_leavetemps_flag)
1059
-	    cli_dbgmsg("SUE: Decrypted executable saved in %s\n", tempfile);
1060
-	  else
1061
-	    cli_dbgmsg("SUE: Executable decrypted\n");
1062
-	  fsync(ndesc);
1063
-	  lseek(ndesc, 0, SEEK_SET);
1064
-
1065
-	  if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1066
-	    free(exe_sections);
1067
-	    close(ndesc);
1068
-	    if(!cli_leavetemps_flag)
1069
-	      unlink(tempfile);
1070
-	    free(tempfile);
1071
-	    return CL_VIRUS;
1072
-	  }
1073
-	  close(ndesc);
1074
-	  if(!cli_leavetemps_flag)
1075
-	    unlink(tempfile);
1076
-	  free(tempfile);
1077
-	}
1078
-      }
1079
-
1080
-    }
1081 976
 
1082 977
     /* UPX, FSG, MEW support */
1083 978
 
... ...
@@ -1094,169 +1070,92 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1094 1094
     }
1095 1095
 
1096 1096
     /* MEW support */
1097
-    if (found && (DCONF & PE_CONF_MEW)) {
1097
+    if (found && (DCONF & PE_CONF_MEW) && epsize>=16 && epbuff[0]=='\xe9') {
1098 1098
 	uint32_t fileoffset;
1099
-	/* Check EP for MEW */
1100
-	if(lseek(desc, ep, SEEK_SET) == -1) {
1101
-	    cli_dbgmsg("MEW: lseek() failed\n");
1102
-	    free(exe_sections);
1103
-	    return CL_EIO;
1104
-	}
1105 1099
 
1106
-        if((bytes = read(desc, buff, 25)) != 25 && bytes < 16) {
1107
-	    cli_dbgmsg("MEW: Can't read at least 16 bytes at 0x%x (%d) %d\n", ep, ep, bytes);
1108
-	    cli_dbgmsg("MEW: Broken or not compressed file\n");
1109
-	    free(exe_sections);
1110
-	    return CL_CLEAN;
1111
-	}
1100
+	fileoffset = (vep + cli_readint32(epbuff + 1) + 5);
1101
+	while (fileoffset == 0x154 || fileoffset == 0x158) {
1102
+	    uint32_t offdiff, uselzma;
1112 1103
 
1113
-	fileoffset = (vep + cli_readint32(buff + 1) + 5);
1114
-	do {
1115
-	    if (found && (buff[0] == '\xe9') && (fileoffset == 0x154 || fileoffset == 0x158))
1116
-	    {
1117
-		uint32_t offdiff, uselzma;
1104
+	    cli_dbgmsg ("MEW: found MEW characteristics %08X + %08X + 5 = %08X\n", 
1105
+			cli_readint32(epbuff + 1), vep, cli_readint32(epbuff + 1) + vep + 5);
1118 1106
 
1119
-		cli_dbgmsg ("MEW characteristics found: %08X + %08X + 5 = %08X\n", 
1120
-			cli_readint32(buff + 1), vep, cli_readint32(buff + 1) + vep + 5);
1107
+	    if(lseek(desc, fileoffset, SEEK_SET) == -1) {
1108
+	        cli_dbgmsg("MEW: lseek() failed\n");
1109
+		free(exe_sections);
1110
+		return CL_EIO;
1111
+	    }
1121 1112
 
1122
-		if(lseek(desc, fileoffset, SEEK_SET) == -1) {
1123
-		    cli_dbgmsg("MEW: lseek() failed\n");
1124
-		    free(exe_sections);
1125
-		    return CL_EIO;
1126
-		}
1113
+	    if((bytes = read(desc, buff, 0xb0)) != 0xb0) {
1114
+	        cli_dbgmsg("MEW: Can't read 0xb0 bytes at 0x%x (%d) %d\n", fileoffset, fileoffset, bytes);
1115
+		break;
1116
+	    }
1127 1117
 
1128
-		if((bytes = read(desc, buff, 0xb0)) != 0xb0) {
1129
-		    cli_dbgmsg("MEW: Can't read 0xb0 bytes at 0x%x (%d) %d\n", fileoffset, fileoffset, bytes);
1130
-		    break;
1131
-		}
1118
+	    if (fileoffset == 0x154) cli_dbgmsg("MEW: Win9x compatibility was set!\n");
1119
+	    else cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
1132 1120
 
1133
-		if (fileoffset == 0x154) 
1134
-		    cli_dbgmsg("MEW: Win9x compatibility was set!\n");
1135
-		else
1136
-		    cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
1121
+	    if((offdiff = cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
1122
+	        cli_dbgmsg("MEW: ESI is not in proper section\n");
1123
+		break;
1124
+	    }
1125
+	    offdiff -= exe_sections[i + 1].rva;
1137 1126
 
1138
-		/* is it always 0x1C and 0x21C or not */
1139
-		if((offdiff = cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4)
1140
-		{
1141
-		    cli_dbgmsg("MEW: ESI is not in proper section\n");
1142
-		    break;
1143
-		}
1144
-		offdiff -= exe_sections[i + 1].rva;
1127
+	    if(!cli_seeksect(desc, &exe_sections[i + 1])) {
1128
+		free(exe_sections);
1129
+		return CL_EIO;
1130
+	    }
1131
+	    ssize = exe_sections[i + 1].vsz;
1132
+	    dsize = exe_sections[i].vsz;
1145 1133
 
1146
-		if(lseek(desc, exe_sections[i + 1].raw, SEEK_SET) == -1) {
1147
-		    cli_dbgmsg("MEW: lseek() failed\n"); /* ACAB: lseek won't fail here but checking doesn't hurt even */
1148
-		    free(exe_sections);
1149
-		    return CL_EIO;
1150
-		}
1151
-		ssize = exe_sections[i + 1].vsz;
1152
-		dsize = exe_sections[i].vsz;
1134
+	    cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff);
1153 1135
 
1154
-		cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff);
1155
-		if(ctx->limits && ctx->limits->maxfilesize && (ssize + dsize > ctx->limits->maxfilesize || exe_sections[i + 1].rsz > ctx->limits->maxfilesize)) {
1156
-		    cli_dbgmsg("MEW: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize);
1157
-		    free(exe_sections);
1158
-		    if(BLOCKMAX) {
1159
-			*ctx->virname = "PE.MEW.ExceededFileSize";
1160
-			return CL_VIRUS;
1161
-		    } else {
1162
-			return CL_CLEAN;
1163
-		    }
1164
-		}
1136
+	    CLI_UNPSIZELIMITS("MEW", MAX(ssize + dsize, exe_sections[i + 1].rsz));
1165 1137
 
1166
-		/* allocate needed buffer */
1167
-		if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
1168
-		    free(exe_sections);
1169
-		    return CL_EMEM;
1170
-		}
1138
+	    /* allocate needed buffer */
1139
+	    if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
1140
+	        free(exe_sections);
1141
+		return CL_EMEM;
1142
+	    }
1171 1143
 
1172
-		if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize)
1173
-		{
1174
-		    cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
1175
-		    free(src);
1176
-		    break;
1177
-		}
1144
+	    if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
1145
+	        cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
1146
+		free(src);
1147
+		break;
1148
+	    }
1178 1149
 
1179
-		if((bytes = read(desc, src + dsize, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
1180
-		    cli_dbgmsg("MEW: Can't read %d bytes [readed: %d]\n", exe_sections[i + 1].rsz, bytes);
1181
-		    free(exe_sections);
1182
-		    free(src);
1183
-		    return CL_EIO;
1184
-		}
1185
-		cli_dbgmsg("MEW: %d (%08x) bytes read\n", bytes, bytes);
1186
-		/* count offset to lzma proc, if lzma used, 0xe8 -> call */
1187
-		if (buff[0x7b] == '\xe8')
1188
-		{
1189
-		    if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(buff + 0x7c) + fileoffset + 0x80, 4))
1190
-		    {
1191
-			cli_dbgmsg("MEW: lzma proc out of bounds!\n");
1192
-			free(src);
1193
-			break; /* to next unpacker in chain */
1194
-		    }
1195
-		    uselzma = cli_readint32(buff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
1196
-		} else
1197
-		    uselzma = 0;
1150
+	    if((bytes = read(desc, src + dsize, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
1151
+	        cli_dbgmsg("MEW: Can't read %d bytes [readed: %d]\n", exe_sections[i + 1].rsz, bytes);
1152
+		free(exe_sections);
1153
+		free(src);
1154
+		return CL_EIO;
1155
+	    }
1156
+	    cli_dbgmsg("MEW: %d (%08x) bytes read\n", bytes, bytes);
1198 1157
 
1199
-		if(!(tempfile = cli_gentemp(NULL))) {
1200
-		    free(exe_sections);
1201
-		    free(src);
1202
-		    return CL_EMEM;
1203
-		}
1204
-		if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1205
-		    cli_dbgmsg("MEW: Can't create file %s\n", tempfile);
1206
-		    free(tempfile);
1207
-		    free(exe_sections);
1158
+	    /* count offset to lzma proc, if lzma used, 0xe8 -> call */
1159
+	    if (buff[0x7b] == '\xe8') {
1160
+	        if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(buff + 0x7c) + fileoffset + 0x80, 4)) {
1161
+		    cli_dbgmsg("MEW: lzma proc out of bounds!\n");
1208 1162
 		    free(src);
1209
-		    return CL_EIO;
1210
-		}
1211
-		dest = src;
1212
-		switch(unmew11(i, src, offdiff, ssize, dsize, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, uselzma, NULL, NULL, ndesc)) {
1213
-		    case 1: /* Everything OK */
1214
-			cli_dbgmsg("MEW: Unpacked and rebuilt executable saved in %s\n", tempfile);
1215
-			free(src);
1216
-			fsync(ndesc);
1217
-			lseek(ndesc, 0, SEEK_SET);
1218
-
1219
-			cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1220
-			if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1221
-			    free(exe_sections);
1222
-			    close(ndesc);
1223
-			    if(!cli_leavetemps_flag)
1224
-				unlink(tempfile);
1225
-			    free(tempfile);
1226
-			    return CL_VIRUS;
1227
-			}
1228
-			close(ndesc);
1229
-			if(!cli_leavetemps_flag)
1230
-			    unlink(tempfile);
1231
-			free(tempfile);
1232
-			free(exe_sections);
1233
-			return CL_CLEAN;
1234
-		    default: /* Everything gone wrong */
1235
-			cli_dbgmsg("MEW: Unpacking failed\n");
1236
-			close(ndesc);
1237
-			unlink(tempfile); /* It's empty anyway */
1238
-			free(tempfile);
1239
-			free(src);
1240
-			break;
1163
+		    break; /* to next unpacker in chain */
1241 1164
 		}
1165
+		uselzma = cli_readint32(buff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
1166
+	    } else {
1167
+	        uselzma = 0;
1242 1168
 	    }
1243
-	} while (0);
1244
-    }
1245 1169
 
1246
-    if(found || upack) {
1247
-	/* Check EP for UPX vs. FSG vs. Upack */
1248
-	if(lseek(desc, ep, SEEK_SET) == -1) {
1249
-	    cli_dbgmsg("UPX/FSG: lseek() failed\n");
1250
-	    free(exe_sections);
1251
-	    return CL_EIO;
1170
+	    CLI_UNPTEMP("MEW",src,exe_sections);
1171
+	    CLI_UNPRESULTS("MEW",(unmew11(i, src, offdiff, ssize, dsize, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, uselzma, NULL, NULL, ndesc)),1,src);
1172
+	    break;
1252 1173
 	}
1174
+    }
1253 1175
 
1254
-        if(cli_readn(desc, buff, 168) != 168) {
1255
-	    cli_dbgmsg("UPX/FSG: Can't read 168 bytes at 0x%x (%d)\n", ep, ep);
1256
-	    cli_dbgmsg("UPX/FSG: Broken or not UPX/FSG compressed file\n");
1257
-	    free(exe_sections);
1258
-	    return CL_CLEAN;
1259
-	}
1176
+    if(epsize<168) {
1177
+	free(exe_sections);
1178
+	return CL_CLEAN;
1179
+    }
1180
+
1181
+    if (found || upack) {
1182
+	/* Check EP for UPX vs. FSG vs. Upack */
1260 1183
 
1261 1184
 	/* Upack 0.39 produces 2 types of executables
1262 1185
 	 * 3 sections:           | 2 sections (one empty, I don't chech found if !upack, since it's in OR above):
... ...
@@ -1278,947 +1177,593 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1278 1278
 	 * 
1279 1279
 	 */
1280 1280
 	/* upack 0.39-3s + sample 0151477*/
1281
- 	if(((upack && nsections == 3) && /* 3 sections */
1281
+ 	while(((upack && nsections == 3) && /* 3 sections */
1282 1282
 	    (
1283
-	     buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1284
-	     buff[5] == '\xad' && buff[6] == '\x50' /* lodsd; push eax */
1283
+	     epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1284
+	     epbuff[5] == '\xad' && epbuff[6] == '\x50' /* lodsd; push eax */
1285 1285
 	     )
1286 1286
 	    || 
1287 1287
 	    /* based on 0297729 sample from aCaB */
1288
-	    (buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1289
-	     buff[5] == '\xff' && buff[6] == '\x36' /* push [esi] */
1288
+	    (epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1289
+	     epbuff[5] == '\xff' && epbuff[6] == '\x36' /* push [esi] */
1290 1290
 	     )
1291 1291
 	    ) 
1292 1292
 	   ||
1293 1293
 	   ((!upack && nsections == 2) && /* 2 sections */
1294 1294
 	    ( /* upack 0.39-2s */
1295
-	     buff[0] == '\x60' && buff[1] == '\xe8' && cli_readint32(buff+2) == 0x9 /* pusha; call+9 */
1295
+	     epbuff[0] == '\x60' && epbuff[1] == '\xe8' && cli_readint32(epbuff+2) == 0x9 /* pusha; call+9 */
1296 1296
 	     )
1297 1297
 	    ||
1298 1298
 	    ( /* upack 1.1/1.2, based on 2 samples */
1299
-	     buff[0] == '\xbe' && cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase) < min &&  /* mov esi */
1300
-	     cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
1301
-	     buff[5] == '\xad' && buff[6] == '\x8b' && buff[7] == '\xf8' /* loads;  mov edi, eax */
1299
+	     epbuff[0] == '\xbe' && cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase) < min &&  /* mov esi */
1300
+	     cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
1301
+	     epbuff[5] == '\xad' && epbuff[6] == '\x8b' && epbuff[7] == '\xf8' /* loads;  mov edi, eax */
1302 1302
 	     )
1303 1303
 	    )
1304
-	   ){ 
1305
-		uint32_t vma, off;
1306
-		int a,b,c;
1307
-
1308
-		cli_dbgmsg("Upack characteristics found.\n");
1309
-		a = exe_sections[0].vsz;
1310
-		b = exe_sections[1].vsz;
1311
-		if (upack) {
1312
-			cli_dbgmsg("Upack: var set\n");
1313
-			c = exe_sections[2].vsz;
1314
-			ssize = exe_sections[0].ursz + exe_sections[0].uraw;
1315
-			off = exe_sections[0].rva;
1316
-			vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva;
1317
-		} else {
1318
-			cli_dbgmsg("Upack: var NOT set\n");
1319
-			c = exe_sections[1].rva;
1320
-			ssize = exe_sections[1].uraw;
1321
-			off = 0;
1322
-			vma = exe_sections[1].rva - exe_sections[1].uraw;
1323
-		}
1324
-
1325
-		dsize = a+b+c;
1326
-		if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || exe_sections[1].ursz > ctx->limits->maxfilesize))
1327
-		{
1328
-		    cli_dbgmsg("Upack: Sizes exceeded (a: %u, b: %u, c: %ux, max: %lu)\n", a, b, c, ctx->limits->maxfilesize);
1329
-		    free(exe_sections);
1330
-		    if(BLOCKMAX) {
1331
-			*ctx->virname = "PE.Upack.ExceededFileSize";
1332
-			return CL_VIRUS;
1333
-		    } else {
1334
-			return CL_CLEAN;
1335
-		    }
1336
-		}
1337
-		/* these are unsigned so if vaddr - off < 0, it should be ok */
1338
-		if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && (exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize)) || ssize > dsize)
1339
-		{
1340
-		    cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
1341
-		    goto skip_upack_and_go_to_next_unpacker;
1342
-		}
1343
-			
1344
-		if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1345
-		    free(exe_sections);
1346
-		    return CL_EMEM;
1347
-		}
1348
-		src = NULL;
1349
-	
1350
-		lseek(desc, 0, SEEK_SET);
1351
-		if(read(desc, dest, ssize) != ssize) {
1352
-		    cli_dbgmsg("Upack: Can't read raw data of section 0\n");
1353
-		    free(exe_sections);
1354
-		    free(dest);
1355
-		    return CL_EIO;
1356
-		}
1304
+	   ) { 
1305
+	    uint32_t vma, off;
1306
+	    int a,b,c;
1307
+
1308
+	    cli_dbgmsg("Upack characteristics found.\n");
1309
+	    a = exe_sections[0].vsz;
1310
+	    b = exe_sections[1].vsz;
1311
+	    if (upack) {
1312
+	        cli_dbgmsg("Upack: var set\n");
1313
+		c = exe_sections[2].vsz;
1314
+		ssize = exe_sections[0].ursz + exe_sections[0].uraw;
1315
+		off = exe_sections[0].rva;
1316
+		vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva;
1317
+	    } else {
1318
+	        cli_dbgmsg("Upack: var NOT set\n");
1319
+		c = exe_sections[1].rva;
1320
+		ssize = exe_sections[1].uraw;
1321
+		off = 0;
1322
+		vma = exe_sections[1].rva - exe_sections[1].uraw;
1323
+	    }
1357 1324
 
1358
-		if (upack)
1359
-		    memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
1325
+	    dsize = a+b+c;
1360 1326
 
1361
-		lseek(desc, exe_sections[1].uraw, SEEK_SET);
1327
+	    CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
1362 1328
 
1363
-		if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].ursz) != exe_sections[1].ursz) {
1364
-		    cli_dbgmsg("Upack: Can't read raw data of section 1\n");
1365
-		    free(exe_sections);
1366
-		    free(dest);
1367
-		    return CL_EIO;
1368
-		}
1369
-
1370
-		if(!(tempfile = cli_gentemp(NULL))) {
1371
-		    free(exe_sections);
1372
-		    free(dest);
1373
-		    return CL_EMEM;
1374
-		}
1329
+	    if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && (exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize)) || ssize > dsize) {
1330
+	        cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
1331
+		break;
1332
+	    }
1333
+			
1334
+	    if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1335
+	        free(exe_sections);
1336
+		return CL_EMEM;
1337
+	    }
1375 1338
 
1376
-		if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1377
-		    cli_dbgmsg("Upack: Can't create file %s\n", tempfile);
1378
-		    free(tempfile);
1379
-		    free(exe_sections);
1380
-		    free(dest);
1381
-		    return CL_EIO;
1382
-		}
1339
+	    lseek(desc, 0, SEEK_SET);
1340
+	    if(read(desc, dest, ssize) != ssize) {
1341
+	        cli_dbgmsg("Upack: Can't read raw data of section 0\n");
1342
+		free(exe_sections);
1343
+		free(dest);
1344
+		return CL_EIO;
1345
+	    }
1383 1346
 
1384
-		switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc))
1385
-		{
1386
-			case 1: /* Everything OK */
1387
-				cli_dbgmsg("Upack: Unpacked and rebuilt executable saved in %s\n", tempfile);
1388
-				free(dest);
1389
-				fsync(ndesc);
1390
-				lseek(ndesc, 0, SEEK_SET);
1391
-
1392
-				cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1393
-				if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1394
-					free(exe_sections);
1395
-					close(ndesc);
1396
-					if(!cli_leavetemps_flag)
1397
-						unlink(tempfile);
1398
-					free(tempfile);
1399
-					return CL_VIRUS;
1400
-				}
1401
-
1402
-				close(ndesc);
1403
-				if(!cli_leavetemps_flag)
1404
-					unlink(tempfile);
1405
-				free(tempfile);
1406
-				free(exe_sections);
1407
-				return CL_CLEAN;
1408
-
1409
-			default: /* Everything gone wrong */
1410
-				cli_dbgmsg("Upack: Unpacking failed\n");
1411
-				close(ndesc);
1412
-				unlink(tempfile); /* It's empty anyway */
1413
-				free(tempfile);
1414
-				free(dest);
1415
-				break;
1416
-		}
1417
-	}
1418
-skip_upack_and_go_to_next_unpacker:
1347
+	    if(upack) memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
1419 1348
 
1420
-	if((DCONF & PE_CONF_FSG) && buff[0] == '\x87' && buff[1] == '\x25') {
1349
+	    lseek(desc, exe_sections[1].uraw, SEEK_SET);
1421 1350
 
1422
-	    /* FSG v2.0 support - thanks to aCaB ! */
1351
+	    if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].ursz) != exe_sections[1].ursz) {
1352
+		cli_dbgmsg("Upack: Can't read raw data of section 1\n");
1353
+		free(exe_sections);
1354
+		free(dest);
1355
+		return CL_EIO;
1356
+	    }
1423 1357
 
1424
-	    ssize = exe_sections[i + 1].rsz;
1425
-	    dsize = exe_sections[i].vsz;
1358
+	    CLI_UNPTEMP("Upack",dest,exe_sections);
1359
+	    CLI_UNPRESULTS("Upack",(unupack(upack, dest, dsize, epbuff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)),1,dest);
1360
+	    break;
1361
+	}
1362
+    }
1426 1363
 
1427
-	    while(found) {
1428
-		    uint32_t newesi, newedi, newebx, newedx;
1364
+    
1365
+    while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\x87' && epbuff[1] == '\x25') {
1429 1366
 
1430
-		if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1431
-		    cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize);
1432
-		    free(exe_sections);
1433
-		    if(BLOCKMAX) {
1434
-			*ctx->virname = "PE.FSG.ExceededFileSize";
1435
-			return CL_VIRUS;
1436
-		    } else {
1437
-			return CL_CLEAN;
1438
-		    }
1439
-		}
1367
+	/* FSG v2.0 support - thanks to aCaB ! */
1440 1368
 
1441
-		if(ssize <= 0x19 || dsize <= ssize) {
1442
-		    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1443
-		    free(exe_sections);
1444
-		    return CL_CLEAN;
1445
-		}
1369
+	uint32_t newesi, newedi, newebx, newedx;
1370
+	
1371
+	ssize = exe_sections[i + 1].rsz;
1372
+	dsize = exe_sections[i].vsz;
1446 1373
 
1447
-		newedx = cli_readint32(buff + 2) - EC32(optional_hdr32.ImageBase);
1448
-		if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1449
-		    cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
1450
-		    break;
1451
-		}
1374
+	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1452 1375
 
1453
-		if((src = (char *) cli_malloc(ssize)) == NULL) {
1454
-		    free(exe_sections);
1455
-		    return CL_EMEM;
1456
-		}
1376
+	if(ssize <= 0x19 || dsize <= ssize) {
1377
+	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1378
+	    free(exe_sections);
1379
+	    return CL_CLEAN;
1380
+	}
1381
+	
1382
+	newedx = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase);
1383
+	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1384
+	    cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
1385
+	    break;
1386
+	}
1387
+	
1388
+	if((src = (char *) cli_malloc(ssize)) == NULL) {
1389
+	    free(exe_sections);
1390
+	    return CL_EMEM;
1391
+	}
1457 1392
 
1458
-		lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1459
-		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1460
-		    cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
1461
-		    free(exe_sections);
1462
-		    free(src);
1463
-		    return CL_EIO;
1464
-		}
1393
+	if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
1394
+	    cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
1395
+	    free(exe_sections);
1396
+	    free(src);
1397
+	    return CL_EIO;
1398
+	}
1465 1399
 
1466
-		dest = src + newedx - exe_sections[i + 1].rva;
1467
-		if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
1468
-		    cli_dbgmsg("FSG: New ESP out of bounds\n");
1469
-		    free(src);
1470
-		    break;
1471
-		}
1400
+	dest = src + newedx - exe_sections[i + 1].rva;
1401
+	if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
1402
+	    cli_dbgmsg("FSG: New ESP out of bounds\n");
1403
+	    free(src);
1404
+	    break;
1405
+	}
1472 1406
 
1473
-		newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1474
-		if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1475
-		    cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
1476
-		    free(src);
1477
-		    break;
1478
-		}
1407
+	newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1408
+	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1409
+	    cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
1410
+	    free(src);
1411
+	    break;
1412
+	}
1479 1413
  
1480
-		dest = src + newedx - exe_sections[i + 1].rva;
1481
-		if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
1482
-		    cli_dbgmsg("FSG: New stack out of bounds\n");
1483
-		    free(src);
1484
-		    break;
1485
-		}
1414
+	dest = src + newedx - exe_sections[i + 1].rva;
1415
+	if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
1416
+	    cli_dbgmsg("FSG: New stack out of bounds\n");
1417
+	    free(src);
1418
+	    break;
1419
+	}
1486 1420
 
1487
-		newedi = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1488
-		newesi = cli_readint32(dest + 4) - EC32(optional_hdr32.ImageBase);
1489
-		newebx = cli_readint32(dest + 16) - EC32(optional_hdr32.ImageBase);
1490
-		newedx = cli_readint32(dest + 20);
1421
+	newedi = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1422
+	newesi = cli_readint32(dest + 4) - EC32(optional_hdr32.ImageBase);
1423
+	newebx = cli_readint32(dest + 16) - EC32(optional_hdr32.ImageBase);
1424
+	newedx = cli_readint32(dest + 20);
1491 1425
 
1492
-		if(newedi != exe_sections[i].rva) {
1493
-		    cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
1494
-		    free(src);
1495
-		    break;
1496
-		}
1426
+	if(newedi != exe_sections[i].rva) {
1427
+	    cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
1428
+	    free(src);
1429
+	    break;
1430
+	}
1497 1431
 
1498
-		if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1499
-		    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1500
-		    free(src);
1501
-		    break;
1502
-		}
1432
+	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1433
+	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1434
+	    free(src);
1435
+	    break;
1436
+	}
1503 1437
 
1504
-		if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
1505
-		    cli_dbgmsg("FSG: Array of functions out of bounds\n");
1506
-		    free(src);
1507
-		    break;
1508
-		}
1438
+	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
1439
+	    cli_dbgmsg("FSG: Array of functions out of bounds\n");
1440
+	    free(src);
1441
+	    break;
1442
+	}
1509 1443
 
1510
-		newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
1511
-		cli_dbgmsg("FSG: found old EP @%x\n",newedx);
1444
+	newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
1445
+	cli_dbgmsg("FSG: found old EP @%x\n",newedx);
1512 1446
 
1513
-		if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1514
-		    free(exe_sections);
1515
-		    free(src);
1516
-		    return CL_EMEM;
1517
-		}
1447
+	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1448
+	    free(exe_sections);
1449
+	    free(src);
1450
+	    return CL_EMEM;
1451
+	}
1518 1452
 
1519
-		if(!(tempfile = cli_gentemp(NULL))) {
1520
-		    free(exe_sections);
1521
-		    free(src);
1522
-		    free(dest);
1523
-		    return CL_EMEM;
1524
-		}
1453
+	CLI_UNPTEMP("FSG",src,dest,exe_sections);
1454
+	CLI_UNPRESULTSFSG2("FSG",(unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)),1,src,dest);
1455
+	break;
1456
+    }
1525 1457
 
1526
-		if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1527
-		    cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1528
-		    free(tempfile);
1529
-		    free(exe_sections);
1530
-		    free(src);
1531
-		    free(dest);
1532
-		    return CL_EIO;
1533
-		}
1534
-		
1535
-		switch (unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)) {
1536
-		    case 1: /* Everything OK */
1537
-			cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1538
-			free(src);
1539
-			free(dest);
1540
-			fsync(ndesc);
1541
-			lseek(ndesc, 0, SEEK_SET);
1542
-
1543
-			cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1544
-			if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1545
-			    free(exe_sections);
1546
-			    close(ndesc);
1547
-			    if(!cli_leavetemps_flag)
1548
-				unlink(tempfile);
1549
-			    free(tempfile);
1550
-			    return CL_VIRUS;
1551
-			}
1552 1458
 
1553
-			close(ndesc);
1554
-			if(!cli_leavetemps_flag)
1555
-			    unlink(tempfile);
1556
-			free(tempfile);
1557
-			free(exe_sections);
1558
-			return CL_CLEAN;
1559
-
1560
-		    case 0: /* We've got an unpacked buffer, no exe though */
1561
-			cli_dbgmsg("FSG: Successfully decompressed\n");
1562
-			close(ndesc);
1563
-			unlink(tempfile);
1564
-			free(tempfile);
1565
-			found = 0;
1566
-			upx_success = 1;
1567
-			break; /* Go and scan the buffer! */
1568
-
1569
-		    default: /* Everything gone wrong */
1570
-			cli_dbgmsg("FSG: Unpacking failed\n");
1571
-			close(ndesc);
1572
-			unlink(tempfile); /* It's empty anyway */
1573
-			free(tempfile);
1574
-			free(src);
1575
-			free(dest);
1576
-			break;
1577
-		}
1459
+    while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1578 1460
 
1579
-		break; /* were done with 2 */
1580
-	    }
1581
-	}
1461
+	/* FSG support - v. 1.33 (thx trog for the many samples) */
1582 1462
 
1583
- 	if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1463
+	int sectcnt = 0;
1464
+	char *support;
1465
+	uint32_t newesi, newedi, newebx, oldep, gp, t;
1466
+	struct cli_exe_section *sections;
1584 1467
 
1585
-	    /* FSG support - v. 1.33 (thx trog for the many samples) */
1468
+	ssize = exe_sections[i + 1].rsz;
1469
+	dsize = exe_sections[i].vsz;
1586 1470
 
1587
-	    ssize = exe_sections[i + 1].rsz;
1588
-	    dsize = exe_sections[i].vsz;
1471
+	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1589 1472
 
1590
-	    while(found) {
1591
-	            int sectcnt = 0;
1592
-		    char *support;
1593
-		    uint32_t newesi, newedi, newebx, oldep, gp, t;
1594
-		    struct cli_exe_section *sections;
1473
+	if(ssize <= 0x19 || dsize <= ssize) {
1474
+	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1475
+	    free(exe_sections);
1476
+	    return CL_CLEAN;
1477
+	}
1595 1478
 
1479
+	if(!(gp = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
1480
+	    cli_dbgmsg("FSG: Support data out of padding area\n");
1481
+	    break;
1482
+	}
1596 1483
 
1597
-		if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1598
-		    cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize);
1599
-		    free(exe_sections);
1600
-		    if(BLOCKMAX) {
1601
-			*ctx->virname = "PE.FSG.ExceededFileSize";
1602
-			return CL_VIRUS;
1603
-		    } else {
1604
-			return CL_CLEAN;
1605
-		    }
1606
-		}
1484
+	lseek(desc, gp, SEEK_SET);
1485
+	gp = exe_sections[i + 1].raw - gp;
1607 1486
 
1608
-		if(ssize <= 0x19 || dsize <= ssize) {
1609
-		    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1610
-		    free(exe_sections);
1611
-		    return CL_CLEAN;
1612
-		}
1487
+	CLI_UNPSIZELIMITS("FSG", gp)
1613 1488
 
1614
-		if(!(gp = cli_rawaddr(cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
1615
-		    cli_dbgmsg("FSG: Support data out of padding area\n");
1616
-		    break;
1617
-		}
1489
+	if((support = (char *) cli_malloc(gp)) == NULL) {
1490
+	    free(exe_sections);
1491
+	    return CL_EMEM;
1492
+	}
1618 1493
 
1619
-		lseek(desc, gp, SEEK_SET);
1620
-		gp = exe_sections[i + 1].raw - gp;
1494
+	if((int)cli_readn(desc, support, gp) != (int)gp) {
1495
+	    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1496
+	    free(exe_sections);
1497
+	    free(support);
1498
+	    return CL_EIO;
1499
+	}
1621 1500
 
1622
-		if(ctx->limits && ctx->limits->maxfilesize && (unsigned int) gp > ctx->limits->maxfilesize) {
1623
-		    cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize);
1624
-		    free(exe_sections);
1625
-		    if(BLOCKMAX) {
1626
-			*ctx->virname = "PE.FSG.ExceededFileSize";
1627
-			return CL_VIRUS;
1628
-		    } else {
1629
-			return CL_CLEAN;
1630
-		    }
1631
-		}
1501
+	/* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase);  Unused */
1502
+	newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
1503
+	newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
1632 1504
 
1633
-		if((support = (char *) cli_malloc(gp)) == NULL) {
1634
-		    free(exe_sections);
1635
-		    return CL_EMEM;
1636
-		}
1505
+	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1506
+	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1507
+	    free(support);
1508
+	    break;
1509
+	}
1637 1510
 
1638
-		if((int)cli_readn(desc, support, gp) != (int)gp) {
1639
-		    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1640
-		    free(exe_sections);
1641
-		    free(support);
1642
-		    return CL_EIO;
1643
-		}
1511
+	if(newedi != exe_sections[i].rva) {
1512
+	    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1513
+	    free(support);
1514
+	    break;
1515
+	}
1644 1516
 
1645
-		/* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase);  Unused */
1646
-		newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
1647
-		newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
1517
+	/* Counting original sections */
1518
+	for(t = 12; t < gp - 4; t += 4) {
1519
+	    uint32_t rva = cli_readint32(support+t);
1648 1520
 
1649
-		if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1650
-		    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1651
-		    free(support);
1652
-		    break;
1653
-		}
1521
+	    if(!rva)
1522
+		break;
1654 1523
 
1655
-		if(newedi != exe_sections[i].rva) {
1656
-		    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1657
-		    free(support);
1658
-		    break;
1659
-		}
1524
+	    rva -= EC32(optional_hdr32.ImageBase)+1;
1525
+	    sectcnt++;
1660 1526
 
1661
-		/* Counting original sections */
1662
-		for(t = 12; t < gp - 4; t += 4) {
1663
-			uint32_t rva = cli_readint32(support+t);
1527
+	    if(rva % 0x1000) cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
1664 1528
 
1665
-		    if(!rva)
1666
-			break;
1529
+	    if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1530
+		cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1531
+		break;
1532
+	    }
1533
+	}
1667 1534
 
1668
-		    rva -= EC32(optional_hdr32.ImageBase)+1;
1669
-		    sectcnt++;
1535
+	if(t >= gp - 4 || cli_readint32(support + t)) {
1536
+	    free(support);
1537
+	    break;
1538
+	}
1670 1539
 
1671
-		    if(rva % 0x1000)
1672
-			/* FIXME: really need to bother? */
1673
-			cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
1540
+	if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1541
+	    free(exe_sections);
1542
+	    free(support);
1543
+	    return CL_EMEM;
1544
+	}
1674 1545
 
1675
-		    if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1676
-			cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1677
-			break;
1678
-		    }
1679
-		}
1546
+	sections[0].rva = newedi;
1547
+	for(t = 1; t <= (uint32_t)sectcnt; t++)
1548
+	    sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
1680 1549
 
1681
-		if(t >= gp - 4 || cli_readint32(support + t)) {
1682
-		    free(support);
1683
-		    break;
1684
-		}
1550
+	free(support);
1685 1551
 
1686
-		if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1687
-		    free(exe_sections);
1688
-		    free(support);
1689
-		    return CL_EMEM;
1690
-		}
1552
+	if((src = (char *) cli_malloc(ssize)) == NULL) {
1553
+	    free(exe_sections);
1554
+	    free(sections);
1555
+	    return CL_EMEM;
1556
+	}
1691 1557
 
1692
-		sections[0].rva = newedi;
1693
-		for(t = 1; t <= (uint32_t)sectcnt; t++)
1694
-		    sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
1558
+	if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
1559
+	    cli_dbgmsg("Can't read raw data of section %d\n", i);
1560
+	    free(exe_sections);
1561
+	    free(sections);
1562
+	    free(src);
1563
+	    return CL_EIO;
1564
+	}
1695 1565
 
1696
-		free(support);
1566
+	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1567
+	    free(exe_sections);
1568
+	    free(src);
1569
+	    free(sections);
1570
+	    return CL_EMEM;
1571
+	}
1697 1572
 
1698
-		if((src = (char *) cli_malloc(ssize)) == NULL) {
1699
-		    free(exe_sections);
1700
-		    free(sections);
1701
-		    return CL_EMEM;
1702
-		}
1573
+	oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
1574
+	cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1703 1575
 
1704
-		lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1705
-		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1706
-		    cli_dbgmsg("Can't read raw data of section %d\n", i);
1707
-		    free(exe_sections);
1708
-		    free(sections);
1709
-		    free(src);
1710
-		    return CL_EIO;
1711
-		}
1576
+	CLI_UNPTEMP("FSG",src,dest,sections,exe_sections);
1577
+	CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,src,dest,sections);
1578
+	break; /* were done with 1.33 */
1579
+    }
1712 1580
 
1713
-		if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1714
-		    free(exe_sections);
1715
-		    free(src);
1716
-		    free(sections);
1717
-		    return CL_EMEM;
1718
-		}
1719 1581
 
1720
-		oldep = vep + 161 + 6 + cli_readint32(buff+163);
1721
-		cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1582
+    while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbb' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min && epbuff[5] == '\xbf' && epbuff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1722 1583
 
1723
-		if(!(tempfile = cli_gentemp(NULL))) {
1724
-		    free(exe_sections);
1725
-		    free(src);
1726
-		    free(dest);
1727
-		    free(sections);
1728
-		    return CL_EMEM;
1729
-		}
1584
+	/* FSG support - v. 1.31 */
1730 1585
 
1731
-		if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1732
-		    cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1733
-		    free(tempfile);
1734
-		    free(exe_sections);
1735
-		    free(src);
1736
-		    free(dest);
1737
-		    free(sections);
1738
-		    return CL_EIO;
1739
-		}
1586
+	int sectcnt = 0;
1587
+	uint32_t t;
1588
+	uint32_t gp = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
1589
+	char *support;
1590
+	uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
1591
+	uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
1592
+	uint32_t oldep = vep - exe_sections[i + 1].rva;
1593
+	struct cli_exe_section *sections;
1740 1594
 
1741
-		switch(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) {
1742
-		    case 1: /* Everything OK */
1743
-			cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1744
-			free(src);
1745
-			free(dest);
1746
-			free(sections);
1747
-			fsync(ndesc);
1748
-			lseek(ndesc, 0, SEEK_SET);
1749
-
1750
-			cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1751
-			if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1752
-			    free(exe_sections);
1753
-			    close(ndesc);
1754
-			    if(!cli_leavetemps_flag)
1755
-				unlink(tempfile);
1756
-			    free(tempfile);
1757
-			    return CL_VIRUS;
1758
-			}
1595
+	ssize = exe_sections[i + 1].rsz;
1596
+	dsize = exe_sections[i].vsz;
1759 1597
 
1760
-			close(ndesc);
1761
-			if(!cli_leavetemps_flag)
1762
-			    unlink(tempfile);
1763
-			free(tempfile);
1764
-			free(exe_sections);
1765
-			return CL_CLEAN;
1766
-
1767
-		    case 0: /* We've got an unpacked buffer, no exe though */
1768
-			cli_dbgmsg("FSG: Successfully decompressed\n");
1769
-			close(ndesc);
1770
-			unlink(tempfile);
1771
-			free(tempfile);
1772
-			free(sections);
1773
-			found = 0;
1774
-			upx_success = 1;
1775
-			break; /* Go and scan the buffer! */
1776
-
1777
-		    default: /* Everything gone wrong */
1778
-			cli_dbgmsg("FSG: Unpacking failed\n");
1779
-			close(ndesc);
1780
-			unlink(tempfile); /* It's empty anyway */
1781
-			free(tempfile);
1782
-			free(src);
1783
-			free(dest);
1784
-			free(sections);
1785
-			break;
1786
-		}
1787 1598
 
1788
-		break; /* were done with 1.33 */
1789
-	    }
1599
+	if(err) {
1600
+	    cli_dbgmsg("FSG: Support data out of padding area\n");
1601
+	    break;
1790 1602
 	}
1791 1603
 
1792
-	/* FIXME: easy 2 hack */
1793
- 	if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbb' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min && buff[5] == '\xbf' && buff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1794
-
1795
-	    /* FSG support - v. 1.31 */
1604
+	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
1605
+	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1606
+	    break;
1607
+	}
1796 1608
 
1797
-	    ssize = exe_sections[i + 1].rsz;
1798
-	    dsize = exe_sections[i].vsz;
1609
+	if(newedi != exe_sections[i].rva) {
1610
+	    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1611
+	    break;
1612
+	}
1799 1613
 
1800
-	    while(found) {
1801
-		    int sectcnt = 0;
1802
-		    uint32_t t;
1803
-		    uint32_t gp = cli_rawaddr(cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
1804
-		    char *support;
1805
-		    uint32_t newesi = cli_readint32(buff+11) - EC32(optional_hdr32.ImageBase);
1806
-		    uint32_t newedi = cli_readint32(buff+6) - EC32(optional_hdr32.ImageBase);
1807
-		    uint32_t oldep = vep - exe_sections[i + 1].rva;
1808
-		    struct cli_exe_section *sections;
1809
-
1810
-		if(err) {
1811
-		    cli_dbgmsg("FSG: Support data out of padding area\n");
1812
-		    break;
1813
-		}
1614
+	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1814 1615
 
1815
-		if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
1816
-		    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1817
-		    break;
1818
-		}
1616
+	if(ssize <= 0x19 || dsize <= ssize) {
1617
+	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1618
+	    free(exe_sections);
1619
+	    return CL_CLEAN;
1620
+	}
1819 1621
 
1820
-		if(newedi != exe_sections[i].rva) {
1821
-		    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1822
-		    break;
1823
-		}
1622
+	lseek(desc, gp, SEEK_SET);
1623
+	gp = exe_sections[i + 1].raw - gp;
1824 1624
 
1825
-		if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1826
-		    cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize);
1827
-		    free(exe_sections);
1828
-		    if(BLOCKMAX) {
1829
-			*ctx->virname = "PE.FSG.ExceededFileSize";
1830
-			return CL_VIRUS;
1831
-		    } else {
1832
-			return CL_CLEAN;
1833
-		    }
1834
-		}
1625
+	CLI_UNPSIZELIMITS("FSG", gp)
1835 1626
 
1836
-		if(ssize <= 0x19 || dsize <= ssize) {
1837
-		    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1838
-		    free(exe_sections);
1839
-		    return CL_CLEAN;
1840
-		}
1627
+	if((support = (char *) cli_malloc(gp)) == NULL) {
1628
+	    free(exe_sections);
1629
+	    return CL_EMEM;
1630
+	}
1841 1631
 
1842
-		lseek(desc, gp, SEEK_SET);
1843
-		gp = exe_sections[i + 1].raw - gp;
1632
+	if(cli_readn(desc, support, gp) != (int)gp) {
1633
+	    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1634
+	    free(exe_sections);
1635
+	    free(support);
1636
+	    return CL_EIO;
1637
+	}
1844 1638
 
1845
-		if(ctx->limits && ctx->limits->maxfilesize && gp > ctx->limits->maxfilesize) {
1846
-		    cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize);
1847
-		    free(exe_sections);
1848
-		    if(BLOCKMAX) {
1849
-			*ctx->virname = "PE.FSG.ExceededFileSize";
1850
-			return CL_VIRUS;
1851
-		    } else {
1852
-			return CL_CLEAN;
1853
-		    }
1854
-		}
1639
+	/* Counting original sections */
1640
+	for(t = 0; t < gp - 2; t += 2) {
1641
+	    uint32_t rva = support[t]|(support[t+1]<<8);
1855 1642
 
1856
-		if((support = (char *) cli_malloc(gp)) == NULL) {
1857
-		    free(exe_sections);
1858
-		    return CL_EMEM;
1859
-		}
1643
+	    if (rva == 2 || rva == 1)
1644
+		break;
1860 1645
 
1861
-		if(cli_readn(desc, support, gp) != (int)gp) {
1862
-		    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1863
-		    free(exe_sections);
1864
-		    free(support);
1865
-		    return CL_EIO;
1866
-		}
1646
+	    rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
1647
+	    sectcnt++;
1867 1648
 
1868
-		/* Counting original sections */
1869
-		for(t = 0; t < gp - 2; t += 2) {
1870
-		  uint32_t rva = support[t]|(support[t+1]<<8);
1871
-		  
1872
-		  if (rva == 2 || rva == 1)
1873
-		    break;
1649
+	    if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1650
+		cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1651
+		break;
1652
+	    }
1653
+	}
1874 1654
 
1875
-		  rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
1876
-		  sectcnt++;
1655
+	if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
1656
+	    free(support);
1657
+	    break;
1658
+	}
1877 1659
 
1878
-		  if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1879
-		    cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1880
-		    break;
1881
-		  }
1882
-		}
1660
+	if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1661
+	    free(exe_sections);
1662
+	    free(support);
1663
+	    return CL_EMEM;
1664
+	}
1883 1665
 
1884
-		if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
1885
-		    free(support);
1886
-		    break;
1887
-		}
1666
+	sections[0].rva = newedi;
1667
+	for(t = 0; t <= (uint32_t)sectcnt - 1; t++) {
1668
+	    sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
1669
+	}
1888 1670
 
1889
-		if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1890
-		    free(exe_sections);
1891
-		    free(support);
1892
-		    return CL_EMEM;
1893
-		}
1671
+	free(support);
1894 1672
 
1895
-		sections[0].rva = newedi;
1896
-		for(t = 0; t <= (uint32_t)sectcnt - 1; t++) {
1897
-		  sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
1898
-		}
1673
+	if((src = (char *) cli_malloc(ssize)) == NULL) {
1674
+	    free(exe_sections);
1675
+	    free(sections);
1676
+	    return CL_EMEM;
1677
+	}
1899 1678
 
1900
-		free(support);
1679
+	if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
1680
+	    cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
1681
+	    free(exe_sections);
1682
+	    free(sections);
1683
+	    free(src);
1684
+	    return CL_EIO;
1685
+	}
1901 1686
 
1902
-		if((src = (char *) cli_malloc(ssize)) == NULL) {
1903
-		    free(exe_sections);
1904
-		    free(sections);
1905
-		    return CL_EMEM;
1906
-		}
1687
+	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1688
+	    free(exe_sections);
1689
+	    free(src);
1690
+	    free(sections);
1691
+	    return CL_EMEM;
1692
+	}
1907 1693
 
1908
-		lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1909
-		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1910
-		    cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
1911
-		    free(exe_sections);
1912
-		    free(sections);
1913
-		    free(src);
1914
-		    return CL_EIO;
1915
-		}
1694
+	gp = 0xda + 6*(epbuff[16]=='\xe8');
1695
+	oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
1696
+	cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1916 1697
 
1917
-		if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1918
-		    free(exe_sections);
1919
-		    free(src);
1920
-		    free(sections);
1921
-		    return CL_EMEM;
1922
-		}
1698
+	CLI_UNPTEMP("FSG",src,dest,sections,exe_sections);
1699
+	CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,src,dest,sections);
1700
+	break; /* were done with 1.31 */
1701
+    }
1923 1702
 
1924
-		/* Better not increasing buff size any further, let's go the hard way */
1925
-		gp = 0xda + 6*(buff[16]=='\xe8');
1926
-		oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
1927
-		cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1928 1703
 
1929
-		if(!(tempfile = cli_gentemp(NULL))) {
1930
-		    free(exe_sections);
1931
-		    free(src);
1932
-		    free(dest);
1933
-		    free(sections);
1934
-		    return CL_EMEM;
1935
-		}
1704
+    if(found && (DCONF & PE_CONF_UPX)) {
1936 1705
 
1937
-		if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1938
-		    cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1939
-		    free(tempfile);
1940
-		    free(exe_sections);
1941
-		    free(src);
1942
-		    free(dest);
1943
-		    free(sections);
1944
-		    return CL_EIO;
1945
-		}
1706
+	/* UPX support */
1946 1707
 
1947
-		switch(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) {
1948
-		    case 1: /* Everything OK */
1949
-			cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1950
-			free(src);
1951
-			free(dest);
1952
-			free(sections);
1953
-			fsync(ndesc);
1954
-			lseek(ndesc, 0, SEEK_SET);
1955
-
1956
-			cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1957
-			if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1958
-			    free(exe_sections);
1959
-			    close(ndesc);
1960
-			    if(!cli_leavetemps_flag)
1961
-				unlink(tempfile);
1962
-			    free(tempfile);
1963
-			    return CL_VIRUS;
1964
-			}
1708
+	/* we assume (i + 1) is UPX1 */
1709
+	ssize = exe_sections[i + 1].rsz;
1710
+	dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
1965 1711
 
1966
-			close(ndesc);
1967
-			if(!cli_leavetemps_flag)
1968
-			    unlink(tempfile);
1969
-			free(tempfile);
1970
-			free(exe_sections);
1971
-			return CL_CLEAN;
1972
-
1973
-		    case 0: /* We've got an unpacked buffer, no exe though */
1974
-			cli_dbgmsg("FSG: FSG: Successfully decompressed\n");
1975
-			close(ndesc);
1976
-			unlink(tempfile);
1977
-			free(tempfile);
1978
-			free(sections);
1979
-			found = 0;
1980
-			upx_success = 1;
1981
-			break; /* Go and scan the buffer! */
1982
-
1983
-		    default: /* Everything gone wrong */
1984
-			cli_dbgmsg("FSG: Unpacking failed\n");
1985
-			close(ndesc);
1986
-			unlink(tempfile); /* It's empty anyway */
1987
-			free(tempfile);
1988
-			free(src);
1989
-			free(dest);
1990
-			free(sections);
1991
-			break;
1992
-		}
1712
+	CLI_UNPSIZELIMITS("UPX", MAX(dsize, ssize));
1993 1713
 
1994
-		break; /* were done with 1.31 */
1995
-	    }
1714
+	if(ssize <= 0x19 || dsize <= ssize || dsize > CLI_MAX_ALLOCATION ) {
1715
+	    cli_dbgmsg("UPX: Size mismatch or dsize too big (ssize: %d, dsize: %d)\n", ssize, dsize);
1716
+	    free(exe_sections);
1717
+	    return CL_CLEAN;
1996 1718
 	}
1997 1719
 
1720
+	if((src = (char *) cli_malloc(ssize)) == NULL) {
1721
+	    free(exe_sections);
1722
+	    return CL_EMEM;
1723
+	}
1998 1724
 
1999
-	if(found && (DCONF & PE_CONF_UPX)) {
2000
-
2001
-	    /* UPX support */
2002
-
2003
-	    /* we assume (i + 1) is UPX1 */
2004
-	    ssize = exe_sections[i + 1].rsz;
2005
-	    dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
2006
-
2007
-	    if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
2008
-		cli_dbgmsg("UPX: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize);
2009
-		free(exe_sections);
2010
-		if(BLOCKMAX) {
2011
-		    *ctx->virname = "PE.UPX.ExceededFileSize";
2012
-		    return CL_VIRUS;
2013
-		} else {
2014
-		    return CL_CLEAN;
2015
-		}
2016
-	    }
2017
-
2018
-	    if(ssize <= 0x19 || dsize <= ssize) { /* FIXME: What are reasonable values? */
2019
-		cli_dbgmsg("UPX: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
2020
-		free(exe_sections);
2021
-		return CL_CLEAN;
2022
-	    }
2023
-
2024
-	    if((src = (char *) cli_malloc(ssize)) == NULL) {
2025
-		free(exe_sections);
2026
-		return CL_EMEM;
2027
-	    }
2028
-
2029
-	    if(dsize > CLI_MAX_ALLOCATION) {
2030
-		cli_errmsg("UPX: Too big value of dsize\n");
2031
-		free(exe_sections);
2032
-		free(src);
2033
-		return CL_EMEM;
2034
-	    }
1725
+	if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
1726
+	    free(exe_sections);
1727
+	    free(src);
1728
+	    return CL_EMEM;
1729
+	}
2035 1730
 
2036
-	    if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
2037
-		free(exe_sections);
2038
-		free(src);
2039
-		return CL_EMEM;
2040
-	    }
1731
+	if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
1732
+	    cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
1733
+	    free(exe_sections);
1734
+	    free(src);
1735
+	    free(dest);
1736
+	    return CL_EIO;
1737
+	}
2041 1738
 
2042
-	    lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
2043
-	    if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
2044
-		cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
2045
-		free(exe_sections);
2046
-		free(src);
2047
-		free(dest);
2048
-		return CL_EIO;
2049
-	    }
1739
+	/* try to detect UPX code */
1740
+	if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
1741
+	    cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
1742
+	    upxfn = upx_inflate2b;
1743
+	} else if(cli_memstr(UPX_NRV2D, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, epbuff + 0x69 + 8, 13)) {
1744
+	    cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
1745
+	    upxfn = upx_inflate2d;
1746
+	} else if(cli_memstr(UPX_NRV2E, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, epbuff + 0x69 + 8, 13)) {
1747
+	    cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
1748
+	    upxfn = upx_inflate2e;
1749
+	}
2050 1750
 
2051
-	    /* try to detect UPX code */
1751
+	if(upxfn) {
1752
+	    int skew = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
2052 1753
 
2053
-	    if(lseek(desc, ep, SEEK_SET) == -1) {
2054
-		cli_dbgmsg("UPX: lseek() failed\n");
2055
-		free(exe_sections);
2056
-		free(src);
2057
-		free(dest);
2058
-		return CL_EIO;
2059
-	    }
1754
+	    if(epbuff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
1755
+		skew = 0; 
1756
+		if(upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
1757
+		    upx_success = 1;
2060 1758
 
2061
-	    if(cli_readn(desc, buff, 126) != 126) { /* i.e. 0x69 + 13 + 8 */
2062
-		cli_dbgmsg("UPX: Can't read 126 bytes at 0x%x (%d)\n", ep, ep);
2063
-		cli_dbgmsg("UPX: Broken or not UPX compressed file\n");
2064
-		free(exe_sections);
2065
-		free(src);
2066
-		free(dest);
2067
-		return CL_CLEAN;
2068 1759
 	    } else {
2069
-		if(cli_memstr(UPX_NRV2B, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, buff + 0x69 + 8, 13)) {
2070
-		    cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
2071
-		    upxfn = upx_inflate2b;
2072
-		} else if(cli_memstr(UPX_NRV2D, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, buff + 0x69 + 8, 13)) {
2073
-		    cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
2074
-		    upxfn = upx_inflate2d;
2075
-		} else if(cli_memstr(UPX_NRV2E, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, buff + 0x69 + 8, 13)) {
2076
-		    cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
2077
-		    upxfn = upx_inflate2e;
2078
-		}
1760
+		cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
1761
+		if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0 || upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
1762
+		    upx_success = 1;
2079 1763
 	    }
2080 1764
 
2081
-	    if(upxfn) {
2082
-		    int skew = cli_readint32(buff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
2083
-
2084
-		if(buff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
2085
-		    skew = 0; 
2086
-		    if(upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
2087
-			upx_success = 1;
2088
-
2089
-		} else {
2090
-		    cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
2091
-                    if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0 || upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
2092
-			upx_success = 1;
2093
-		}
2094
-
2095
-		if(upx_success)
2096
-		    cli_dbgmsg("UPX: Successfully decompressed\n");
2097
-		else
2098
-		    cli_dbgmsg("UPX: Preferred decompressor failed\n");
2099
-	    }
1765
+	    if(upx_success)
1766
+		cli_dbgmsg("UPX: Successfully decompressed\n");
1767
+	    else
1768
+		cli_dbgmsg("UPX: Preferred decompressor failed\n");
1769
+	}
2100 1770
 
2101
-	    if(!upx_success && upxfn != upx_inflate2b) {
2102
-		if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1771
+	if(!upx_success && upxfn != upx_inflate2b) {
1772
+	    if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2103 1773
 
2104
-		    cli_dbgmsg("UPX: NRV2B decompressor failed\n");
2105
-		} else {
2106
-		    upx_success = 1;
2107
-		    cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
2108
-		}
1774
+		cli_dbgmsg("UPX: NRV2B decompressor failed\n");
1775
+	    } else {
1776
+		upx_success = 1;
1777
+		cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
2109 1778
 	    }
1779
+	}
2110 1780
 
2111
-	    if(!upx_success && upxfn != upx_inflate2d) {
2112
-		if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1781
+	if(!upx_success && upxfn != upx_inflate2d) {
1782
+	    if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2113 1783
 
2114
-		    cli_dbgmsg("UPX: NRV2D decompressor failed\n");
2115
-		} else {
2116
-		    upx_success = 1;
2117
-		    cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
2118
-		}
2119
-	    }
2120
-
2121
-	    if(!upx_success && upxfn != upx_inflate2e) {
2122
-		if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2123
-		    cli_dbgmsg("UPX: NRV2E decompressor failed\n");
2124
-		} else {
2125
-		    upx_success = 1;
2126
-		    cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
2127
-		}
1784
+		cli_dbgmsg("UPX: NRV2D decompressor failed\n");
1785
+	    } else {
1786
+		upx_success = 1;
1787
+		cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
2128 1788
 	    }
1789
+	}
2129 1790
 
2130
-	    if(!upx_success) {
2131
-		cli_dbgmsg("UPX: All decompressors failed\n");
2132
-		free(src);
2133
-		free(dest);
1791
+	if(!upx_success && upxfn != upx_inflate2e) {
1792
+	    if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1793
+		cli_dbgmsg("UPX: NRV2E decompressor failed\n");
1794
+	    } else {
1795
+		upx_success = 1;
1796
+		cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
2134 1797
 	    }
2135 1798
 	}
2136 1799
 
2137
-	if(upx_success) {
1800
+	if(!upx_success) {
1801
+	    cli_dbgmsg("UPX: All decompressors failed\n");
2138 1802
 	    free(src);
2139
-	    free(exe_sections);
2140
-
2141
-	    if(!(tempfile = cli_gentemp(NULL))) {
2142
-	        free(dest);
2143
-		return CL_EMEM;
2144
-	    }
1803
+	    free(dest);
1804
+	}
1805
+    }
2145 1806
 
2146
-	    if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2147
-		cli_dbgmsg("UPX/FSG: Can't create file %s\n", tempfile);
2148
-		free(tempfile);
2149
-		free(dest);
2150
-		return CL_EIO;
2151
-	    }
1807
+    if(upx_success) {
1808
+	free(src);
1809
+	free(exe_sections);
2152 1810
 
2153
-	    if((unsigned int) write(ndesc, dest, dsize) != dsize) {
2154
-		cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
2155
-		free(tempfile);
2156
-		free(dest);
2157
-		close(ndesc);
2158
-		return CL_EIO;
2159
-	    }
1811
+	CLI_UNPTEMP("UPX/FSG",dest);
2160 1812
 
1813
+	if((unsigned int) write(ndesc, dest, dsize) != dsize) {
1814
+	    cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
1815
+	    free(tempfile);
2161 1816
 	    free(dest);
2162
-	    fsync(ndesc);
2163
-	    lseek(ndesc, 0, SEEK_SET);
1817
+	    close(ndesc);
1818
+	    return CL_EIO;
1819
+	}
2164 1820
 
2165
-	    if(cli_leavetemps_flag)
2166
-		cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
1821
+	free(dest);
1822
+	fsync(ndesc);
1823
+	lseek(ndesc, 0, SEEK_SET);
2167 1824
 
2168
-	    cli_dbgmsg("***** Scanning decompressed file *****\n");
2169
-	    if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
2170
-		close(ndesc);
2171
-		if(!cli_leavetemps_flag)
2172
-		    unlink(tempfile);
2173
-		free(tempfile);
2174
-		return CL_VIRUS;
2175
-	    }
1825
+	if(cli_leavetemps_flag)
1826
+	    cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
2176 1827
 
1828
+	cli_dbgmsg("***** Scanning decompressed file *****\n");
1829
+	if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
2177 1830
 	    close(ndesc);
2178
-	    if(!cli_leavetemps_flag)
2179
-		unlink(tempfile);
1831
+	    CLI_TMPUNLK();
2180 1832
 	    free(tempfile);
2181
-	    return ret;
1833
+	    return CL_VIRUS;
2182 1834
 	}
1835
+
1836
+	close(ndesc);
1837
+	CLI_TMPUNLK();
1838
+	free(tempfile);
1839
+	return ret;
2183 1840
     }
2184 1841
 
2185
-    /* Petite */
2186 1842
 
2187
-    found = 2;
1843
+    /* Petite */
2188 1844
 
2189
-    lseek(desc, ep, SEEK_SET);
2190
-    memset(buff, 0, sizeof(buff));
2191
-    if(cli_readn(desc, buff, 200) == -1) {
2192
-	cli_dbgmsg("cli_readn() failed\n");
1845
+    if(epsize<200) {
2193 1846
 	free(exe_sections);
2194
-	return CL_EIO;
1847
+	return CL_CLEAN;
2195 1848
     }
2196 1849
 
2197
-    if(buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != exe_sections[nsections - 1].rva + EC32(optional_hdr32.ImageBase)) {
2198
-	if(nsections < 2 || buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase))
1850
+    found = 2;
1851
+
1852
+    if(epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 1].rva + EC32(optional_hdr32.ImageBase)) {
1853
+	if(nsections < 2 || epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase))
2199 1854
 	    found = 0;
2200 1855
 	else
2201 1856
 	    found = 1;
2202 1857
     }
2203 1858
 
2204
-    if((DCONF & PE_CONF_PETITE) && found) {
1859
+    if(found && (DCONF & PE_CONF_PETITE)) {
2205 1860
 	cli_dbgmsg("Petite: v2.%d compression detected\n", found);
2206 1861
 
2207
-	if(cli_readint32(buff + 0x80) == 0x163c988d) {
1862
+	if(cli_readint32(epbuff + 0x80) == 0x163c988d) {
2208 1863
 	    cli_dbgmsg("Petite: level zero compression is not supported yet\n");
2209 1864
 	} else {
2210 1865
 	    dsize = max - min;
2211 1866
 
2212
-	    if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) {
2213
-		cli_dbgmsg("Petite: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize);
2214
-		free(exe_sections);
2215
-		if(BLOCKMAX) {
2216
-		    *ctx->virname = "PE.Petite.ExceededFileSize";
2217
-		    return CL_VIRUS;
2218
-		} else {
2219
-		    return CL_CLEAN;
2220
-		}
2221
-	    }
1867
+	    CLI_UNPSIZELIMITS("Petite", dsize);
2222 1868
 
2223 1869
 	    if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
2224 1870
 		cli_dbgmsg("Petite: Can't allocate %d bytes\n", dsize);
... ...
@@ -2228,9 +1773,7 @@ skip_upack_and_go_to_next_unpacker:
2228 2228
 
2229 2229
 	    for(i = 0 ; i < nsections; i++) {
2230 2230
 		if(exe_sections[i].raw) {
2231
-		  uint32_t offset = exe_sections[i].raw;
2232
-
2233
-		  if(lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + exe_sections[i].rva - min, exe_sections[i].ursz) != exe_sections[i].ursz) {
2231
+		    if(!cli_seeksect(desc, &exe_sections[i]) || (unsigned int) cli_readn(desc, dest + exe_sections[i].rva - min, exe_sections[i].ursz) != exe_sections[i].ursz) {
2234 2232
 			free(exe_sections);
2235 2233
 			free(dest);
2236 2234
 			return CL_EIO;
... ...
@@ -2238,49 +1781,8 @@ skip_upack_and_go_to_next_unpacker:
2238 2238
 		}
2239 2239
 	    }
2240 2240
 
2241
-	    if(!(tempfile = cli_gentemp(NULL))) {
2242
-	      free(dest);
2243
-	      free(exe_sections);
2244
-	      return CL_EMEM;
2245
-	    }
2246
-
2247
-	    if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2248
-		cli_dbgmsg("Petite: Can't create file %s\n", tempfile);
2249
-		free(tempfile);
2250
-		free(exe_sections);
2251
-		free(dest);
2252
-		return CL_EIO;
2253
-	    }
2254
-
2255
-	    /* aCaB: Fixed to allow petite v2.1 unpacking (last section is a ghost) */
2256
-	    if (!petite_inflate2x_1to9(dest, min, max - min, exe_sections,
2257
-		    nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),
2258
-		    vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),
2259
-		    EC32(optional_hdr32.DataDirectory[2].Size))) {
2260
-	        cli_dbgmsg("Petite: Unpacked and rebuilt executable saved in %s\n", tempfile);
2261
-		cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
2262
-		free(dest);
2263
-		fsync(ndesc);
2264
-		lseek(ndesc, 0, SEEK_SET);
2265
-		if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2266
-		    free(exe_sections);
2267
-		    close(ndesc);
2268
-		    if(!cli_leavetemps_flag) {
2269
-		        unlink(tempfile);
2270
-		    }
2271
-		    free(tempfile);
2272
-		    return CL_VIRUS;
2273
-		}
2274
-
2275
-	    } else {
2276
-	        cli_dbgmsg("Petite: Unpacking failed\n");
2277
-		free(dest);
2278
-	    }
2279
-	    close(ndesc);
2280
-	    if(!cli_leavetemps_flag) {
2281
-	        unlink(tempfile);
2282
-	    }
2283
-	    free(tempfile);
2241
+	    CLI_UNPTEMP("Petite",dest,exe_sections);
2242
+	    CLI_UNPRESULTS("Petite",(petite_inflate2x_1to9(dest, min, max - min, exe_sections, nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),EC32(optional_hdr32.DataDirectory[2].Size))),0,dest);
2284 2243
 	}
2285 2244
     }
2286 2245
 
... ...
@@ -2289,20 +1791,11 @@ skip_upack_and_go_to_next_unpacker:
2289 2289
     if((DCONF & PE_CONF_PESPIN) && nsections > 1 &&
2290 2290
        vep >= exe_sections[nsections - 1].rva &&
2291 2291
        vep < exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz - 0x3217 - 4 &&
2292
-       memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0)  {
2292
+       memcmp(epbuff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0)  {
2293 2293
 
2294
-	    char *spinned;
2294
+	char *spinned;
2295 2295
 
2296
-	if(ctx->limits && ctx->limits->maxfilesize && fsize > ctx->limits->maxfilesize) {
2297
-	    cli_dbgmsg("PEspin: Size exceeded (fsize: %u, max: %lu)\n", fsize, ctx->limits->maxfilesize);
2298
-	    free(exe_sections);
2299
-	    if(BLOCKMAX) {
2300
-		*ctx->virname = "PE.Pespin.ExceededFileSize";
2301
-		return CL_VIRUS;
2302
-	    } else {
2303
-		return CL_CLEAN;
2304
-	    }
2305
-	}
2296
+	CLI_UNPSIZELIMITS("PEspin", fsize);
2306 2297
 
2307 2298
 	if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2308 2299
 	    free(exe_sections);
... ...
@@ -2317,61 +1810,8 @@ skip_upack_and_go_to_next_unpacker:
2317 2317
 	    return CL_EIO;
2318 2318
 	}
2319 2319
 
2320
-	if(!(tempfile = cli_gentemp(NULL))) {
2321
-	  free(spinned);
2322
-	  free(exe_sections);
2323
-	  return CL_EMEM;
2324
-	}
2325
-
2326
-	if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2327
-	    cli_dbgmsg("PESpin: Can't create file %s\n", tempfile);
2328
-	    free(tempfile);
2329
-	    free(spinned);
2330
-	    free(exe_sections);
2331
-	    return CL_EIO;
2332
-	}
2333
-
2334
-	switch(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)) {
2335
-	case 0:
2336
-	    free(spinned);
2337
-	    if(cli_leavetemps_flag)
2338
-		cli_dbgmsg("PESpin: Unpacked and rebuilt executable saved in %s\n", tempfile);
2339
-	    else
2340
-		cli_dbgmsg("PESpin: Unpacked and rebuilt executable\n");
2341
-	    fsync(ndesc);
2342
-	    lseek(ndesc, 0, SEEK_SET);
2343
-	    if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2344
-		close(ndesc);
2345
-		if(!cli_leavetemps_flag)
2346
-		    unlink(tempfile);
2347
-	        free(tempfile);
2348
-		free(exe_sections);
2349
-		return CL_VIRUS;
2350
-	    }
2351
-	    close(ndesc);
2352
-   	    if(!cli_leavetemps_flag)
2353
-		unlink(tempfile);
2354
-	    break;
2355
-	case 1:
2356
-	    free(spinned);
2357
-	    close(ndesc);
2358
-	    unlink(tempfile);
2359
-	    cli_dbgmsg("PESpin: Rebuilding failed\n");
2360
-	    break;
2361
-	case 2:
2362
-	    free(spinned);
2363
-	    close(ndesc);
2364
-	    unlink(tempfile);
2365
-	    cli_dbgmsg("PESpin: Size exceeded\n");
2366
-	    if(BLOCKMAX) {
2367
-		free(tempfile);
2368
-		free(exe_sections);
2369
-		*ctx->virname = "PE.Pespin.ExceededFileSize";
2370
-		return CL_VIRUS;
2371
-	    }
2372
-	}
2373
-	free(tempfile);
2374
-	
2320
+	CLI_UNPTEMP("PESpin",spinned,exe_sections);
2321
+	CLI_UNPRESULTS_("PEspin",SPINCASE(),(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)),0,spinned);
2375 2322
     }
2376 2323
 
2377 2324
 
... ...
@@ -2379,70 +1819,25 @@ skip_upack_and_go_to_next_unpacker:
2379 2379
 
2380 2380
     if((DCONF & PE_CONF_YC) && nsections > 1 &&
2381 2381
        EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60 &&
2382
-       memcmp(buff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0)  {
2382
+       memcmp(epbuff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0 && fsize >= exe_sections[nsections - 1].raw + 0xC6 + 0xb97)  {
2383 2383
 
2384
-	    char *spinned;
2384
+	char *spinned;
2385 2385
 
2386
-	if ( fsize >= exe_sections[nsections - 1].raw + 0xC6 + 0xb97 ) { /* size check on yC sect */
2387
-	  if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2386
+	if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2388 2387
 	    free(exe_sections);
2389 2388
 	    return CL_EMEM;
2390
-	  }
2389
+	}
2391 2390
 
2392
-	  lseek(desc, 0, SEEK_SET);
2393
-	  if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
2391
+	lseek(desc, 0, SEEK_SET);
2392
+	if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
2394 2393
 	    cli_dbgmsg("yC: Can't read %d bytes\n", fsize);
2395 2394
 	    free(spinned);
2396 2395
 	    free(exe_sections);
2397 2396
 	    return CL_EIO;
2398
-	  }
2399
-
2400
-	  if(!(tempfile = cli_gentemp(NULL))) {
2401
-	    free(spinned);
2402
-	    free(exe_sections);
2403
-	    return CL_EMEM;
2404
-	  }
2405
-
2406
-	  if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2407
-	    cli_dbgmsg("yC: Can't create file %s\n", tempfile);
2408
-	    free(tempfile);
2409
-	    free(spinned);
2410
-	    free(exe_sections);
2411
-	    return CL_EIO;
2412
-	  }
2413
-
2414
-	  if(!yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc)) {
2415
-	    free(spinned);
2416
-	    cli_dbgmsg("yC: Unpacked and rebuilt executable saved in %s\n", tempfile);
2417
-	    fsync(ndesc);
2418
-	    lseek(ndesc, 0, SEEK_SET);
2419
-	    
2420
-	    if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2421
-	      free(exe_sections);
2422
-	      close(ndesc);
2423
-	      if(!cli_leavetemps_flag) {
2424
-		unlink(tempfile);
2425
-		free(tempfile);
2426
-	      } else {
2427
-		free(tempfile);
2428
-	      }
2429
-	      return CL_VIRUS;
2430
-	    }
2431
-	    
2432
-	  } else {
2433
-	    free(spinned);
2434
-	    cli_dbgmsg("yC: Rebuilding failed\n");
2435
-	  }
2436
-	  
2437
-	  close(ndesc);
2438
-	  if(!cli_leavetemps_flag) {
2439
-	    unlink(tempfile);
2440
-	    free(tempfile);
2441
-	  } else {
2442
-	    free(tempfile);
2443
-	  }
2444
-
2445 2397
 	}
2398
+
2399
+	CLI_UNPTEMP("yC",spinned,exe_sections);
2400
+	CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc)),0,spinned);
2446 2401
     }
2447 2402
 
2448 2403
 
... ...
@@ -2452,154 +1847,121 @@ skip_upack_and_go_to_next_unpacker:
2452 2452
        exe_sections[nsections-1].raw>0x2b1 &&
2453 2453
        vep == exe_sections[nsections - 1].rva &&
2454 2454
        exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz == max &&
2455
-       memcmp(buff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
2456
-       memcmp(buff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0)  {
2457
-      uint32_t headsize=exe_sections[nsections - 1].raw;
2458
-      char *dest, *wwp;
2455
+       memcmp(epbuff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
2456
+       memcmp(epbuff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0)  {
2457
+	uint32_t headsize=exe_sections[nsections - 1].raw;
2458
+	char *dest, *wwp;
2459 2459
 
2460
-      for(i = 0 ; i < (unsigned int)nsections-1; i++)
2461
-	if (exe_sections[i].raw<headsize) headsize=exe_sections[i].raw;
2460
+	for(i = 0 ; i < (unsigned int)nsections-1; i++)
2461
+	    if (exe_sections[i].raw<headsize) headsize=exe_sections[i].raw;
2462 2462
       
2463
-      dsize = max-min+headsize-exe_sections[nsections - 1].rsz;
2463
+	dsize = max-min+headsize-exe_sections[nsections - 1].rsz;
2464 2464
 
2465
-      if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) {
2466
-	cli_dbgmsg("WWPack: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize);
2467
-	free(exe_sections);
2468
-	if(BLOCKMAX) {
2469
-	  *ctx->virname = "PE.WWPack.ExceededFileSize";
2470
-	  return CL_VIRUS;
2471
-	} else {
2472
-	  return CL_CLEAN;
2473
-	}
2474
-      }
2465
+	CLI_UNPSIZELIMITS("WWPack", dsize);
2475 2466
 
2476
-      if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
2477
-	cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
2478
-	free(exe_sections);
2479
-	return CL_EMEM;
2480
-      }
2481
-
2482
-      lseek(desc, 0, SEEK_SET);
2483
-      if((size_t) cli_readn(desc, dest, headsize) != headsize) {
2484
-	cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
2485
-	free(dest);
2486
-	free(exe_sections);
2487
-	return CL_EIO;
2488
-      }
2467
+	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
2468
+	    cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
2469
+	    free(exe_sections);
2470
+	    return CL_EMEM;
2471
+	}
2489 2472
 
2490
-      for(i = 0 ; i < (unsigned int)nsections-1; i++) {
2491
-	if(exe_sections[i].rsz) {
2492
-	  uint32_t offset = exe_sections[i].raw;
2493
-	  
2494
-	  if(lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + headsize + exe_sections[i].rva - min, exe_sections[i].rsz) != exe_sections[i].rsz) {
2473
+	lseek(desc, 0, SEEK_SET);
2474
+	if((size_t) cli_readn(desc, dest, headsize) != headsize) {
2475
+	    cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
2495 2476
 	    free(dest);
2496 2477
 	    free(exe_sections);
2497 2478
 	    return CL_EIO;
2498
-	  }
2499 2479
 	}
2500
-      }
2501 2480
 
2502
-      if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
2503
-	cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz);
2504
-	free(dest);
2505
-	free(exe_sections);
2506
-	return CL_EMEM;
2507
-      }
2481
+	for(i = 0 ; i < (unsigned int)nsections-1; i++) {
2482
+	    if(exe_sections[i].rsz) {
2483
+		if(!cli_seeksect(desc, &exe_sections[i]) || (unsigned int) cli_readn(desc, dest + headsize + exe_sections[i].rva - min, exe_sections[i].rsz) != exe_sections[i].rsz) {
2484
+		    free(dest);
2485
+		    free(exe_sections);
2486
+		    return CL_EIO;
2487
+		}
2488
+	    }
2489
+	}
2508 2490
 
2509
-      lseek(desc, exe_sections[nsections - 1].raw, SEEK_SET);
2510
-      if((size_t) cli_readn(desc, wwp, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
2511
-	cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
2512
-	free(dest);
2513
-	free(wwp);
2514
-	free(exe_sections);
2515
-	return CL_EIO;
2516
-      }
2491
+	if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
2492
+	    cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz);
2493
+	    free(dest);
2494
+	    free(exe_sections);
2495
+	    return CL_EMEM;
2496
+	}
2517 2497
 
2518
-      if (!wwunpack(dest, dsize, headsize, min, exe_sections[nsections-1].rva, e_lfanew, wwp, exe_sections[nsections - 1].rsz, nsections-1)) {
2498
+	if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, wwp, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
2499
+	    cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
2500
+	    free(dest);
2501
+	    free(wwp);
2502
+	    free(exe_sections);
2503
+	    return CL_EIO;
2504
+	}
2505
+
2506
+	if (!wwunpack(dest, dsize, headsize, min, exe_sections[nsections-1].rva, e_lfanew, wwp, exe_sections[nsections - 1].rsz, nsections-1)) {
2519 2507
 	
2520
-	free(wwp);
2508
+	    free(wwp);
2521 2509
 
2522
-	if(!(tempfile = cli_gentemp(NULL))) {
2523
-	  free(dest);
2524
-	  free(exe_sections);
2525
-	  return CL_EMEM;
2526
-	}
2510
+	    CLI_UNPTEMP("WWPack",dest,exe_sections);
2527 2511
 
2528
-	if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2529
-	  cli_dbgmsg("WWPack: Can't create file %s\n", tempfile);
2530
-	  free(tempfile);
2531
-	  free(dest);
2532
-	  free(exe_sections);
2533
-	  return CL_EIO;
2534
-	}
2512
+	    if((unsigned int) write(ndesc, dest, dsize) != dsize) {
2513
+		cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
2514
+		close(ndesc);
2515
+		free(tempfile);
2516
+		free(dest);
2517
+		free(exe_sections);
2518
+		return CL_EIO;
2519
+	    }
2535 2520
 
2536
-	if((unsigned int) write(ndesc, dest, dsize) != dsize) {
2537
-	  cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
2538
-	  close(ndesc);
2539
-	  free(tempfile);
2540
-	  free(dest);
2541
-	  free(exe_sections);
2542
-	  return CL_EIO;
2543
-	}
2521
+	    free(dest);
2522
+	    if (cli_leavetemps_flag)
2523
+		cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
2524
+	    else
2525
+		cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
2544 2526
 
2545
-	free(dest);
2546
-	if (cli_leavetemps_flag)
2547
-	  cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
2548
-	else
2549
-	  cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
2527
+	    fsync(ndesc);
2528
+	    lseek(ndesc, 0, SEEK_SET);
2550 2529
 
2551
-	fsync(ndesc);
2552
-	lseek(ndesc, 0, SEEK_SET);
2530
+	    if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2531
+		free(exe_sections);
2532
+		close(ndesc);
2533
+		if(!cli_leavetemps_flag)
2534
+		    unlink(tempfile);
2535
+		free(tempfile);
2536
+		return CL_VIRUS;
2537
+	    }
2553 2538
 
2554
-	if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2555
-	  free(exe_sections);
2556
-	  close(ndesc);
2557
-	  if(!cli_leavetemps_flag)
2558
-	    unlink(tempfile);
2559
-	  free(tempfile);
2560
-	  return CL_VIRUS;
2539
+	    close(ndesc);
2540
+	    if(!cli_leavetemps_flag)
2541
+		unlink(tempfile);
2542
+	    free(tempfile);
2543
+	} else {
2544
+	    free(wwp);
2545
+	    free(dest);
2546
+	    cli_dbgmsg("WWPpack: Decompression failed\n");
2561 2547
 	}
2562
-
2563
-	close(ndesc);
2564
-	if(!cli_leavetemps_flag)
2565
-	  unlink(tempfile);
2566
-	free(tempfile);
2567
-      } else {
2568
-	free(wwp);
2569
-	free(dest);
2570
-	cli_dbgmsg("WWPpack: Decompression failed\n");
2571
-      }
2572 2548
     }
2573 2549
 
2550
+
2574 2551
     /* ASPACK support */
2575
-    while((DCONF & PE_CONF_ASPACK) && ep+58+0x70e < fsize && !memcmp(buff,"\x60\xe8\x03\x00\x00\x00\xe9\xeb",8)) {
2576
-        char nbuff[6];
2552
+    while((DCONF & PE_CONF_ASPACK) && ep+58+0x70e < fsize && !memcmp(epbuff,"\x60\xe8\x03\x00\x00\x00\xe9\xeb",8)) {
2577 2553
 
2578
-        if(lseek(desc, ep+0x3b9, SEEK_SET) == -1) break;
2579
-        if(cli_readn(desc, nbuff, 6)!=6) break;
2580
-        if(memcmp(nbuff, "\x68\x00\x00\x00\x00\xc3",6)) break;
2554
+        if(epsize<0x3bf || memcmp(epbuff+0x3b9, "\x68\x00\x00\x00\x00\xc3",6)) break;
2581 2555
 	ssize = 0;
2582 2556
 	for(i=0 ; i< nsections ; i++)
2583
-	  if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
2584
-	    ssize=exe_sections[i].rva+exe_sections[i].vsz;
2557
+	    if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
2558
+		ssize=exe_sections[i].rva+exe_sections[i].vsz;
2585 2559
 	if(!ssize) break;
2586
-        if(ctx->limits && ctx->limits->maxfilesize && ssize > ctx->limits->maxfilesize) {
2587
-            cli_dbgmsg("Pe.Aspack: Size exceeded\n");
2588
-            free(exe_sections);
2589
-            if(BLOCKMAX) {
2590
-                *ctx->virname = "Pe.Aspack.ExceededFileSize";
2591
-                return CL_VIRUS;
2592
-            } else {
2593
-              return CL_CLEAN;
2594
-            }
2595
-        }
2560
+
2561
+	CLI_UNPSIZELIMITS("Aspack", ssize);
2562
+
2596 2563
         if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
2597 2564
 	    free(exe_sections);
2598 2565
 	    return CL_EMEM;
2599 2566
 	}
2600 2567
         for(i = 0 ; i < (unsigned int)nsections; i++) {
2601 2568
 	    if(!exe_sections[i].rsz) continue;
2602
-	    if(lseek(desc, exe_sections[i].raw, SEEK_SET) == -1) break;
2569
+	    if(!cli_seeksect(desc, &exe_sections[i])) break;
2603 2570
             if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
2604 2571
             if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
2605 2572
         }
... ...
@@ -2608,151 +1970,84 @@ skip_upack_and_go_to_next_unpacker:
2608 2608
             free(src);
2609 2609
             break;
2610 2610
         }
2611
-	if(!(tempfile = cli_gentemp(NULL))) {
2612
-	  free(exe_sections);
2613
-	  free(src);
2614
-	  return CL_EMEM;
2615
-	}
2616
-	if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2617
-	  cli_dbgmsg("Aspack: Can't create file %s\n", tempfile);
2618
-	  free(tempfile);
2619
-	  free(exe_sections);
2620
-	  free(src);
2621
-	  return CL_EIO;
2622
-	}
2623
-	if (unaspack212((uint8_t *)src, ssize, exe_sections, nsections, vep-1, EC32(optional_hdr32.ImageBase), ndesc)) {
2624
-	  free(src);
2625
-	  cli_dbgmsg("Aspack: Dumped to %s\n", tempfile);
2626
-	  fsync(ndesc);
2627
-	  lseek(ndesc, 0, SEEK_SET);
2628
-	  if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2629
-	      free(exe_sections);
2630
-	      close(ndesc);
2631
-	      if(!cli_leavetemps_flag)
2632
-		  unlink(tempfile);
2633
-	      free(tempfile);
2634
-	      return CL_VIRUS;
2635
-	  }
2636
-	} else {
2637
-	  free(src);
2638
-	}
2639
-
2640
-	close(ndesc);
2641
-	if(!cli_leavetemps_flag)
2642
-	  unlink(tempfile);
2643
-	free(tempfile);
2644 2611
 
2612
+	CLI_UNPTEMP("Aspack",src,exe_sections);
2613
+	CLI_UNPRESULTS("Aspack",(unaspack212((uint8_t *)src, ssize, exe_sections, nsections, vep-1, EC32(optional_hdr32.ImageBase), ndesc)),1,src);
2645 2614
 	break;
2646 2615
     }
2647 2616
 
2648 2617
     /* NsPack */
2649 2618
 
2650 2619
     while (DCONF & PE_CONF_NSPACK) {
2651
-      uint32_t eprva = vep;
2652
-      uint32_t start_of_stuff, ssize, dsize, rep = ep;
2653
-      unsigned int nowinldr;
2654
-      char nbuff[24];
2655
-      char *src=buff, *dest;
2656
-
2657
-      if (*buff=='\xe9') { /* bitched headers */
2658
-	eprva = cli_readint32(buff+1)+vep+5;
2659
-	if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
2660
-	if (lseek(desc, rep, SEEK_SET)==-1) break;
2661
-	if (cli_readn(desc, nbuff, 24)!=24) break;
2620
+	uint32_t eprva = vep;
2621
+	uint32_t start_of_stuff, ssize, dsize, rep = ep;
2622
+	unsigned int nowinldr;
2623
+	char nbuff[24];
2624
+	char *src=buff, *dest;
2625
+
2626
+	if (*epbuff=='\xe9') { /* bitched headers */
2627
+	    eprva = cli_readint32(epbuff+1)+vep+5;
2628
+	    if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
2629
+	    if (lseek(desc, rep, SEEK_SET)==-1) break;
2630
+	    if (cli_readn(desc, nbuff, 24)!=24) break;
2631
+	    src = nbuff;
2632
+	}
2633
+
2634
+	if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13)) break;
2635
+
2636
+	nowinldr = 0x54-cli_readint32(src+17);
2637
+	cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
2638
+
2639
+	if (lseek(desc, rep-nowinldr, SEEK_SET)==-1) break;
2640
+	if (cli_readn(desc, nbuff, 4)!=4) break;
2641
+	start_of_stuff=rep+cli_readint32(nbuff);
2642
+	if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2643
+	if (cli_readn(desc, nbuff, 20)!=20) break;
2662 2644
 	src = nbuff;
2663
-      }
2664
-
2665
-      if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13)) break;
2645
+	if (!cli_readint32(nbuff)) {
2646
+	    start_of_stuff+=4; /* FIXME: more to do */
2647
+	    src+=4;
2648
+	}
2666 2649
 
2667
-      nowinldr = 0x54-cli_readint32(src+17);
2668
-      cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
2650
+	ssize = cli_readint32(src+5)|0xff;
2651
+	dsize = cli_readint32(src+9);
2669 2652
 
2670
-      if (lseek(desc, rep-nowinldr, SEEK_SET)==-1) break;
2671
-      if (cli_readn(desc, nbuff, 4)!=4) break;
2672
-      start_of_stuff=rep+cli_readint32(nbuff);
2673
-      if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2674
-      if (cli_readn(desc, nbuff, 20)!=20) break;
2675
-      src = nbuff;
2676
-      if (!cli_readint32(nbuff)) {
2677
-	start_of_stuff+=4; /* FIXME: more to do */
2678
-	src+=4;
2679
-      }
2653
+	CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
2680 2654
 
2681
-      ssize = cli_readint32(src+5)|0xff;
2682
-      dsize = cli_readint32(src+9);
2655
+	if ( !ssize || !dsize || dsize != exe_sections[0].vsz) break;
2656
+	if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2657
+	if (!(dest=cli_malloc(dsize))) break;
2658
+	/* memset(dest, 0xfc, dsize); */
2683 2659
 
2684
-      if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
2685
-	cli_dbgmsg("NsPack: Size exceeded\n");
2686
-	free(exe_sections);
2687
-	if(BLOCKMAX) {
2688
-	  *ctx->virname = "PE.NsPack.ExceededFileSize";
2689
-	  return CL_VIRUS;
2690
-	} else {
2691
-	  return CL_CLEAN;
2660
+	if (!(src=cli_malloc(ssize))) {
2661
+	    free(dest);
2662
+	    break;
2692 2663
 	}
2693
-      }
2664
+	/* memset(src, 0x00, ssize); */
2665
+	cli_readn(desc, src, ssize);
2694 2666
 
2695
-      if ( !ssize || !dsize || dsize != exe_sections[0].vsz) break;
2696
-      if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2697
-      if (!(dest=cli_malloc(dsize))) break;
2698
-      /* memset(dest, 0xfc, dsize); */
2667
+	eprva+=0x27a;
2668
+	if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
2669
+	  free(dest);
2670
+	  free(src);
2671
+	  break;
2672
+	}
2673
+	if (lseek(desc, rep, SEEK_SET)==-1) {
2674
+	  free(dest);
2675
+	  free(src);
2676
+	  break;
2677
+	}
2678
+	if (cli_readn(desc, nbuff, 5)!=5) {
2679
+	  free(dest);
2680
+	  free(src);
2681
+	  break;
2682
+	}
2683
+	eprva=eprva+5+cli_readint32(nbuff+1);
2684
+	cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
2699 2685
 
2700
-      if (!(src=cli_malloc(ssize))) {
2701
-	free(dest);
2686
+	CLI_UNPTEMP("NsPack",src,dest,exe_sections);
2687
+	CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,src,dest);
2702 2688
 	break;
2703
-      }
2704
-      /* memset(src, 0x00, ssize); */
2705
-      cli_readn(desc, src, ssize);
2706
-
2707
-      eprva+=0x27a;
2708
-      if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
2709
-      if (lseek(desc, rep, SEEK_SET)==-1) break;
2710
-      if (cli_readn(desc, nbuff, 5)!=5) break;
2711
-      eprva=eprva+5+cli_readint32(nbuff+1);
2712
-      cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
2713
-
2714
-      if(!(tempfile = cli_gentemp(NULL))) {
2715
-	free(src);
2716
-	free(dest);
2717
-	free(exe_sections);
2718
-	return CL_EMEM;
2719
-      }
2720
-
2721
-      if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2722
-	cli_dbgmsg("NsPack: Can't create file %s\n", tempfile);
2723
-	free(tempfile);
2724
-	free(src);
2725
-	free(dest);
2726
-	free(exe_sections);
2727
-	return CL_EIO;
2728
-      }
2729
-
2730
-      if (!unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)) {
2731
-	free(src);
2732
-	free(dest);
2733
-	if (cli_leavetemps_flag)
2734
-	  cli_dbgmsg("NsPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
2735
-	else
2736
-	  cli_dbgmsg("NsPack: Unpacked and rebuilt executable\n");
2737
-	fsync(ndesc);
2738
-	lseek(ndesc, 0, SEEK_SET);
2739
-
2740
-	if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2741
-	  free(exe_sections);
2742
-	  close(ndesc);
2743
-	  if(!cli_leavetemps_flag) unlink(tempfile);
2744
-	  free(tempfile);
2745
-	  return CL_VIRUS;
2746
-	}
2747
-      } else {
2748
-	free(src);
2749
-	free(dest);
2750
-	cli_dbgmsg("NsPack: Unpacking failed\n");
2751
-      }
2752
-      close(ndesc);
2753
-      if(!cli_leavetemps_flag) unlink(tempfile);
2754
-      free(tempfile);
2755
-      break;
2756 2689
     }
2757 2690
 
2758 2691
     /* to be continued ... */