git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1172 77e5149b-7576-45b1-b177-96237e5ba77b
aCaB authored on 2004/12/13 04:43:49... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Sun Dec 12 19:40:10 UTC 2004 (acab) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav: upx: improved PE rebuild - debug info on failure |
|
4 |
+ |
|
1 | 5 |
Fri Dec 10 15:21:48 GMT 2004 (njh) |
2 | 6 |
---------------------------------- |
3 | 7 |
* libclamav/message.c: Warn if the content-type contains a blank entry |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
** 09/05/2k4 - Moved code outta main(), got rid of globals for thread safety, added bound checking, minor cleaning |
25 | 25 |
** 04/06/2k4 - Now we handle 2B, 2D and 2E :D |
26 | 26 |
** 28/08/2k4 - PE rebuild for nested packers |
27 |
+** 12/12/2k4 - Improved PE rebuild code and added some debug info on failure |
|
27 | 28 |
*/ |
28 | 29 |
|
29 | 30 |
/* |
... | ... |
@@ -90,8 +91,10 @@ int pefromupx (char *src, char *dst, int *dsize, uint32_t ep, uint32_t upx0, uin |
90 | 90 |
|
91 | 91 |
realstuffsz = imports-dst; |
92 | 92 |
|
93 |
- if ( realstuffsz < 0 || realstuffsz > *dsize ) |
|
93 |
+ if ( realstuffsz < 0 || realstuffsz > *dsize ) { |
|
94 |
+ cli_dbgmsg("UPX: wrong realstuff size - giving up rebuild\n"); |
|
94 | 95 |
return 0; |
96 |
+ } |
|
95 | 97 |
|
96 | 98 |
pehdr = imports; |
97 | 99 |
while (pehdr+7 < dst+*dsize && cli_readint32(pehdr)) { |
... | ... |
@@ -106,23 +109,33 @@ int pefromupx (char *src, char *dst, int *dsize, uint32_t ep, uint32_t upx0, uin |
106 | 106 |
} |
107 | 107 |
|
108 | 108 |
pehdr+=4; |
109 |
- if (pehdr+0xf8 > dst+*dsize) |
|
109 |
+ if (pehdr+0xf8 > dst+*dsize) { |
|
110 |
+ cli_dbgmsg("UPX: sections out of bounds - giving up rebuild\n"); |
|
110 | 111 |
return 0; |
112 |
+ } |
|
111 | 113 |
|
112 |
- if ( cli_readint32(pehdr) != 0x4550 ) |
|
114 |
+ if ( cli_readint32(pehdr) != 0x4550 ) { |
|
115 |
+ cli_dbgmsg("UPX: No magic for PE - giving up rebuild\n"); |
|
113 | 116 |
return 0; |
117 |
+ } |
|
114 | 118 |
|
115 |
- if (! (align = cli_readint32(pehdr+0x38))) |
|
119 |
+ if (! (align = cli_readint32(pehdr+0x38))) { |
|
120 |
+ cli_dbgmsg("UPX: Cant align to a NULL bound - giving up rebuild\n"); |
|
116 | 121 |
return 0; |
122 |
+ } |
|
117 | 123 |
|
118 | 124 |
sections = pehdr+0xf8; |
119 |
- if ( ! (sectcnt = pehdr[6]+256*pehdr[7])) |
|
125 |
+ if ( ! (sectcnt = pehdr[6]+256*pehdr[7])) { |
|
126 |
+ cli_dbgmsg("UPX: No sections? - giving up rebuild\n"); |
|
120 | 127 |
return 0; |
128 |
+ } |
|
121 | 129 |
|
122 | 130 |
foffset+=0x28*sectcnt; |
123 | 131 |
|
124 |
- if (pehdr + 0xf8 + 0x28*sectcnt >= dst + *dsize) |
|
132 |
+ if (pehdr + 0xf8 + 0x28*sectcnt >= dst + *dsize) { |
|
133 |
+ cli_dbgmsg("UPX: Not enough space for all sects - giving up rebuild\n"); |
|
125 | 134 |
return 0; |
135 |
+ } |
|
126 | 136 |
|
127 | 137 |
for (upd = 0; upd <sectcnt ; upd++) { |
128 | 138 |
uint32_t vsize=cli_readint32(sections+8)-1; |
... | ... |
@@ -132,16 +145,22 @@ int pefromupx (char *src, char *dst, int *dsize, uint32_t ep, uint32_t upx0, uin |
132 | 132 |
vsize=(((vsize/0x1000)+1)*0x1000); /* FIXME: get bounds from header */ |
133 | 133 |
|
134 | 134 |
/* Within bounds ? */ |
135 |
- if ( urva < upx0 || urva + vsize > upx0 + realstuffsz) |
|
135 |
+ if ( urva < upx0 || urva + vsize > upx0 + realstuffsz) { |
|
136 |
+ cli_dbgmsg("UPX: Sect %d out of bounds - giving up rebuild\n", upd); |
|
136 | 137 |
return 0; |
138 |
+ } |
|
137 | 139 |
|
138 | 140 |
/* Rsize -gt Vsize ? */ |
139 |
- if ( rsize > vsize ) |
|
141 |
+ if ( rsize > vsize ) { |
|
142 |
+ cli_dbgmsg("UPX: Raw size for sect %d is greater than virtual (%x / %x) - giving up rebuild\n", upd, rsize, vsize); |
|
140 | 143 |
return 0; |
144 |
+ } |
|
141 | 145 |
|
142 | 146 |
/* Am i been fooled? There are better ways ;) */ |
143 |
- if ( rsize+4 < vsize && cli_readint32(dst+urva-upx0+rsize) ) |
|
147 |
+ if ( rsize+4 < vsize && cli_readint32(dst+urva-upx0+rsize) ) { |
|
148 |
+ cli_dbgmsg("UPX: Am i been fooled? - giving up rebuild\n", upd); |
|
144 | 149 |
return 0; |
150 |
+ } |
|
145 | 151 |
|
146 | 152 |
cli_writeint32(sections+8, vsize); |
147 | 153 |
cli_writeint32(sections+20, foffset); |
... | ... |
@@ -152,9 +171,11 @@ int pefromupx (char *src, char *dst, int *dsize, uint32_t ep, uint32_t upx0, uin |
152 | 152 |
|
153 | 153 |
cli_writeint32(pehdr+8, 0x4d414c43); |
154 | 154 |
|
155 |
- if (!(newbuf = (char *) cli_malloc(foffset))) |
|
155 |
+ if (!(newbuf = (char *) cli_malloc(foffset))) { |
|
156 |
+ cli_dbgmsg("UPX: malloc failed - giving up rebuild\n", upd); |
|
156 | 157 |
return 0; |
157 |
- |
|
158 |
+ } |
|
159 |
+ |
|
158 | 160 |
memcpy(newbuf, HEADERS, 0xd0); |
159 | 161 |
memcpy(newbuf+0xd0, pehdr,0xf8+0x28*sectcnt); |
160 | 162 |
sections = pehdr+0xf8; |
... | ... |
@@ -283,12 +304,12 @@ int upx_inflate2b(char *src, int ssize, char *dst, int *dsize, uint32_t upx0, ui |
283 | 283 |
} |
284 | 284 |
|
285 | 285 |
|
286 |
- if ( ep - upx1 + 0x14f <= ssize-5 && /* Wondering how we got so far?! */ |
|
287 |
- src[ep - upx1 + 0x14f] == '\xe9' && /* JMP OldEip */ |
|
286 |
+ if ( ep - upx1 + 0x108 <= ssize-5 && /* Wondering how we got so far?! */ |
|
288 | 287 |
src[ep - upx1 + 0x106] == '\x8d' && /* lea edi, ... */ |
289 | 288 |
src[ep - upx1 + 0x107] == '\xbe' ) /* ... [esi + offset] */ |
290 | 289 |
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x108); |
291 | 290 |
|
291 |
+ cli_dbgmsg("UPX: bad magic for 2b\n"); |
|
292 | 292 |
return 0; |
293 | 293 |
} |
294 | 294 |
|
... | ... |
@@ -372,12 +393,13 @@ int upx_inflate2d(char *src, int ssize, char *dst, int *dsize, uint32_t upx0, ui |
372 | 372 |
dcur+=backsize; |
373 | 373 |
} |
374 | 374 |
|
375 |
- if ( ep - upx1 + 0x139 <= ssize-5 && /* Wondering how we got so far?! */ |
|
376 |
- src[ep - upx1 + 0x139] == '\xe9' && /* JMP OldEip */ |
|
377 |
- src[ep - upx1 + 0xe7] == '\x8d' && /* lea edi, ... */ |
|
378 |
- src[ep - upx1 + 0xe8] == '\xbe' ) /* ... [esi + offset] */ |
|
379 |
- return pefromupx (src, dst, dsize, ep, upx0, upx1, 0xe9); |
|
380 |
- |
|
375 |
+ if ( ep - upx1 + 0x124 <= ssize-5 ) { /* Wondering how we got so far?! */ |
|
376 |
+ if ( src[ep - upx1 + 0x11a] == '\x8d' && src[ep - upx1 + 0x11b] == '\xbe' ) |
|
377 |
+ return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x11c); |
|
378 |
+ if ( src[ep - upx1 + 0x122] == '\x8d' && src[ep - upx1 + 0x123] == '\xbe' ) |
|
379 |
+ return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x124); |
|
380 |
+ } |
|
381 |
+ cli_dbgmsg("UPX: bad magic for 2d\n"); |
|
381 | 382 |
return 0; |
382 | 383 |
} |
383 | 384 |
|
... | ... |
@@ -470,11 +492,12 @@ int upx_inflate2e(char *src, int ssize, char *dst, int *dsize, uint32_t upx0, ui |
470 | 470 |
dcur+=backsize; |
471 | 471 |
} |
472 | 472 |
|
473 |
- if ( ep - upx1 + 0x145 <= ssize-5 && /* Wondering how we got so far?! */ |
|
474 |
- src[ep - upx1 + 0x145] == '\xe9' && /* JMP OldEip */ |
|
475 |
- src[ep - upx1 + 0xf3] == '\x8d' && /* lea edi, ... */ |
|
476 |
- src[ep - upx1 + 0xf4] == '\xbe' ) /* ... [esi + offset] */ |
|
477 |
- return pefromupx (src, dst, dsize, ep, upx0, upx1, 0xf5); |
|
478 |
- |
|
473 |
+ if ( ep - upx1 + 0x130 <= ssize-5 ) { /* Wondering how we got so far?! */ |
|
474 |
+ if ( src[ep - upx1 + 0x126] == '\x8d' && src[ep - upx1 + 0x127] == '\xbe' ) |
|
475 |
+ return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x128); |
|
476 |
+ if ( src[ep - upx1 + 0x12e] == '\x8d' && src[ep - upx1 + 0x12f] == '\xbe' ) |
|
477 |
+ return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x130); |
|
478 |
+ } |
|
479 |
+ cli_dbgmsg("UPX: bad magic for 2e\n"); |
|
479 | 480 |
return 0; |
480 | 481 |
} |