tags 476694 + patch pending thanks Hi, * Stephen Gran <[EMAIL PROTECTED]> [2008-04-18 18:15]: [...] > I'll apply the patch here, but I'm unlikely to be able to upload to > unstable before Monday night - I'm off for a disconnected weekend in 2 > hours, and I'm still at work. Feel free to NMU, if you like.
debdiff for unstable attached. It will be also archived on: http://people.debian.org/~nion/nmu-diff/clamav-0.92.1~dfsg2-1_0.92.1~dfsg2-1.1.patch If someone has time, please review or test the packages cause I have no possibility to test clamav. unstable: http://people.debian.org/~nion/clamav/unstable/ volatile: http://people.debian.org/~nion/clamav/volatile/ Kind regards Nico -- Nico Golde - http://www.ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -u clamav-0.92.1~dfsg2/debian/changelog clamav-0.92.1~dfsg2/debian/changelog
--- clamav-0.92.1~dfsg2/debian/changelog
+++ clamav-0.92.1~dfsg2/debian/changelog
@@ -1,3 +1,13 @@
+clamav (0.92.1~dfsg2-1.1) unstable; urgency=high
+
+ * Non-maintainer upload by the Security Team.
+ * This update addresses the following security issue:
+ - CVE-2008-1833: heap-based buffer overflow allows remote
+ attackers to execute arbitrary code via a crafted WWPack compressed
+ PE binary (Closes: #476694).
+
+ -- Nico Golde <[EMAIL PROTECTED]> Sat, 19 Apr 2008 12:42:18 +0200
+
clamav (0.92.1~dfsg2-1) unstable; urgency=high
* libclamav/pe.c: possible integer overflow in wwpack
diff -u clamav-0.92.1~dfsg2/debian/patches/00list clamav-0.92.1~dfsg2/debian/patches/00list
--- clamav-0.92.1~dfsg2/debian/patches/00list
+++ clamav-0.92.1~dfsg2/debian/patches/00list
@@ -5,0 +6 @@
+26_CVE-2008-1833
only in patch2:
unchanged:
--- clamav-0.92.1~dfsg2.orig/debian/patches/26_CVE-2008-1833.dpatch
+++ clamav-0.92.1~dfsg2/debian/patches/26_CVE-2008-1833.dpatch
@@ -0,0 +1,727 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 26_CVE-2008-1833.dpatch by Nico Golde <[EMAIL PROTECTED]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
[EMAIL PROTECTED]@
+diff -urNad clamav-0.92.1~dfsg2~/libclamav/pe.c clamav-0.92.1~dfsg2/libclamav/pe.c
+--- clamav-0.92.1~dfsg2~/libclamav/pe.c 2008-04-19 12:33:25.000000000 +0200
++++ clamav-0.92.1~dfsg2/libclamav/pe.c 2008-04-19 12:46:09.000000000 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2004 - 2006 Tomasz Kojm <[EMAIL PROTECTED]>
++ * Copyright (C) 2004 - 2007 Tomasz Kojm <[EMAIL PROTECTED]>
+ * aCaB <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -23,11 +23,12 @@
+ #endif
+
+ #include <stdio.h>
++#if HAVE_STRING_H
+ #include <string.h>
++#endif
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+-#include <sys/stat.h>
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+@@ -1861,106 +1862,65 @@
+ CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc)),0,(spinned,0));
+ }
+
+-
+ /* WWPack */
+
+- if((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
+- exe_sections[nsections-1].raw>0x2b1 &&
++ while ((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
+ vep == exe_sections[nsections - 1].rva &&
+- exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz == max &&
+ memcmp(epbuff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
+ memcmp(epbuff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0) {
+- uint32_t headsize=exe_sections[nsections - 1].raw;
+- char *dest, *wwp;
++ uint32_t head = exe_sections[nsections - 1].raw;
++ uint8_t *packer;
+
+- for(i = 0 ; i < (unsigned int)nsections-1; i++)
+- if (exe_sections[i].raw<headsize) headsize=exe_sections[i].raw;
+-
+- dsize = max-min+headsize-exe_sections[nsections - 1].rsz;
++ ssize = 0;
++ for(i=0 ; ; i++) {
++ if(exe_sections[i].raw<head)
++ head=exe_sections[i].raw;
++ if(i==nsections-1) break;
++ if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
++ ssize=exe_sections[i].rva+exe_sections[i].vsz;
++ }
++ if(!head || !ssize || head>ssize) break;
+
+- CLI_UNPSIZELIMITS("WWPack", dsize);
++ CLI_UNPSIZELIMITS("WWPack", ssize);
+
+- if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
++ if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
+ free(exe_sections);
+ return CL_EMEM;
+ }
+-
+ lseek(desc, 0, SEEK_SET);
+- if((size_t) cli_readn(desc, dest, headsize) != headsize) {
+- cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
+- free(dest);
++ if((size_t) cli_readn(desc, src, head) != head) {
++ cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
++ free(src);
+ free(exe_sections);
+ return CL_EIO;
+ }
+-
+- for(i = 0 ; i < (unsigned int)nsections-1; i++) {
+- if(exe_sections[i].rsz) {
+- 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) {
+- free(dest);
+- free(exe_sections);
+- return CL_EIO;
+- }
+- }
+- }
+-
+- if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
+- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz);
+- free(dest);
++ for(i = 0 ; i < (unsigned int)nsections-1; i++) {
++ if(!exe_sections[i].rsz) continue;
++ if(!cli_seeksect(desc, &exe_sections[i])) break;
++ if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
++ if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
++ }
++ if(i!=nsections-1) {
++ cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
++ free(src);
++ break;
++ }
++ if((packer = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
++ free(src);
+ free(exe_sections);
+ return CL_EMEM;
+ }
+-
+- if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, wwp, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
++ if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, packer, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
+ cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
+- free(dest);
+- free(wwp);
++ free(src);
++ free(packer);
+ free(exe_sections);
+ return CL_EIO;
+ }
+
+- if (!wwunpack(dest, dsize, headsize, min, exe_sections[nsections-1].rva, e_lfanew, wwp, exe_sections[nsections - 1].rsz, nsections-1)) {
+-
+- free(wwp);
+-
+- CLI_UNPTEMP("WWPack",(dest,exe_sections,0));
+-
+- if((unsigned int) write(ndesc, dest, dsize) != dsize) {
+- cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
+- close(ndesc);
+- free(tempfile);
+- free(dest);
+- free(exe_sections);
+- return CL_EIO;
+- }
+-
+- free(dest);
+- if (cli_leavetemps_flag)
+- cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
+- else
+- cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
+-
+- fsync(ndesc);
+- lseek(ndesc, 0, SEEK_SET);
+-
+- if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
+- free(exe_sections);
+- close(ndesc);
+- if(!cli_leavetemps_flag)
+- unlink(tempfile);
+- free(tempfile);
+- return CL_VIRUS;
+- }
+-
+- close(ndesc);
+- if(!cli_leavetemps_flag)
+- unlink(tempfile);
+- free(tempfile);
+- } else {
+- free(wwp);
+- free(dest);
+- cli_dbgmsg("WWPpack: Decompression failed\n");
+- }
++ CLI_UNPTEMP("WWPack",(src,packer,exe_sections,0));
++ CLI_UNPRESULTS("WWPack",(wwunpack(src, ssize, packer, exe_sections, nsections-1, e_lfanew, ndesc)),0,(src,packer,0));
++ break;
+ }
+
+
+diff -urNad clamav-0.92.1~dfsg2~/libclamav/wwunpack.c clamav-0.92.1~dfsg2/libclamav/wwunpack.c
+--- clamav-0.92.1~dfsg2~/libclamav/wwunpack.c 2007-12-06 13:59:04.000000000 +0100
++++ clamav-0.92.1~dfsg2/libclamav/wwunpack.c 2008-04-19 13:42:25.000000000 +0200
+@@ -1,6 +1,7 @@
+ /*
+- * Copyright (C) 2006 Sensory Networks, Inc.
+- * Written by aCaB <[EMAIL PROTECTED]>
++ * Copyright (C) 2007 Sourcefire Inc.
++ * Author: aCaB <[EMAIL PROTECTED]>
++ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+@@ -16,346 +17,218 @@
+ * MA 02110-1301, USA.
+ */
+
+-/*
+-** wwunpack.c
+-**
+-** 09/07/2k6 - Campioni del mondo!!!
+-** 14/07/2k6 - RCE'ed + standalone sect unpacker
+-** 15/07/2k6 - Merge started
+-** 17/07/2k6 - Rebuild
+-** 18/07/2k6 - Secured (well, hopefully...)
+-**
+-*/
+-
+-/*
+-** Unpacks+rebuilds WWPack32 1.20
+-**
+-** Just boooooring stuff, blah.
+-**
+-*/
+-
+-
+-/*
+-** TODO:
+-**
+-** review
+-** check eax vs al
+-** (check for dll's)
+-** (have a look at older versions)
+-**
+-*/
+-
+-
+ #if HAVE_CONFIG_H
+ #include "clamav-config.h"
+ #endif
+
+-#include <stdlib.h>
+-#include <string.h>
+-
+ #include "cltypes.h"
+ #include "others.h"
+-#include "wwunpack.h"
++#include "execs.h"
+
+-#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
+-#define FIXVS(v, r) (VAALIGN((r>v)?r:v))
++#if HAVE_STRING_H
++#include <string.h>
++#endif
+
++#define RESEED \
++if (CLI_ISCONTAINED(compd, szd, ccur, 4)) { \
++ bt = cli_readint32(ccur); \
++ ccur+=4; \
++} else { \
++ cli_dbgmsg("WWPack: Out of bits\n"); \
++ error=1; \
++} \
++bc = 32;
+
+-static int getbitmap(uint32_t *bitmap, char **src, uint8_t *bits, char *buf, unsigned int size) {
+- if (! CLI_ISCONTAINED(buf, size, *src, 4)) return 1;
+- *bitmap=cli_readint32(*src);
+- *src+=4;
+- *bits=32;
+- return 0;
+-}
+
+-static int getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, char **src, char *buf, unsigned int size) {
+- *eax=*bitmap>>(32-X);
+- if (*bits>X) {
+- *bitmap<<=X;
+- *bits-=X;
+- } else if (*bits<X) {
+- X-=*bits;
+- *eax>>=X;
+- if (getbitmap(bitmap, src, bits, buf, size)) return 1;
+- *eax<<=X;
+- *eax|=*bitmap>>(32-X);
+- *bitmap<<=X;
+- *bits-=X;
+- } else {
+- if (getbitmap(bitmap, src, bits, buf, size)) return 1;
+- }
+- return 0;
++#define BIT \
++bits = bt>>31; \
++bt<<=1; \
++if(!--bc) { \
++ RESEED; \
+ }
+
+-static int wunpsect(char *packed, char *unpacked, unsigned int psize, unsigned int usize) {
+- char *src=packed, *dst=unpacked;
+- uint32_t bitmap, eax;
+- uint8_t bits;
+- unsigned int lostbit, getmorestuff;
+- uint16_t backbytes;
+- uint16_t backsize;
+- uint8_t oal;
++#define BITS(N) \
++bits = bt>>(32-(N)); \
++if (bc>=(N)) { \
++ bc -= (N); \
++ bt<<=(N); \
++ if (!bc) { \
++ RESEED; \
++ } \
++} else { \
++ if (CLI_ISCONTAINED(compd, szd, ccur, 4)) { \
++ bt = cli_readint32(ccur); \
++ ccur+=4; \
++ bc += 32 - (N); \
++ bits |= bt>>(bc); \
++ bt <<= (32-bc); \
++ } else { \
++ cli_dbgmsg("WWPack: Out of bits\n"); \
++ error=1; \
++ } \
++}
+
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+- eax=bitmap;
++int wwunpack(uint8_t *exe, uint32_t exesz, uint8_t *wwsect, struct cli_exe_section *sects, uint16_t scount, uint32_t pe, int desc) {
++ uint8_t *structs = wwsect + 0x2a1, *compd, *ccur, *unpd, *ucur, bc;
++ uint32_t src, srcend, szd, bt, bits;
++ int error=0, i;
+
++ cli_dbgmsg("in wwunpack\n");
+ while (1) {
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!lostbit && bits) {
+- if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
+- *dst++=*src++;
+- continue;
++ if (!CLI_ISCONTAINED(wwsect, sects[scount].rsz, structs, 17)) {
++ cli_dbgmsg("WWPack: Array of structs out of section\n");
++ break;
+ }
++ src = sects[scount].rva - cli_readint32(structs); /* src delta / dst delta - not used / dwords / end of src */
++ structs+=8;
++ szd = cli_readint32(structs) * 4;
++ structs+=4;
++ srcend = cli_readint32(structs);
++ structs+=4;
++
++ unpd = ucur = exe+src+srcend+4-szd;
++ if (!szd || !CLI_ISCONTAINED(exe, exesz, unpd, szd)) {
++ cli_dbgmsg("WWPack: Compressed data out of file\n");
++ break;
++ }
++ cli_dbgmsg("WWP: src: %x, szd: %x, srcend: %x - %x\n", src, szd, srcend, srcend+4-szd);
++ if (!(compd = cli_malloc(szd))) break;
++ memcpy(compd, unpd, szd);
++ memset(unpd, -1, szd); /*FIXME*/
++ ccur=compd;
+
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+- eax=bitmap;
+- if (!lostbit) {
+- if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
+- *dst++=*src++;
++ RESEED;
++ while(!error) {
++ uint32_t backbytes, backsize;
++ uint8_t saved;
++
++ BIT;
++ if (!bits) { /* BYTE copy */
++ if(ccur-compd>=szd || !CLI_ISCONTAINED(exe, exesz, ucur, 1))
++ error=1;
++ else
++ *ucur++=*ccur++;
+ continue;
+ }
+- }
+-
+- if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+-
+- if ((eax&0xff)>=3) {
+- /* 50ff - two_bytes */
+- uint8_t fetchbits;
+-
+- if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- fetchbits=(eax&0xff)+5;
+- eax--;
+- if ((int16_t)(eax&0xffff)<=0) {
+- /* 5113 */
+- backbytes=1<<fetchbits;
+- backbytes=(backbytes&0xff00)|((backbytes-31)&0xff);
+- } else {
+- /* 511b */
+- fetchbits++;
+- backbytes=1<<fetchbits;
+- backbytes-=0x9f;
++
++ BITS(2);
++ if(bits==3) { /* WORD backcopy */
++ uint8_t shifted, subbed = 31;
++ BITS(2);
++ shifted = bits + 5;
++ if(bits>=2) {
++ shifted++;
++ subbed += 0x80;
++ }
++ backbytes = (1<<shifted)-subbed; /* 1h, 21h, 61h, 161h */
++ BITS(shifted); /* 5, 6, 8, 9 */
++ if(error || bits == 0x1ff) break;
++ backbytes+=bits;
++ if(!CLI_ISCONTAINED(exe, exesz, ucur, 2) || !CLI_ISCONTAINED(exe, exesz, ucur-backbytes, 2)) {
++ error=1;
++ } else {
++ ucur[0]=*(ucur-backbytes);
++ ucur[1]=*(ucur-backbytes+1);
++ ucur+=2;
++ }
++ continue;
+ }
+- /* 5125 */
+- if (getbits(fetchbits, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- if ((eax&0xffff)==0x1ff) break;
+- eax&=0xffff;
+- backbytes+=eax;
+- if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, 2) && CLI_ISCONTAINED(unpacked, usize, dst, 2))) return 1;
+- *dst=*(dst-backbytes);
+- dst++;
+- *dst=*(dst-backbytes);
+- dst++;
+- continue;
+- }
+
+- /* 5143 - more_backbytes */
+- oal=eax&0xff;
+- getmorestuff=1;
++ /* BLOCK backcopy */
++ saved = bits; /* cmp al, 1 / pushf */
+
+-
+- if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- if ((eax&0xff)<=3) {
+- lostbit=0;
+- if ((eax&0xff)==3) {
+- /* next_bit_or_reseed */
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
++ BITS(3);
++ if (bits<6) {
++ backbytes = bits;
++ switch(bits) {
++ case 4: /* 10,11 */
++ backbytes++;
++ case 3: /* 8,9 */
++ BIT;
++ backbytes+=bits;
++ case 0: case 1: case 2: /* 5,6,7 */
++ backbytes+=5;
++ break;
++ case 5: /* 12 */
++ backbytes=12;
++ break;
+ }
++ BITS(backbytes);
++ bits+=(1<<backbytes)-31;
++ } else if(bits==6) {
++ BITS(0x0e);
++ bits+=0x1fe1;
++ } else {
++ BITS(0x0f);
++ bits+=0x5fe1;
+ }
+- eax=eax+lostbit+5;
+- /* jmp more_bb_commondock */
+- } else { /* >3 */
+- /* 5160 - more_bb_morethan3 */
+- if ((eax&0xff)==4) {
+- /* next_bit_or_reseed */
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+- }
+- eax=eax+lostbit+6;
+- /* jmp more_bb_commondock */
+- } else { /* !=4 */
+- eax+=7;
+- if ((eax&0xff)>=0x0d) {
+- getmorestuff=0; /* jmp more_bb_PASTcommondock */
+- if ((eax&0xff)==0x0d) {
+- /* 5179 */
+- if (getbits(0x0e, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- eax+=0x1fe1;
++
++ backbytes = bits;
++
++ /* popf / jb */
++ if (!saved) {
++ BIT;
++ if(!bits) {
++ BIT;
++ bits+=5;
++ } else {
++ BITS(3);
++ if(bits) {
++ bits+=6;
+ } else {
+- /* 516c */
+- if (getbits(0x0f, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- eax+=0x5fe1;
++ BITS(4);
++ if(bits) {
++ bits+=13;
++ } else {
++ uint8_t cnt = 4;
++ uint16_t shifted = 0x0d;
++
++ do {
++ if(cnt==7) { cnt = 0x0e; shifted = 0; break; }
++ shifted=((shifted+2)<<1)-1;
++ BIT;
++ cnt++;
++ } while(!bits);
++ BITS(cnt);
++ bits+=shifted;
++ }
+ }
+- /* jmp more_bb_PASTcommondock */
+- } /* al >= 0d */
+- } /* al != 4 */
+- } /* >3 */
+-
+- if (getmorestuff) {
+- /* 5192 - more_bb_commondock */
+- uint16_t bk=(1<<(eax&0xff))-0x1f;
+- if (getbits((eax&0xff), &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- eax+=bk;
+- }
+-
+- /* 51a7 - more_bb_pastcommondock */
+- eax&=0xffff;
+- backbytes=eax;
+- backsize=3+(oal!=1);
+-
+- if (oal<1) { /* overrides backsize */
+- /* 51bb - more_bb_again */
+-
+- /* next_bit_or_reseed */
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+- }
+- if (!lostbit) {
+- /* 51c2 */
+- /* next_bit_or_reseed */
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+ }
+- eax=5+lostbit;
+- /* jmp setsize_and_backcopy */
++ backsize = bits;
+ } else {
+- /* 51ce - more_bb_again_and_again */
+- if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- if (eax&0xff) {
+- /* 51e6 */
+- eax+=6;
+- /* jmp setsize_and_backcopy */
+- } else {
+- if (getbits(4, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- if (eax&0xff) {
+- /* 51e4 */
+- eax+=7+6;
+- /* jmp setsize_and_backcopy */
+- } else {
+- /* 51ea - OMGWTF */
+- uint8_t c=4;
+- uint16_t d=0x0d;
+-
+- while ( 1 ) {
+- if (c!=7){
+- d+=2;
+- d<<=1;
+- d--;
+-
+- /* next_bit_or_reseed */
+- lostbit=bitmap>>31;
+- bitmap<<=1;
+- bits--;
+- if (!bits) {
+- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+- }
+- c++;
+- if (!lostbit) continue;
+- if (getbits(c, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- d+=eax&0xff;
+- eax&=0xffffff00;
+- eax|=d&0xff;
+- } else {
+- if (getbits(14, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
+- }
+- break;
+- } /* while */
+- } /* OMGWTF */
+- } /* eax&0xff */
+- } /* lostbit */
+- /* 521b - setsize_and_backcopy */
+- backsize=eax&0xffff;
+- }
+-
+- /* 521e - backcopy */
+- if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, backsize) && CLI_ISCONTAINED(unpacked, usize, dst, backsize))) return 1;
+- while(backsize--){
+- *dst=*(dst-backbytes);
+- dst++;
+- }
+-
+- } /* while true */
+-
+- return 0;
+-}
+-
+-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) {
+- char *stuff=wwp+0x2a1, *packed, *unpacked;
+- uint32_t rva, csize;
+-
+- cli_dbgmsg("in wwunpack\n");
+-
++ backsize = saved+2;
++ }
+
+- while(1) {
+- if (!CLI_ISCONTAINED(wwp, wwpsz, stuff, 17)) {
+- cli_dbgmsg("WWPack: next chunk out ouf file, giving up.\n");
+- return 1;
+- }
+- if ((csize=cli_readint32(stuff+8)*4)!=(uint32_t)cli_readint32(stuff+12)+4) {
+- cli_dbgmsg("WWPack: inconsistent/hacked data, go figure!\n");
+- return 1;
+- }
+- rva = wwprva-cli_readint32(stuff);
+- if((packed = (char *) cli_calloc(csize, sizeof(char))) == NULL) {
+- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", csize);
+- return 1;
+- }
+- unpacked=exe+headsize+rva-min;
+- if (!CLI_ISCONTAINED(exe, exesz, unpacked, csize)) {
+- free(packed);
+- cli_dbgmsg("WWPack: packed data out of bounds, giving up.\n");
+- return 1;
++ if(!CLI_ISCONTAINED(exe, exesz, ucur, backsize) || !CLI_ISCONTAINED(exe, exesz, ucur-backbytes, backsize)) error=1;
++ while(backsize--) {
++ *ucur=*(ucur-backbytes);
++ ucur++;
++ }
+ }
+- memcpy(packed, unpacked, csize);
+- if (wunpsect(packed, unpacked, csize, exesz-(unpacked-exe))) {
+- free(packed);
+- cli_dbgmsg("WWPack: unpacking failed.\n");
+- return 1;
++ free(compd);
++ if(error) {
++ cli_dbgmsg("WWPack: decompression error\n");
++ break;
+ }
+- free(packed);
+- if (!stuff[16]) break;
+- stuff+=17;
++ if (error || !*structs++) break;
+ }
+
+- stuff=exe+e_lfanew;
+- stuff[6]=sects&0xff;
+- stuff[7]=sects>>8;
+-
+- csize=cli_readint32(wwp+0x295)+wwprva+0x299;
+- cli_dbgmsg("WWPack: found OEP @%x\n", csize);
+- cli_writeint32(stuff+0x28, csize);
+-
+- csize=cli_readint32(stuff+0x50)-VAALIGN(wwpsz);
+- cli_writeint32(stuff+0x50, csize);
+-
++ if(!error) {
++ exe[pe+6]=(uint8_t)scount;
++ exe[pe+7]=(uint8_t)(scount>>8);
++ cli_writeint32(&exe[pe+0x28], cli_readint32(wwsect+0x295)+sects[scount].rva+0x299);
++ cli_writeint32(&exe[pe+0x50], cli_readint32(&exe[pe+0x50])-sects[scount].vsz);
+
+- stuff+=0x18+(cli_readint32(stuff+0x14)&0xffff);
+- while (sects--) {
+- uint32_t v=cli_readint32(stuff+8);
+- uint32_t r=cli_readint32(stuff+16);
+- csize=FIXVS(v, r);
+- cli_writeint32(stuff+8, csize);
+- cli_writeint32(stuff+16, csize);
+- cli_writeint32(stuff+20, cli_readint32(stuff+12)-min+headsize);
+- stuff+=0x28;
++ structs = &exe[0xffff&cli_readint32(&exe[pe+0x14])+pe+0x18];
++ for(i=0 ; i<scount ; i++) {
++ cli_writeint32(structs+8, sects[i].vsz);
++ cli_writeint32(structs+12, sects[i].rva);
++ cli_writeint32(structs+16, sects[i].vsz);
++ cli_writeint32(structs+20, sects[i].rva);
++ structs+=0x28;
++ }
++ memset(structs, 0, 0x28);
++ error = cli_writen(desc, exe, exesz)!=exesz;
+ }
+- memset(stuff, 0, 0x28);
+-
+- return 0;
++ return error;
+ }
+diff -urNad clamav-0.92.1~dfsg2~/libclamav/wwunpack.h clamav-0.92.1~dfsg2/libclamav/wwunpack.h
+--- clamav-0.92.1~dfsg2~/libclamav/wwunpack.h 2007-12-06 13:59:04.000000000 +0100
++++ clamav-0.92.1~dfsg2/libclamav/wwunpack.h 2008-04-19 13:42:25.000000000 +0200
+@@ -20,8 +20,8 @@
+ #define __WWP32_H
+
+ #include "cltypes.h"
+-#include "rebuildpe.h"
++#include "execs.h"
+
+-int wwunpack(char *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, char *, uint32_t, uint16_t);
++int wwunpack(uint8_t *, uint32_t, uint8_t *, struct cli_exe_section *, uint16_t, uint32_t, int);
+
+ #endif
pgpCWWHVE1MyZ.pgp
Description: PGP signature

