Browse code

Added support for wwwpack32 - not yet enabled

git-svn: trunk@2087

aCaB authored on 2006/07/17 04:49:42
Showing 6 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Jul 16 21:42:58 CEST 2006 (acab)
2
+------------------------------------
3
+  * libclamav: added support for wwpack32 - not yet activated
4
+
1 5
 Sat Jul 15 21:33:22 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav/message.c:	Some HTML.Phishing.Bank-1 were getting through,
... ...
@@ -92,6 +92,8 @@ libclamav_la_SOURCES = \
92 92
 	rebuildpe.h \
93 93
 	petite.c \
94 94
 	petite.h \
95
+	wwunpack.c \
96
+	wwunpack.h \
95 97
 	fsg.c \
96 98
 	fsg.h \
97 99
 	line.c \
... ...
@@ -82,11 +82,11 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \
82 82
 	filetypes.lo blob.lo mbox.lo message.lo snprintf.lo table.lo \
83 83
 	text.lo ole2_extract.lo vba_extract.lo msexpand.lo pe.lo \
84 84
 	cabd.lo lzxd.lo mszipd.lo qtmd.lo system.lo upx.lo htmlnorm.lo \
85
-	chmunpack.lo rebuildpe.lo petite.lo fsg.lo line.lo untar.lo \
86
-	unzip.lo special.lo binhex.lo is_tar.lo tnef.lo unrar15.lo \
87
-	unrarvm.lo unrar.lo unrarfilter.lo unrarppm.lo unrar20.lo \
88
-	unrarcmd.lo pdf.lo spin.lo yc.lo elf.lo sis.lo uuencode.lo \
89
-	pst.lo
85
+	chmunpack.lo rebuildpe.lo petite.lo wwunpack.lo fsg.lo line.lo \
86
+	untar.lo unzip.lo special.lo binhex.lo is_tar.lo tnef.lo \
87
+	unrar15.lo unrarvm.lo unrar.lo unrarfilter.lo unrarppm.lo \
88
+	unrar20.lo unrarcmd.lo pdf.lo spin.lo yc.lo elf.lo sis.lo \
89
+	uuencode.lo pst.lo
90 90
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
91 91
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
92 92
 depcomp = $(SHELL) $(top_srcdir)/depcomp
... ...
@@ -291,6 +291,8 @@ libclamav_la_SOURCES = \
291 291
 	rebuildpe.h \
292 292
 	petite.c \
293 293
 	petite.h \
294
+	wwunpack.c \
295
+	wwunpack.h \
294 296
 	fsg.c \
295 297
 	fsg.h \
296 298
 	line.c \
... ...
@@ -459,6 +461,7 @@ distclean-compile:
459 459
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upx.Plo@am__quote@
460 460
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uuencode.Plo@am__quote@
461 461
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vba_extract.Plo@am__quote@
462
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wwunpack.Plo@am__quote@
462 463
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yc.Plo@am__quote@
463 464
 
464 465
 .c.o:
... ...
@@ -41,6 +41,9 @@
41 41
 #include "spin.h"
42 42
 #include "upx.h"
43 43
 #include "yc.h"
44
+#ifdef WWP32
45
+#include "wwunpack.h"
46
+#endif
44 47
 #include "scanners.h"
45 48
 #include "rebuildpe.h"
46 49
 #include "str.h"
