76
68
\x65\x72\x20\x2D\x20\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\
77
69
\x63\x6C\x61\x6D\x61\x76\x2E\x6E\x65\x74\x0D\x0A\x24\x00\x00\x00\
80
\x50\x45\x00\x00\x4C\x01\x01\x00\x43\x4C\x41\x4D\x00\x00\x00\x00\
81
\x00\x00\x00\x00\xE0\x00\x83\x8F\x0B\x01\x00\x00\x00\x10\x00\x00\
82
\x00\x10\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x10\x00\x00\
83
\x00\x10\x00\x00\x00\x00\x40\x00\x00\x10\x00\x00\x00\x02\x00\x00\
84
\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0A\x00\x00\x00\x00\x00\
85
\xFF\xFF\xFF\xFF\x00\x02\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\
86
\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x10\x00\x00\x10\x00\x00\
87
\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
88
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
89
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
90
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
91
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
92
\x00\x00\x00\x00\x00\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\x2e\x63\x6c\x61\x6d\x30\x31\x00\
96
\xFF\xFF\xFF\xFF\x00\x10\x00\x00\xFF\xFF\xFF\xFF\x00\x02\x00\x00\
97
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\
100
static char *checkpe(char *dst, uint32_t dsize, char *pehdr, uint32_t *valign, unsigned int *sectcnt)
103
if (!CLI_ISCONTAINED(dst, dsize, pehdr, 0xf8)) return NULL;
105
if (cli_readint32(pehdr) != 0x4550 ) return NULL;
107
if (!(*valign=cli_readint32(pehdr+0x38))) return NULL;
109
sections = pehdr+0xf8;
110
if (!(*sectcnt = (unsigned char)pehdr[6] + (unsigned char)pehdr[7]*256)) return NULL;
112
if (!CLI_ISCONTAINED(dst, dsize, sections, *sectcnt*0x28)) return NULL;
119
static int pefromupx (char *src, uint32_t ssize, char *dst, uint32_t *dsize, uint32_t ep, uint32_t upx0, uint32_t upx1, uint32_t *magic, uint32_t dend)
74
static int pefromupx (char *src, char *dst, uint32_t *dsize, uint32_t ep, uint32_t upx0, uint32_t upx1, uint32_t magic)
121
char *imports, *sections=NULL, *pehdr=NULL, *newbuf;
122
unsigned int sectcnt=0, upd=1;
123
uint32_t realstuffsz=0, valign=0;
76
char *imports, *sections, *pehdr, *newbuf;
78
uint32_t realstuffsz, valign;
124
79
uint32_t foffset=0xd0+0xf8;
126
81
if((dst == NULL) || (src == NULL))
129
while ((valign=magic[sectcnt++])) {
130
if ( ep - upx1 + valign <= ssize-5 && /* Wondering how we got so far?! */
131
src[ep - upx1 + valign - 2] == '\x8d' && /* lea edi, ... */
132
src[ep - upx1 + valign - 1] == '\xbe' ) /* ... [esi + offset] */
136
if (!valign && ep - upx1 + 0x80 < ssize-8) {
137
const char *pt = &src[ep - upx1 + 0x80];
138
cli_dbgmsg("UPX: bad magic - scanning for imports\n");
140
while ((pt=cli_memstr(pt, ssize - (pt-src) - 8, "\x8d\xbe", 2))) {
141
if (pt[6] == '\x8b' && pt[7] == '\x07') { /* lea edi, [esi+imports] / mov eax, [edi] */
142
valign=pt-src+2-ep+upx1;
149
if (valign && CLI_ISCONTAINED(src, ssize, src + ep - upx1 + valign, 4)) {
150
imports = dst + cli_readint32(src + ep - upx1 + valign);
152
realstuffsz = imports-dst;
154
if (realstuffsz >= *dsize ) {
155
cli_dbgmsg("UPX: wrong realstuff size\n");
156
/* fallback and eventually craft */
159
while (CLI_ISCONTAINED(dst, *dsize, pehdr, 8) && cli_readint32(pehdr)) {
161
while(CLI_ISCONTAINED(dst, *dsize, pehdr, 2) && *pehdr) {
163
while (CLI_ISCONTAINED(dst, *dsize, pehdr, 2) && *pehdr)
84
imports = dst + cli_readint32(src + ep - upx1 + magic);
86
realstuffsz = imports-dst;
88
if (realstuffsz >= *dsize ) {
89
cli_dbgmsg("UPX: wrong realstuff size - giving up rebuild\n");
94
while (CLI_ISCONTAINED(dst, *dsize, pehdr, 8) && cli_readint32(pehdr)) {
96
while(CLI_ISCONTAINED(dst, *dsize, pehdr, 2) && *pehdr) {
98
while (CLI_ISCONTAINED(dst, *dsize, pehdr, 2) && *pehdr)
171
if (!(sections=checkpe(dst, *dsize, pehdr, &valign, §cnt))) pehdr=NULL;
175
if (!pehdr && dend>0xf8+0x28) {
176
cli_dbgmsg("UPX: no luck - scanning for PE\n");
177
pehdr = &dst[dend-0xf8-0x28];
179
if ((sections=checkpe(dst, *dsize, pehdr, &valign, §cnt)))
183
if (!(realstuffsz = pehdr-dst)) pehdr=NULL;
187
uint32_t rebsz = PESALIGN(dend, 0x1000);
188
cli_dbgmsg("UPX: no luck - brutally crafing a reasonable PE\n");
189
if (!(newbuf = (char *)cli_calloc(rebsz+0x200, sizeof(char)))) {
190
cli_dbgmsg("UPX: malloc failed - giving up rebuild\n");
193
memcpy(newbuf, HEADERS, 0xd0);
194
memcpy(newbuf+0xd0, FAKEPE, 0x120);
195
memcpy(newbuf+0x200, dst, dend);
196
memcpy(dst, newbuf, dend+0x200);
198
cli_writeint32(dst+0xd0+0x50, rebsz+0x1000);
199
cli_writeint32(dst+0xd0+0x100, rebsz);
200
cli_writeint32(dst+0xd0+0x108, rebsz);
202
cli_dbgmsg("UPX: PE structure added to uncompressed data\n");
106
if (!CLI_ISCONTAINED(dst, *dsize, pehdr, 0xf8)) {
107
cli_dbgmsg("UPX: sections out of bounds - giving up rebuild\n");
111
if ( cli_readint32(pehdr) != 0x4550 ) {
112
cli_dbgmsg("UPX: No magic for PE - giving up rebuild\n");
116
if (!(valign=cli_readint32(pehdr+0x38))) {
117
cli_dbgmsg("UPX: Cant align to a NULL bound - giving up rebuild\n");
121
sections = pehdr+0xf8;
122
if ( ! (sectcnt = (unsigned char)pehdr[6]+256*(unsigned char)pehdr[7])) {
123
cli_dbgmsg("UPX: No sections? - giving up rebuild\n");
206
127
foffset = PESALIGN(foffset+0x28*sectcnt, valign);
129
if (!CLI_ISCONTAINED(dst, *dsize, sections, 0x28*sectcnt)) {
130
cli_dbgmsg("UPX: Not enough space for all sects - giving up rebuild\n");
208
134
for (upd = 0; upd <sectcnt ; upd++) {
209
uint32_t vsize=PESALIGN((uint32_t)cli_readint32(sections+8), valign);
210
uint32_t urva=PEALIGN((uint32_t)cli_readint32(sections+12), valign);
135
uint32_t vsize=PESALIGN(cli_readint32(sections+8), valign);
136
uint32_t urva=PEALIGN(cli_readint32(sections+12), valign);
212
138
/* Within bounds ? */
213
139
if (!CLI_ISCONTAINED(upx0, realstuffsz, urva, vsize)) {
344
if (!CLI_ISCONTAINED(dst, *dsize, dst+dcur+unp_offset, backsize) || !CLI_ISCONTAINED(dst, *dsize, dst+dcur, backsize) || unp_offset >=0)
346
for (i = 0; i < backsize; i++)
271
for (i = 0; i < backsize; i++) {
272
if (dcur+i<0 || dcur+i>=*dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=*dsize)
347
274
dst[dcur + i] = dst[dcur + unp_offset + i];
351
return pefromupx (src, ssize, dst, dsize, ep, upx0, upx1, magic, dcur);
280
if ( ep - upx1 + 0x108 <= ssize-5 && /* Wondering how we got so far?! */
281
src[ep - upx1 + 0x106] == '\x8d' && /* lea edi, ... */
282
src[ep - upx1 + 0x107] == '\xbe' ) /* ... [esi + offset] */
283
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x108);
285
cli_dbgmsg("UPX: bad magic for 2b\n");
354
289
int upx_inflate2d(char *src, uint32_t ssize, char *dst, uint32_t *dsize, uint32_t upx0, uint32_t upx1, uint32_t ep)
356
int32_t backbytes, unp_offset = -1;
357
uint32_t backsize, myebx = 0, scur=0, dcur=0, i, magic[]={0x11c,0x124,0};
291
int32_t backbytes, unp_offset = -1, myebx = 0;
292
int scur=0, dcur=0, i, backsize, oob;
361
295
while ( (oob = doubleebx(src, &myebx, &scur, ssize)) == 1) {
362
if (scur>=ssize || dcur>=*dsize)
296
if (scur<0 || scur>=ssize || dcur<0 || dcur>=*dsize)
364
298
dst[dcur++] = src[scur++];
426
if (!CLI_ISCONTAINED(dst, *dsize, dst+dcur+unp_offset, backsize) || !CLI_ISCONTAINED(dst, *dsize, dst+dcur, backsize) || unp_offset >=0 )
428
for (i = 0; i < backsize; i++)
361
for (i = 0; i < backsize; i++) {
362
if (dcur+i<0 || dcur+i>=*dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=*dsize)
429
364
dst[dcur + i] = dst[dcur + unp_offset + i];
433
return pefromupx (src, ssize, dst, dsize, ep, upx0, upx1, magic, dcur);
369
if ( ep - upx1 + 0x124 <= ssize-5 ) { /* Wondering how we got so far?! */
370
if ( src[ep - upx1 + 0x11a] == '\x8d' && src[ep - upx1 + 0x11b] == '\xbe' )
371
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x11c);
372
if ( src[ep - upx1 + 0x122] == '\x8d' && src[ep - upx1 + 0x123] == '\xbe' )
373
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x124);
375
cli_dbgmsg("UPX: bad magic for 2d\n");
436
379
int upx_inflate2e(char *src, uint32_t ssize, char *dst, uint32_t *dsize, uint32_t upx0, uint32_t upx1, uint32_t ep)
438
int32_t backbytes, unp_offset = -1;
439
uint32_t backsize, myebx = 0, scur=0, dcur=0, i, magic[]={0x128,0x130,0};
381
int32_t backbytes, unp_offset = -1, myebx = 0;
382
int scur=0, dcur=0, i, backsize, oob;
443
385
while ( (oob = doubleebx(src, &myebx, &scur, ssize)) ) {
446
if (scur>=ssize || dcur>=*dsize)
388
if (scur<0 || scur>=ssize || dcur<0 || dcur>=*dsize)
448
390
dst[dcur++] = src[scur++];
495
440
if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
497
442
backsize = 2 + oob;
500
if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
502
backsize = backsize * 2 + oob;
503
} while ((oob = doubleebx(src, &myebx, &scur, ssize)) == 0);
446
if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
448
backsize = backsize * 2 + oob;
449
} while ((oob = doubleebx(src, &myebx, &scur, ssize)) == 0);
510
456
if ( (uint32_t)unp_offset < 0xfffffb00 )
515
if (!CLI_ISCONTAINED(dst, *dsize, dst+dcur+unp_offset, backsize) || !CLI_ISCONTAINED(dst, *dsize, dst+dcur, backsize) || unp_offset >=0 )
517
for (i = 0; i < backsize; i++)
460
for (i = 0; i < backsize; i++) {
461
if (dcur+i<0 || dcur+i>=*dsize || dcur+unp_offset+i<0 || dcur+unp_offset+i>=*dsize)
518
463
dst[dcur + i] = dst[dcur + unp_offset + i];
522
return pefromupx (src, ssize, dst, dsize, ep, upx0, upx1, magic, dcur);
525
int upx_inflatelzma(char *src, uint32_t ssize, char *dst, uint32_t *dsize, uint32_t upx0, uint32_t upx1, uint32_t ep) {
527
uint32_t magic[]={0xb16,0xb1e,0};
528
unsigned char fake_lzmahdr[5];
530
memset(&l, 0, sizeof(l));
531
cli_writeint32(fake_lzmahdr + 1, *dsize);
532
*fake_lzmahdr = 3 /* lc */ + 9* ( 5* 2 /* pb */ + 0 /* lp */);
533
l.next_in = fake_lzmahdr;
535
if(cli_LzmaInit(&l, *dsize) != LZMA_RESULT_OK)
538
l.avail_out = *dsize;
539
l.next_in = (unsigned char*)src+2;
540
l.next_out = (unsigned char*)dst;
542
if(cli_LzmaDecode(&l)==LZMA_RESULT_DATA_ERROR) {
543
/* __asm__ __volatile__("int3"); */
544
cli_LzmaShutdown(&l);
468
if ( ep - upx1 + 0x130 <= ssize-5 ) { /* Wondering how we got so far?! */
469
if ( src[ep - upx1 + 0x126] == '\x8d' && src[ep - upx1 + 0x127] == '\xbe' )
470
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x128);
471
if ( src[ep - upx1 + 0x12e] == '\x8d' && src[ep - upx1 + 0x12f] == '\xbe' )
472
return pefromupx (src, dst, dsize, ep, upx0, upx1, 0x130);
547
cli_LzmaShutdown(&l);
549
return pefromupx (src, ssize, dst, dsize, ep, upx0, upx1, magic, *dsize);
474
cli_dbgmsg("UPX: bad magic for 2e\n");