Browse code

upx - craft some kind of header if everything else fails

git-svn: trunk@2971

aCaB authored on 2007/03/26 23:35:25
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Mar 26 13:41:33 CEST 2007 (acab)
2
+------------------------------------
3
+  * libclamav/upx.c: craft some kind of header if everything else fails
4
+
1 5
 Mon Mar 26 13:05:01 CEST 2007 (tk)
2 6
 ----------------------------------
3 7
   * libclamav: optimize loading of .ndb files (bb#339), patch from Edwin
... ...
@@ -35,8 +35,7 @@
35 35
 
36 36
 /*
37 37
   TODO:
38
-  - forgepe()
39
-  - pass dll flag from pe.c
38
+  - pass dll flag from pe.c ?
40 39
   - grab statistical magic data from teh zoo
41 40
 */
42 41
 
... ...
@@ -81,6 +80,26 @@
81 81
 \x65\x72\x20\x2D\x20\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\
82 82
 \x63\x6C\x61\x6D\x61\x76\x2E\x6E\x65\x74\x0D\x0A\x24\x00\x00\x00\
83 83
 "
84
+#define FAKEPE "\
85
+\x50\x45\x00\x00\x4C\x01\x01\x00\x43\x4C\x41\x4D\x00\x00\x00\x00\
86
+\x00\x00\x00\x00\xE0\x00\x83\x8F\x0B\x01\x00\x00\x00\x10\x00\x00\
87
+\x00\x10\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x10\x00\x00\
88
+\x00\x10\x00\x00\x00\x00\x40\x00\x00\x10\x00\x00\x00\x02\x00\x00\
89
+\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0A\x00\x00\x00\x00\x00\
90
+\xFF\xFF\xFF\xFF\x00\x02\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\
91
+\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x10\x00\x00\x10\x00\x00\
92
+\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
93
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
94
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
95
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
96
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
97
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
98
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
99
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
100
+\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x63\x6c\x61\x6d\x30\x31\x00\
101
+\xFF\xFF\xFF\xFF\x00\x10\x00\x00\xFF\xFF\xFF\xFF\x00\x02\x00\x00\
102
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\
103
+"
84 104
 
85 105
 static char *checkpe(char *dst, uint32_t dsize, char *pehdr, uint32_t *valign, unsigned int *sectcnt) {
86 106
   char *sections;
... ...
@@ -173,7 +192,7 @@ static int pefromupx (char *src, uint32_t ssize, char *dst, uint32_t *dsize, uin
173 173
   if (!pehdr && dend>0xf8+0x28) {
174 174
     cli_dbgmsg("UPX: no luck - scanning for PE\n");
175 175
     pehdr = &dst[dend-0xf8-0x28];
176
-    while (pehdr>=dst) {
176
+    while (pehdr>dst) {
177 177
       if ((sections=checkpe(dst, *dsize, pehdr, &valign, &sectcnt)))
178 178
 	break;
179 179
       pehdr--;
... ...
@@ -182,9 +201,23 @@ static int pefromupx (char *src, uint32_t ssize, char *dst, uint32_t *dsize, uin
182 182
   }
183 183
 
184 184
   if (!pehdr) {
185
-    cli_dbgmsg("UPX: no luck - brutally crafing a reasonable PE (TODO)\n");
186
-    /*TODO: forgepe() or escape via cli_rebuildpe() ?*/
187
-    return 0;
185
+    uint32_t rebsz = PESALIGN(dend, 0x1000);
186
+    cli_dbgmsg("UPX: no luck - brutally crafing a reasonable PE\n");
187
+    if (!(newbuf = (char *)cli_calloc(rebsz+0x200, sizeof(char)))) {
188
+      cli_dbgmsg("UPX: malloc failed - giving up rebuild\n");
189
+      return 0;
190
+    }
191
+    memcpy(newbuf, HEADERS, 0xd0);
192
+    memcpy(newbuf+0xd0, FAKEPE, 0x120);
193
+    memcpy(newbuf+0x200, dst, dend);
194
+    memcpy(dst, newbuf, dend+0x200);
195
+    free(newbuf);
196
+    cli_writeint32(dst+0xd0+0x50, rebsz+0x1000);
197
+    cli_writeint32(dst+0xd0+0x100, rebsz);
198
+    cli_writeint32(dst+0xd0+0x108, rebsz);
199
+    *dsize=rebsz+0x200;
200
+    cli_dbgmsg("UPX: PE structure added to uncompressed data\n");
201
+    return 1;
188 202
   }
189 203
   
190 204
   foffset = PESALIGN(foffset+0x28*sectcnt, valign);
... ...
@@ -263,7 +296,7 @@ static int doubleebx(char *src, uint32_t *myebx, uint32_t *scur, uint32_t ssize)
263 263
 int upx_inflate2b(char *src, uint32_t ssize, char *dst, uint32_t *dsize, uint32_t upx0, uint32_t upx1, uint32_t ep)
264 264
 {
265 265
   int32_t backbytes, unp_offset = -1;
266
-  uint32_t backsize, myebx = 0, scur=0, dcur=0, i, magic[]={/*0, TODO: removeme */0x108,0x110,0};
266
+  uint32_t backsize, myebx = 0, scur=0, dcur=0, i, magic[]={0x108,0x110,0};
267 267
   int oob;
268 268
   
269 269
   while (1) {