Browse code

Activated wwwpack32

git-svn: trunk@2088

aCaB authored on 2006/07/17 08:20:13
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Jul 17 01:17:40 CEST 2006 (acab)
2
+------------------------------------
3
+  * libclamav: wwpack32 handler secured and activated
4
+
1 5
 Sun Jul 16 21:42:58 CEST 2006 (acab)
2 6
 ------------------------------------
3 7
   * libclamav: added support for wwpack32 - not yet activated
... ...
@@ -41,9 +41,7 @@
41 41
 #include "spin.h"
42 42
 #include "upx.h"
43 43
 #include "yc.h"
44
-#ifdef WWP32
45 44
 #include "wwunpack.h"
46
-#endif
47 45
 #include "scanners.h"
48 46
 #include "rebuildpe.h"
49 47
 #include "str.h"
... ...
@@ -1858,7 +1856,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1858 1858
 	}
1859 1859
     }
1860 1860
 
1861
-#ifdef WWP32
1861
+
1862 1862
     /* WWPack */
1863 1863
 
1864 1864
     if(nsections > 1 &&
... ...
@@ -1870,7 +1868,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1870 1870
       uint32_t headsize=EC32(section_hdr[nsections - 1].PointerToRawData);
1871 1871
       char *dest, *wwp;
1872 1872
 
1873
-      for(i = 0 ; i < nsections-1; i++) {
1873
+      for(i = 0 ; i < (unsigned int)nsections-1; i++) {
1874 1874
 	uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1875 1875
 	if (!err && offset<headsize) headsize=offset;
1876 1876
       }
... ...
@@ -1903,7 +1901,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1903 1903
 	return CL_EIO;
1904 1904
       }
1905 1905
 
1906
-      for(i = 0 ; i < nsections-1; i++) {
1906
+      for(i = 0 ; i < (unsigned int)nsections-1; i++) {
1907 1907
 	if(section_hdr[i].SizeOfRawData) {
1908 1908
 	  uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1909 1909
 	  
... ...
@@ -1979,7 +1977,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1979 1979
 	cli_dbgmsg("WWPpack: Decompression failed\n");
1980 1980
       }
1981 1981
     }
1982
-#endif
1983 1982
 
1984 1983
 
1985 1984
     /* to be continued ... */
... ...
@@ -19,10 +19,12 @@
19 19
 
20 20
 /*
21 21
 ** wwunpack.c
22
+**
22 23
 ** 09/07/2k6 - Campioni del mondo!!!
23 24
 ** 14/07/2k6 - RCE'ed + standalone sect unpacker
24 25
 ** 15/07/2k6 - Merge started
25 26
 ** 17/07/2k6 - Rebuild
27
+** 18/07/2k6 - Secured (well, hopefully...)
26 28
 **
27 29
 */
28 30
 
... ...
@@ -37,13 +39,14 @@
37 37
 /*
38 38
 ** TODO:
39 39
 **
40
-** use cli_readint32
41
-** add bound checks
40
+** review
42 41
 ** check eax vs al
42
+** check the missed samples
43
+** (check for dll's)
44
+** (have a look at older versions)
43 45
 **
44 46
 */
45 47
 
46
-#ifdef WWP32
47 48
 
48 49
 #if HAVE_CONFIG_H
49 50
 #include "clamav-config.h"
... ...
@@ -62,7 +65,19 @@
62 62
 #include "others.h"
63 63
 #include "wwunpack.h"
64 64
 
65
-static void getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, char **src) {
65
+#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
66
+#define FIXVS(v, r) (VAALIGN((r>v)?r:v))
67
+
68
+
69
+static int getbitmap(uint32_t *bitmap, char **src, uint8_t *bits, char *buf, unsigned int size) {
70
+  if (! CLI_ISCONTAINED(buf, size, *src, 4)) return 1;
71
+  *bitmap=cli_readint32(*src);
72
+  *src+=4;
73
+  *bits=32;
74
+  return 0;
75
+}
76
+
77
+static int getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, char **src, char *buf, unsigned int size) {
66 78
   *eax=*bitmap>>(32-X);
67 79
   if (*bits>X) {
68 80
     *bitmap<<=X;
... ...
@@ -70,21 +85,19 @@ static void getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, c
70 70
   } else if (*bits<X) {
71 71
     X-=*bits;
72 72
     *eax>>=X;
73
-    *bitmap=*(uint32_t *)(*src);
74
-    *src+=4;
73
+    if (getbitmap(bitmap, src, bits, buf, size)) return 1;
75 74
     *eax<<=X;
76 75
     *eax|=*bitmap>>(32-X);
77 76
     *bitmap<<=X;
78
-    *bits=32-X;
77
+    *bits-=X;
79 78
   } else {
80
-    *bitmap=*(uint32_t *)(*src);
81
-    *src+=4;
82
-    *bits=32;
79
+    if (getbitmap(bitmap, src, bits, buf, size)) return 1;
83 80
   }
81
+  return 0;
84 82
 }
85 83
 
86
-
87
-static void wunpsect(char *src, char *dst) {
84
+static int wunpsect(char *packed, char *unpacked, unsigned int psize, unsigned int usize) {
85
+  char *src=packed, *dst=unpacked;
88 86
   uint32_t bitmap, eax;
89 87
   uint8_t bits;
90 88
   unsigned int lostbit, getmorestuff;
... ...
@@ -92,37 +105,36 @@ static void wunpsect(char *src, char *dst) {
92 92
   uint16_t backsize;
93 93
   uint8_t oal;
94 94
 
95
-  eax=bitmap=*(uint32_t *)src;
96
-  src+=4;
97
-  bits=32;
98
-
95
+  if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
96
+  eax=bitmap;
99 97
 
100 98
   while (1) {
101 99
     lostbit=bitmap>>31;
102 100
     bitmap<<=1;
103 101
     bits--;
104 102
     if (!lostbit && bits) {
103
+      if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
105 104
       *dst++=*src++;
106 105
       continue;
107 106
     }
108 107
     
109 108
     if (!bits) {
110
-      eax=bitmap=*(uint32_t *)src;
111
-      bits=32;
112
-      src+=4;
109
+      if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
110
+      eax=bitmap;
113 111
       if (!lostbit) {
112
+	if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
114 113
 	*dst++=*src++;
115 114
 	continue;
116 115
       }
117 116
     }
118 117
     
119
-    getbits(2, &eax, &bitmap, &bits, &src);
118
+    if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
120 119
     
121 120
     if ((eax&0xff)>=3) {
122 121
       /* 50ff - two_bytes */
123 122
       uint8_t fetchbits;
124 123
       
125
-      getbits(2, &eax, &bitmap, &bits, &src);
124
+      if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
126 125
       fetchbits=(eax&0xff)+5;
127 126
       eax--;
128 127
       if ((int16_t)(eax&0xffff)<=0) {
... ...
@@ -136,10 +148,11 @@ static void wunpsect(char *src, char *dst) {
136 136
 	backbytes-=0x9f;
137 137
       }
138 138
       /* 5125 */
139
-      getbits(fetchbits, &eax, &bitmap, &bits, &src);
139
+      if (getbits(fetchbits, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
140 140
       if ((eax&0xffff)==0x1ff) break;
141 141
       eax&=0xffff;
142 142
       backbytes+=eax;
143
+      if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, 2) && CLI_ISCONTAINED(unpacked, usize, dst, 2))) return 1;
143 144
       *dst=*(dst-backbytes);
144 145
       dst++;
145 146
       *dst=*(dst-backbytes);
... ...
@@ -150,9 +163,9 @@ static void wunpsect(char *src, char *dst) {
150 150
     /* 5143 - more_backbytes */      
151 151
     oal=eax&0xff;
152 152
     getmorestuff=1;
153
-    /* FIXME: pushf */
153
+
154 154
     
155
-    getbits(3, &eax, &bitmap, &bits, &src);
155
+    if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
156 156
     if ((eax&0xff)<=3) {
157 157
       lostbit=0;
158 158
       if ((eax&0xff)==3) {
... ...
@@ -160,14 +173,12 @@ static void wunpsect(char *src, char *dst) {
160 160
 	lostbit=bitmap>>31;
161 161
 	bitmap<<=1;
162 162
 	bits--;
163
-	if (!bits) { 
164
-	  bitmap=*(uint32_t *)src;
165
-	  bits=32;
166
-	  src+=4;
163
+	if (!bits) {
164
+	  if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1; 
167 165
 	}
168 166
       }
169 167
       eax=eax+lostbit+5;
170
-      /* FIXME: jmp more_bb_commondock */
168
+      /* jmp more_bb_commondock */
171 169
     } else { /* >3 */
172 170
       /* 5160 - more_bb_morethan3 */
173 171
       if ((eax&0xff)==4) {
... ...
@@ -175,27 +186,25 @@ static void wunpsect(char *src, char *dst) {
175 175
 	lostbit=bitmap>>31;
176 176
 	bitmap<<=1;
177 177
 	bits--;
178
-	if (!bits) { 
179
-	  bitmap=*(uint32_t *)src;
180
-	  bits=32;
181
-	  src+=4;
178
+	if (!bits) {
179
+	  if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;  
182 180
 	}
183 181
 	eax=eax+lostbit+6;
184
-	/* FIXME: jmp more_bb_commondock */
182
+	/* jmp more_bb_commondock */
185 183
       } else { /* !=4 */
186 184
 	eax+=7;
187 185
 	if ((eax&0xff)>=0x0d) {
188 186
 	  getmorestuff=0; /* jmp more_bb_PASTcommondock */
189 187
 	  if ((eax&0xff)==0x0d) {
190 188
 	    /* 5179  */
191
-	    getbits(0x0e, &eax, &bitmap, &bits, &src);
189
+	    if (getbits(0x0e, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
192 190
 	    eax+=0x1fe1;
193 191
 	  } else {
194 192
 	    /* 516c */
195
-	    getbits(0x0f, &eax, &bitmap, &bits, &src);
193
+	    if (getbits(0x0f, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
196 194
 	    eax+=0x5fe1;
197 195
 	  }
198
-	  /* FIXME: jmp more_bb_PASTcommondock */
196
+	  /* jmp more_bb_PASTcommondock */
199 197
 	} /* al >= 0d */
200 198
       } /* al != 4 */
201 199
     } /* >3 */
... ...
@@ -203,14 +212,14 @@ static void wunpsect(char *src, char *dst) {
203 203
     if (getmorestuff) {
204 204
       /* 5192 - more_bb_commondock */
205 205
       uint16_t bk=(1<<(eax&0xff))-0x1f;
206
-      getbits((eax&0xff), &eax, &bitmap, &bits, &src);
206
+      if (getbits((eax&0xff), &eax, &bitmap, &bits, &src, packed, psize)) return 1;
207 207
       eax+=bk;
208 208
     }
209 209
     
210 210
     /* 51a7 - more_bb_pastcommondock */
211 211
     eax&=0xffff;
212 212
     backbytes=eax;
213
-    backsize=3+(oal!=1); /* FIXME: move up and remove oal */
213
+    backsize=3+(oal!=1);
214 214
     
215 215
     if (oal<1) { /* overrides backsize */
216 216
       /* 51bb - more_bb_again */
... ...
@@ -219,10 +228,8 @@ static void wunpsect(char *src, char *dst) {
219 219
       lostbit=bitmap>>31;
220 220
       bitmap<<=1;
221 221
       bits--;
222
-      if (!bits) { 
223
-	bitmap=*(uint32_t *)src;
224
-	bits=32;
225
-	src+=4;
222
+      if (!bits) {
223
+	if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;  
226 224
       }
227 225
       if (!lostbit) {
228 226
 	/* 51c2 */
... ...
@@ -230,26 +237,24 @@ static void wunpsect(char *src, char *dst) {
230 230
 	lostbit=bitmap>>31;
231 231
 	bitmap<<=1;
232 232
 	bits--;
233
-	if (!bits) { 
234
-	  bitmap=*(uint32_t *)src;
235
-	  bits=32;
236
-	  src+=4;
233
+	if (!bits) {
234
+	  if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;   
237 235
 	}
238 236
 	eax=5+lostbit;
239
-	/* FIXME: jmp setsize_and_backcopy */
237
+	/* jmp setsize_and_backcopy */
240 238
       } else {
241 239
 	/* 51ce - more_bb_again_and_again */
242
-	getbits(3, &eax, &bitmap, &bits, &src);
240
+	if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
243 241
 	if (eax&0xff) {
244 242
 	  /* 51e6 */
245 243
 	  eax+=6;
246
-	  /* FIXME: jmp setsize_and_backcopy */
244
+	  /* jmp setsize_and_backcopy */
247 245
 	} else {
248
-	  getbits(4, &eax, &bitmap, &bits, &src);
246
+	  if (getbits(4, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
249 247
 	  if (eax&0xff) {
250 248
 	    /* 51e4 */
251 249
 	    eax+=7+6;
252
-	    /* FIXME: jmp setsize_and_backcopy */
250
+	    /* jmp setsize_and_backcopy */
253 251
 	  } else {
254 252
 	    /* 51ea - OMGWTF */
255 253
 	    uint8_t c=4;
... ...
@@ -265,19 +270,17 @@ static void wunpsect(char *src, char *dst) {
265 265
 		lostbit=bitmap>>31;
266 266
 		bitmap<<=1;
267 267
 		bits--;
268
-		if (!bits) { 
269
-		  bitmap=*(uint32_t *)src;
270
-		  bits=32;
271
-		  src+=4;
268
+		if (!bits) {
269
+		  if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;    
272 270
 		}
273 271
 		c++;
274 272
 		if (!lostbit) continue;
275
-		getbits(c, &eax, &bitmap, &bits, &src);
273
+		if (getbits(c, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
276 274
 		d+=eax&0xff;
277 275
 		eax&=0xffffff00;
278 276
 		eax|=d&0xff;
279 277
 	      } else {
280
-		getbits(14, &eax, &bitmap, &bits, &src);
278
+		if (getbits(14, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
281 279
 	      }
282 280
 	      break;
283 281
 	    } /* while */
... ...
@@ -289,13 +292,15 @@ static void wunpsect(char *src, char *dst) {
289 289
     }
290 290
 
291 291
     /* 521e - backcopy */
292
+    if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, backsize) && CLI_ISCONTAINED(unpacked, usize, dst, backsize))) return 1;
292 293
     while(backsize--){
293 294
       *dst=*(dst-backbytes);
294 295
       dst++;
295 296
     }
296 297
 
297 298
   } /* while true */
298
-  
299
+
300
+  return 0;
299 301
 }
300 302
 
301 303
 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) {
... ...
@@ -310,7 +315,7 @@ int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_
310 310
       cli_dbgmsg("WWPack: next chunk out ouf file, giving up.\n");
311 311
       return 1;
312 312
     }
313
-    if ((csize=cli_readint32(stuff+8)*4)!=cli_readint32(stuff+12)+4) {
313
+    if ((csize=cli_readint32(stuff+8)*4)!=(uint32_t)cli_readint32(stuff+12)+4) {
314 314
       cli_dbgmsg("WWPack: inconsistent/hacked data, go figure!\n");
315 315
       return 1;
316 316
     }
... ...
@@ -325,7 +330,11 @@ int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_
325 325
       return 1;
326 326
     }
327 327
     memcpy(packed, unpacked, csize);
328
-    wunpsect(packed, unpacked);
328
+    if (wunpsect(packed, unpacked, csize, exesz-(unpacked-exe))) {
329
+      free(packed);
330
+      cli_dbgmsg("WWPack: unpacking failed.\n");
331
+      return 1;
332
+    }
329 333
     free(packed);
330 334
     if (!stuff[16]) break;
331 335
     stuff+=17;
... ...
@@ -339,9 +348,6 @@ int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_
339 339
   cli_dbgmsg("WWPack: found OEP @%x\n", csize);
340 340
   cli_writeint32(stuff+0x28, csize);
341 341
 
342
-#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
343
-#define FIXVS(v, r) (VAALIGN((r>v)?r:v))
344
-
345 342
   stuff+=0xf8;
346 343
   while (sects--) {
347 344
     uint32_t v=cli_readint32(stuff+8);
... ...
@@ -354,8 +360,5 @@ int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_
354 354
   }
355 355
   memset(stuff, 0, 0x28);
356 356
 
357
-  cli_dbgmsg("WWPack: Successfully rebuilt\n", csize);
358 357
   return 0;
359 358
 }
360
-
361
-#endif