git-svn: trunk@2087
aCaB authored on 2006/07/17 04:49:42... | ... |
@@ -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, |
... | ... |
@@ -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 |