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
pgpeiWo87ew1a.pgp
Description: PGP signature