... ...
@@ -374,7 +377,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
374 374
     if(!pe_plus) { /* PE */
375 375
 
376 376
 	if(read(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
377
-	    cli_dbgmsg("Can't optional file header\n");
377
+	    cli_dbgmsg("Can't read optional file header\n");
378 378
 	    if(DETECT_BROKEN) {
379 379
 		if(ctx->virname)
380 380
 		    *ctx->virname = "Broken.Executable";
... ...
@@ -1557,8 +1560,10 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1557 1557
 	    free(src);
1558 1558
 	    free(section_hdr);
1559 1559
 
1560
-	    if(!(tempfile = cli_gentemp(NULL)))
1560
+	    if(!(tempfile = cli_gentemp(NULL))) {
1561
+	        free(dest);
1561 1562
 		return CL_EMEM;
1563
+	    }
1562 1564
 
1563 1565
 	    if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1564 1566
 		cli_dbgmsg("UPX/FSG: Can't create file %s\n", tempfile);
... ...
@@ -1654,8 +1659,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1654 1654
 		}
1655 1655
 	    }
1656 1656
 
1657
-	    if(!(tempfile = cli_gentemp(NULL)))
1658
-		return CL_EMEM;
1657
+	    if(!(tempfile = cli_gentemp(NULL))) {
1658
+	      free(dest);
1659
+	      free(section_hdr);
1660
+	      return CL_EMEM;
1661
+	    }
1659 1662
 
1660 1663
 	    if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1661 1664
 		cli_dbgmsg("Petite: Can't create file %s\n", tempfile);
... ...
@@ -1733,8 +1741,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1733 1733
 	    return CL_EIO;
1734 1734
 	}
1735 1735
 
1736
-	if(!(tempfile = cli_gentemp(NULL)))
1737
-	    return CL_EMEM;
1736
+	if(!(tempfile = cli_gentemp(NULL))) {
1737
+	  free(spinned);
1738
+	  free(section_hdr);
1739
+	  return CL_EMEM;
1740
+	}
1738 1741
 
1739 1742
 	if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1740 1743
 	    cli_dbgmsg("PESpin: Can't create file %s\n", tempfile);
... ...
@@ -1799,8 +1810,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1799 1799
 	    return CL_EIO;
1800 1800
 	  }
1801 1801
 
1802
-	  if(!(tempfile = cli_gentemp(NULL)))
1803
-	      return CL_EMEM;
1802
+	  if(!(tempfile = cli_gentemp(NULL))) {
1803
+	    free(spinned);
1804
+	    free(section_hdr);
1805
+	    return CL_EMEM;
1806
+	  }
1804 1807
 
1805 1808
 	  if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1806 1809
 	    cli_dbgmsg("yC: Can't create file %s\n", tempfile);
... ...
@@ -1844,6 +1858,130 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1844 1844
 	}
1845 1845
     }
1846 1846
 
1847
+#ifdef WWP32
1848
+    /* WWPack */
1849
+
1850
+    if(nsections > 1 &&
1851
+       EC32(section_hdr[nsections-1].SizeOfRawData)>0x2b1 &&
1852
+       EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) &&
1853
+       EC32(section_hdr[nsections - 1].VirtualAddress)+EC32(section_hdr[nsections - 1].SizeOfRawData) == max &&
1854
+       memcmp(buff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
1855
+       memcmp(buff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0)  {
1856
+      uint32_t headsize=EC32(section_hdr[nsections - 1].PointerToRawData);
1857
+      char *dest, *wwp;
1858
+
1859
+      for(i = 0 ; i < nsections-1; i++) {
1860
+	uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1861
+	if (!err && offset<headsize) headsize=offset;
1862
+      }
1863
+      
1864
+      dsize = max-min+headsize-EC32(section_hdr[nsections - 1].SizeOfRawData);
1865
+
1866
+      if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) {
1867
+	cli_dbgmsg("WWPack: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize);
1868
+	free(section_hdr);
1869
+	if(BLOCKMAX) {
1870
+	  *ctx->virname = "PE.WWPack.ExceededFileSize";
1871
+	  return CL_VIRUS;
1872
+	} else {
1873
+	  return CL_CLEAN;
1874
+	}
1875
+      }
1876
+
1877
+      if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1878
+	cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
1879
+	free(section_hdr);
1880
+	return CL_EMEM;
1881
+      }
1882
+      memset(dest, 0, dsize);
1883
+
1884
+      lseek(desc, 0, SEEK_SET);
1885
+      if((size_t) read(desc, dest, headsize) != headsize) {
1886
+	cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
1887
+	free(dest);
1888
+	free(section_hdr);
1889
+	return CL_EIO;
1890
+      }
1891
+
1892
+      for(i = 0 ; i < nsections-1; i++) {
1893
+	if(section_hdr[i].SizeOfRawData) {
1894
+	  uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1895
+	  
1896
+	  if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) read(desc, dest + headsize + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
1897
+	    free(dest);
1898
+	    free(section_hdr);
1899
+	    return CL_EIO;
1900
+	  }
1901
+	}
1902
+      }
1903
+
1904
+      if((wwp = (char *) cli_calloc(EC32(section_hdr[nsections - 1].SizeOfRawData), sizeof(char))) == NULL) {
1905
+	cli_dbgmsg("WWPack: Can't allocate %d bytes\n", EC32(section_hdr[nsections - 1].SizeOfRawData));
1906
+	free(dest);
1907
+	free(section_hdr);
1908
+	return CL_EMEM;
1909
+      }
1910
+
1911
+      lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData), SEEK_SET);      
1912
+      if((size_t) read(desc, wwp, EC32(section_hdr[nsections - 1].SizeOfRawData)) != EC32(section_hdr[nsections - 1].SizeOfRawData)) {
1913
+	cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", EC32(section_hdr[nsections - 1].SizeOfRawData));
1914
+	free(dest);
1915
+	free(wwp);
1916
+	free(section_hdr);
1917
+	return CL_EIO;
1918
+      }
1919
+
1920
+      if (!wwunpack(dest, dsize, headsize, min, EC32(section_hdr[nsections-1].VirtualAddress),  e_lfanew, wwp, EC32(section_hdr[nsections - 1].SizeOfRawData), nsections-1)) {
1921
+	
1922
+	free(wwp);
1923
+
1924
+	if(!(tempfile = cli_gentemp(NULL)))
1925
+	  return CL_EMEM;
1926
+
1927
+	if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1928
+	  cli_dbgmsg("WWPack: Can't create file %s\n", tempfile);
1929
+	  free(tempfile);
1930
+	  free(dest);
1931
+	  free(section_hdr);
1932
+	  return CL_EIO;
1933
+	}
1934
+
1935
+	if((unsigned int) write(ndesc, dest, dsize) != dsize) {
1936
+	  cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
1937
+	  close(ndesc);
1938
+	  free(tempfile);
1939
+	  free(dest);
1940
+	  free(section_hdr);
1941
+	  return CL_EIO;
1942
+	}
1943
+
1944
+	free(dest);
1945
+	cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
1946
+	fsync(ndesc);
1947
+	lseek(ndesc, 0, SEEK_SET);
1948
+
1949
+	if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1950
+	  free(section_hdr);
1951
+	  close(ndesc);
1952
+	  if(!cli_leavetemps_flag)
1953
+	    unlink(tempfile);
1954
+	  free(tempfile);
1955
+	  return CL_VIRUS;
1956
+	}
1957
+
1958
+	close(ndesc);
1959
+	if(!cli_leavetemps_flag)
1960
+	  unlink(tempfile);
1961
+	free(tempfile);
1962
+      } else {
1963
+	free(wwp);
1964
+	free(dest);
1965
+	cli_dbgmsg("WWPpack: Decompression failed\n");
1966
+      }
1967
+    }
1968
+#endif
1969
+
1970
+
1847 1971
     /* to be continued ... */
1848 1972
 
1849 1973
     free(section_hdr);
1850 1974
new file mode 100644
... ...
@@ -0,0 +1,361 @@
0
+/*
1
+ *  Copyright (C) 2006 aCaB <acab@clamav.net>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License as published by
5
+ *  the Free Software Foundation; either version 2 of the License, or
6
+ *  (at your option) any later version.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+ *  MA 02110-1301, USA.
17
+ */
18
+
19
+/*
20
+** wwunpack.c
21
+** 09/07/2k6 - Campioni del mondo!!!
22
+** 14/07/2k6 - RCE'ed + standalone sect unpacker
23
+** 15/07/2k6 - Merge started
24
+** 17/07/2k6 - Rebuild
25
+**
26
+*/
27
+
28
+/*
29
+** Unpacks+rebuilds WWPack32 1.20
30
+**
31
+** Just boooooring stuff, blah.
32
+**
33
+*/
34
+
35
+
36
+/*
37
+** TODO:
38
+**
39
+** use cli_readint32
40
+** add bound checks
41
+** check eax vs al
42
+**
43
+*/
44
+
45
+#ifdef WWP32
46
+
47
+#if HAVE_CONFIG_H
48
+#include "clamav-config.h"
49
+#endif
50
+
51
+#include <stdio.h>
52
+#include <stdlib.h>
53
+#include <sys/types.h>
54
+#include <sys/stat.h>
55
+#include <unistd.h>
56
+#include <string.h>
57
+
58
+#include "cltypes.h"
59
+#include "pe.h"
60
+#include "rebuildpe.h"
61
+#include "others.h"
62
+#include "wwunpack.h"
63
+
64
+static void getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, char **src) {
65
+  *eax=*bitmap>>(32-X);
66
+  if (*bits>X) {
67
+    *bitmap<<=X;
68
+    *bits-=X;
69
+  } else if (*bits<X) {
70
+    X-=*bits;
71
+    *eax>>=X;
72
+    *bitmap=*(uint32_t *)(*src);
73
+    *src+=4;
74
+    *eax<<=X;
75
+    *eax|=*bitmap>>(32-X);
76
+    *bitmap<<=X;
77
+    *bits=32-X;
78
+  } else {
79
+    *bitmap=*(uint32_t *)(*src);
80
+    *src+=4;
81
+    *bits=32;
82
+  }
83
+}
84
+
85
+
86
+static void wunpsect(char *src, char *dst) {
87
+  uint32_t bitmap, eax;
88
+  uint8_t bits;
89
+  unsigned int lostbit, getmorestuff;
90
+  uint16_t backbytes;
91
+  uint16_t backsize;
92
+  uint8_t oal;
93
+
94
+  eax=bitmap=*(uint32_t *)src;
95
+  src+=4;
96
+  bits=32;
97
+
98
+
99
+  while (1) {
100
+    lostbit=bitmap>>31;
101
+    bitmap<<=1;
102
+    bits--;
103
+    if (!lostbit && bits) {
104
+      *dst++=*src++;
105
+      continue;
106
+    }
107
+    
108
+    if (!bits) {
109
+      eax=bitmap=*(uint32_t *)src;
110
+      bits=32;
111
+      src+=4;
112
+      if (!lostbit) {
113
+	*dst++=*src++;
114
+	continue;
115
+      }
116
+    }
117
+    
118
+    getbits(2, &eax, &bitmap, &bits, &src);
119
+    
120
+    if ((eax&0xff)>=3) {
121
+      /* 50ff - two_bytes */
122
+      uint8_t fetchbits;
123
+      
124
+      getbits(2, &eax, &bitmap, &bits, &src);
125
+      fetchbits=(eax&0xff)+5;
126
+      eax--;
127
+      if ((int16_t)(eax&0xffff)<=0) {
128
+	/* 5113 */
129
+	backbytes=1<<fetchbits;
130
+	backbytes=(backbytes&0xff00)|((backbytes-31)&0xff);
131
+      } else {
132
+	/* 511b */
133
+	fetchbits++;
134
+	backbytes=1<<fetchbits;
135
+	backbytes-=0x9f;
136
+      }
137
+      /* 5125 */
138
+      getbits(fetchbits, &eax, &bitmap, &bits, &src);
139
+      if ((eax&0xffff)==0x1ff) break;
140
+      eax&=0xffff;
141
+      backbytes+=eax;
142
+      *dst=*(dst-backbytes);
143
+      dst++;
144
+      *dst=*(dst-backbytes);
145
+      dst++;
146
+      continue;
147
+    }
148
+
149
+    /* 5143 - more_backbytes */      
150
+    oal=eax&0xff;
151
+    getmorestuff=1;
152
+    /* FIXME: pushf */
153
+    
154
+    getbits(3, &eax, &bitmap, &bits, &src);
155
+    if ((eax&0xff)<=3) {
156
+      lostbit=0;
157
+      if ((eax&0xff)==3) {
158
+	/* next_bit_or_reseed */
159
+	lostbit=bitmap>>31;
160
+	bitmap<<=1;
161
+	bits--;
162
+	if (!bits) { 
163
+	  bitmap=*(uint32_t *)src;
164
+	  bits=32;
165
+	  src+=4;
166
+	}
167
+      }
168
+      eax=eax+lostbit+5;
169
+      /* FIXME: jmp more_bb_commondock */
170
+    } else { /* >3 */
171
+      /* 5160 - more_bb_morethan3 */
172
+      if ((eax&0xff)==4) {
173
+	/* next_bit_or_reseed */
174
+	lostbit=bitmap>>31;
175
+	bitmap<<=1;
176
+	bits--;
177
+	if (!bits) { 
178
+	  bitmap=*(uint32_t *)src;
179
+	  bits=32;
180
+	  src+=4;
181
+	}
182
+	eax=eax+lostbit+6;
183
+	/* FIXME: jmp more_bb_commondock */
184
+      } else { /* !=4 */
185
+	eax+=7;
186
+	if ((eax&0xff)>=0x0d) {
187
+	  getmorestuff=0; /* jmp more_bb_PASTcommondock */
188
+	  if ((eax&0xff)==0x0d) {
189
+	    /* 5179  */
190
+	    getbits(0x0e, &eax, &bitmap, &bits, &src);
191
+	    eax+=0x1fe1;
192
+	  } else {
193
+	    /* 516c */
194
+	    getbits(0x0f, &eax, &bitmap, &bits, &src);
195
+	    eax+=0x5fe1;
196
+	  }
197
+	  /* FIXME: jmp more_bb_PASTcommondock */
198
+	} /* al >= 0d */
199
+      } /* al != 4 */
200
+    } /* >3 */
201
+    
202
+    if (getmorestuff) {
203
+      /* 5192 - more_bb_commondock */
204
+      uint16_t bk=(1<<(eax&0xff))-0x1f;
205
+      getbits((eax&0xff), &eax, &bitmap, &bits, &src);
206
+      eax+=bk;
207
+    }
208
+    
209
+    /* 51a7 - more_bb_pastcommondock */
210
+    eax&=0xffff;
211
+    backbytes=eax;
212
+    backsize=3+(oal!=1); /* FIXME: move up and remove oal */
213
+    
214
+    if (oal<1) { /* overrides backsize */
215
+      /* 51bb - more_bb_again */
216
+      
217
+      /* next_bit_or_reseed */
218
+      lostbit=bitmap>>31;
219
+      bitmap<<=1;
220
+      bits--;
221
+      if (!bits) { 
222
+	bitmap=*(uint32_t *)src;
223
+	bits=32;
224
+	src+=4;
225
+      }
226
+      if (!lostbit) {
227
+	/* 51c2 */
228
+	/* next_bit_or_reseed */
229
+	lostbit=bitmap>>31;
230
+	bitmap<<=1;
231
+	bits--;
232
+	if (!bits) { 
233
+	  bitmap=*(uint32_t *)src;
234
+	  bits=32;
235
+	  src+=4;
236
+	}
237
+	eax=5+lostbit;
238
+	/* FIXME: jmp setsize_and_backcopy */
239
+      } else {
240
+	/* 51ce - more_bb_again_and_again */
241
+	getbits(3, &eax, &bitmap, &bits, &src);
242
+	if (eax&0xff) {
243
+	  /* 51e6 */
244
+	  eax+=6;
245
+	  /* FIXME: jmp setsize_and_backcopy */
246
+	} else {
247
+	  getbits(4, &eax, &bitmap, &bits, &src);
248
+	  if (eax&0xff) {
249
+	    /* 51e4 */
250
+	    eax+=7+6;
251
+	    /* FIXME: jmp setsize_and_backcopy */
252
+	  } else {
253
+	    /* 51ea - OMGWTF */
254
+	    uint8_t c=4;
255
+	    uint16_t d=0x0d;
256
+	    
257
+	    while ( 1 ) {
258
+	      if (c!=7){
259
+		d+=2;
260
+		d<<=1;
261
+		d--;
262
+		
263
+		/* next_bit_or_reseed */
264
+		lostbit=bitmap>>31;
265
+		bitmap<<=1;
266
+		bits--;
267
+		if (!bits) { 
268
+		  bitmap=*(uint32_t *)src;
269
+		  bits=32;
270
+		  src+=4;
271
+		}
272
+		c++;
273
+		if (!lostbit) continue;
274
+		getbits(c, &eax, &bitmap, &bits, &src);
275
+		d+=eax&0xff;
276
+		eax&=0xffffff00;
277
+		eax|=d&0xff;
278
+	      } else {
279
+		getbits(14, &eax, &bitmap, &bits, &src);
280
+	      }
281
+	      break;
282
+	    } /* while */
283
+	  } /* OMGWTF */
284
+	} /* eax&0xff */
285
+      } /* lostbit */
286
+	/* 521b - setsize_and_backcopy */
287
+      backsize=eax&0xffff;
288
+    }
289
+
290
+    /* 521e - backcopy */
291
+    while(backsize--){
292
+      *dst=*(dst-backbytes);
293
+      dst++;
294
+    }
295
+
296
+  } /* while true */
297
+  
298
+}
299
+
300
+int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_t wwprva, uint32_t e_lfanew, char *wwp, uint32_t wwpsz, uint16_t sects) {
301
+  char *stuff=wwp+0x2a1, *packed, *unpacked;
302
+  uint32_t rva, csize;
303
+
304
+  cli_dbgmsg("in wwunpack\n");
305
+
306
+
307
+  while(1) {
308
+    if (!CLI_ISCONTAINED(wwp, wwpsz, stuff, 17)) {
309
+      cli_dbgmsg("WWPack: next chunk out ouf file, giving up.\n");
310
+      return 1;
311
+    }
312
+    if ((csize=cli_readint32(stuff+8)*4)!=cli_readint32(stuff+12)+4) {
313
+      cli_dbgmsg("WWPack: inconsistent/hacked data, go figure!\n");
314
+      return 1;
315
+    }
316
+    rva = wwprva-cli_readint32(stuff);
317
+    if((packed = (char *) cli_calloc(csize, sizeof(char))) == NULL) {
318
+      cli_dbgmsg("WWPack: Can't allocate %d bytes\n", csize);
319
+      return 1;
320
+    }
321
+    unpacked=exe+headsize+rva-min;
322
+    if (!CLI_ISCONTAINED(exe, exesz, unpacked, csize)) {
323
+      cli_dbgmsg("WWPack: packed data out of bounds, giving up.\n");
324
+      return 1;
325
+    }
326
+    memcpy(packed, unpacked, csize);
327
+    wunpsect(packed, unpacked);
328
+    free(packed);
329
+    if (!stuff[16]) break;
330
+    stuff+=17;
331
+  }
332
+
333
+  stuff=exe+e_lfanew;
334
+  stuff[6]=sects&0xff;
335
+  stuff[7]=sects>>8;
336
+
337
+  csize=cli_readint32(wwp+0x295)+wwprva+0x299;
338
+  cli_dbgmsg("WWPack: found OEP @%x\n", csize);
339
+  cli_writeint32(stuff+0x28, csize);
340
+
341
+#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
342
+#define FIXVS(v, r) (VAALIGN((r>v)?r:v))
343
+
344
+  stuff+=0xf8;
345
+  while (sects--) {
346
+    uint32_t v=cli_readint32(stuff+8);
347
+    uint32_t r=cli_readint32(stuff+16);
348
+    csize=FIXVS(v, r);
349
+    cli_writeint32(stuff+8, csize);
350
+    cli_writeint32(stuff+16, csize);
351
+    cli_writeint32(stuff+20, cli_readint32(stuff+12)-min+headsize);
352
+    stuff+=0x28;
353
+  }
354
+  memset(stuff, 0, 0x28);
355
+
356
+  cli_dbgmsg("WWPack: Successfully rebuilt\n", csize);
357
+  return 0;
358
+}
359
+
360
+#endif
0 361
new file mode 100644
... ...
@@ -0,0 +1,28 @@
0
+/*
1
+ *  Copyright (C) 2006 aCaB <acab@clamav.net>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License as published by
5
+ *  the Free Software Foundation; either version 2 of the License, or
6
+ *  (at your option) any later version.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+ *  MA 02110-1301, USA.
17
+ */
18
+
19
+#ifndef __WWP32_H
20
+#define __WWP32_H
21
+
22
+#include "cltypes.h"
23
+#include "rebuildpe.h"
24
+
25
+int wwunpack(char *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, char *, uint32_t, uint16_t);
26
+
27
+#endif