1465
1290
/* upack 0.39-3s + sample 0151477*/
1466
while(((upack && nsections == 3) && /* 3 sections */
1468
epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1469
epbuff[5] == '\xad' && epbuff[6] == '\x50' /* lodsd; push eax */
1472
/* based on 0297729 sample from aCaB */
1473
(epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1474
epbuff[5] == '\xff' && epbuff[6] == '\x36' /* push [esi] */
1478
((!upack && nsections == 2) && /* 2 sections */
1479
(( /* upack 0.39-2s */
1480
epbuff[0] == '\x60' && epbuff[1] == '\xe8' && cli_readint32(epbuff+2) == 0x9 /* pusha; call+9 */
1483
( /* upack 1.1/1.2, based on 2 samples */
1484
epbuff[0] == '\xbe' && cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase) < min && /* mov esi */
1485
cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
1486
epbuff[5] == '\xad' && epbuff[6] == '\x8b' && epbuff[7] == '\xf8' /* loads; mov edi, eax */
1493
cli_dbgmsg("Upack characteristics found.\n");
1494
a = exe_sections[0].vsz;
1495
b = exe_sections[1].vsz;
1497
cli_dbgmsg("Upack: var set\n");
1498
c = exe_sections[2].vsz;
1499
ssize = exe_sections[0].ursz + exe_sections[0].uraw;
1500
off = exe_sections[0].rva;
1501
vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva;
1503
cli_dbgmsg("Upack: var NOT set\n");
1504
c = exe_sections[1].rva;
1505
ssize = exe_sections[1].uraw;
1507
vma = exe_sections[1].rva - exe_sections[1].uraw;
1512
CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
1514
if (!CLI_ISCONTAINED(0, dsize, exe_sections[1].rva - off, exe_sections[1].ursz) || (upack && !CLI_ISCONTAINED(0, dsize, exe_sections[2].rva - exe_sections[0].rva, ssize)) || ssize > dsize) {
1515
cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
1291
if((upack && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1292
buff[5] == '\xad' && buff[6] == '\x50' && /* lodsd; push eax */
1293
EC16(file_hdr.NumberOfSections) == 3) || /* 3 sections */
1294
/* based on 0297729 sample from aCaB */
1295
(upack && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
1296
buff[5] == '\xff' && buff[6] == '\x36' && /* push [esi] */
1297
EC16(file_hdr.NumberOfSections) == 3) ||
1299
(!upack && buff[0] == '\x60' && buff[1] == '\xe8' && cli_readint32(buff+2) == 0x9 && /* pusha; call+9 */
1300
EC16(file_hdr.NumberOfSections) == 2) || /* 2 sections */
1301
/* upack 1.1/1.2, based on 2 samples */
1302
(!upack && buff[0] == '\xbe' && cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase) < min && /* mov esi */
1303
cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
1304
buff[5] == '\xad' && buff[6] == '\x8b' && buff[7] == '\xf8' && /* loads; mov edi, eax */
1305
EC16(file_hdr.NumberOfSections) == 2)) { /* 2 sections */
1309
cli_dbgmsg("Upack characteristics found.\n");
1310
a = EC32(section_hdr[0].VirtualSize);
1311
b = EC32(section_hdr[1].VirtualSize);
1313
cli_dbgmsg("upack var set\n");
1314
c = EC32(section_hdr[2].VirtualSize);
1315
ssize = EC32(section_hdr[0].SizeOfRawData) + EC32(section_hdr[0].PointerToRawData);
1316
off = EC32(section_hdr[0].VirtualAddress);
1317
vma = EC32(optional_hdr32.ImageBase) + EC32(section_hdr[0].VirtualAddress);
1319
cli_dbgmsg("upack var NOT set\n");
1320
c = EC32(section_hdr[1].VirtualAddress);
1321
ssize = EC32(section_hdr[1].PointerToRawData);
1323
vma = EC32(section_hdr[1].VirtualAddress) - EC32(section_hdr[1].PointerToRawData);
1327
if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || EC32(section_hdr[1].SizeOfRawData) > ctx->limits->maxfilesize))
1329
cli_dbgmsg("Upack: Sizes exceeded (a: %u, b: %u, c: %ux, max: %lu)\n", a, b, c, ctx->limits->maxfilesize);
1332
*ctx->virname = "PE.Upack.ExceededFileSize";
1338
/* these are unsigned so if vaddr - off < 0, it should be ok */
1339
if (EC32(section_hdr[1].VirtualAddress) - off > dsize || EC32(section_hdr[1].VirtualAddress) - off > dsize - EC32(section_hdr[1].SizeOfRawData) || (upack && (EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress) > dsize || EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress) > dsize - ssize)) || ssize > dsize)
1341
cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
1342
goto skip_upack_and_go_to_next_unpacker; /* I didn't want to add additional do while + break, can it be this way ? */
1519
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1524
if(fmap_readn(map, dest, 0, ssize) != ssize) {
1525
cli_dbgmsg("Upack: Can't read raw data of section 0\n");
1530
if(upack) memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
1532
if(fmap_readn(map, dest + exe_sections[1].rva - off, exe_sections[1].uraw, exe_sections[1].ursz) != exe_sections[1].ursz) {
1533
cli_dbgmsg("Upack: Can't read raw data of section 1\n");
1538
CLI_UNPTEMP("Upack",(dest,exe_sections,0));
1539
CLI_UNPRESULTS("Upack",(unupack(upack, dest, dsize, epbuff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)),1,(dest,0));
1545
while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\x87' && epbuff[1] == '\x25') {
1547
/* FSG v2.0 support - thanks to aCaB ! */
1549
uint32_t newesi, newedi, newebx, newedx;
1551
ssize = exe_sections[i + 1].rsz;
1552
dsize = exe_sections[i].vsz;
1554
CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1556
if(ssize <= 0x19 || dsize <= ssize) {
1557
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1562
newedx = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase);
1563
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1564
cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
1568
if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
1569
cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
1574
dest = src + newedx - exe_sections[i + 1].rva;
1575
if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
1576
cli_dbgmsg("FSG: New ESP out of bounds\n");
1580
newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1581
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1582
cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
1345
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1350
cli_dbgmsg("Upack: min: %08x %08x max: %08x\n", dest, a+b+c, dest+a+b+c);
1352
lseek(desc, 0, SEEK_SET);
1353
if(read(desc, dest, ssize) != ssize) { /* 2vGiM: i think this can be overflowed - should you check for ssize < dsize ?
1354
* yup, I think you're right, added above
1356
cli_dbgmsg("Upack: Can't read raw data of section 0\n");
1363
memmove(dest + EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress), dest, ssize);
1365
lseek(desc, EC32(section_hdr[1].PointerToRawData), SEEK_SET);
1367
if(read(desc, dest+EC32(section_hdr[1].VirtualAddress) - off, EC32(section_hdr[1].SizeOfRawData)) != EC32(section_hdr[1].SizeOfRawData)) {
1368
cli_dbgmsg("Upack: Can't read raw data of section 1\n");
1374
if(!(tempfile = cli_gentemp(NULL)))
1377
if((file = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
1378
cli_dbgmsg("Upack: Can't create file %s\n", tempfile);
1385
switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), EC32(section_hdr[0].VirtualAddress), file))
1387
case 1: /* Everything OK */
1388
cli_dbgmsg("Upack: Unpacked and rebuilt executable saved in %s\n", tempfile);
1391
lseek(file, 0, SEEK_SET);
1393
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1394
if(cli_magic_scandesc(file, ctx) == CL_VIRUS) {
1397
if(!cli_leavetemps_flag)
1404
if(!cli_leavetemps_flag)
1410
default: /* Everything gone wrong */
1411
cli_dbgmsg("Upack: Unpacking failed\n");
1413
unlink(tempfile); /* It's empty anyway */
1419
skip_upack_and_go_to_next_unpacker:
1421
if((DCONF & PE_CONF_FSG) && buff[0] == '\x87' && buff[1] == '\x25') {
1423
/* FSG v2.0 support - thanks to aCaB ! */
1425
ssize = exe_sections[i + 1].rsz;
1426
dsize = exe_sections[i].vsz;
1429
uint32_t newesi, newedi, newebx, newedx;
1431
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1432
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize);
1436
*ctx->virname = "PE.FSG.ExceededFileSize";
1443
if(ssize <= 0x19 || dsize <= ssize) {
1444
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1450
newedx = cli_readint32(buff + 2) - EC32(optional_hdr32.ImageBase);
1451
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1452
cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
1456
if((src = (char *) cli_malloc(ssize)) == NULL) {
1462
lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1463
if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1464
cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
1471
dest = src + newedx - exe_sections[i + 1].rva;
1472
if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
1473
cli_dbgmsg("FSG: New ESP out of bounds\n");
1478
newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1479
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
1480
cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
1586
dest = src + newedx - exe_sections[i + 1].rva;
1587
if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
1588
cli_dbgmsg("FSG: New stack out of bounds\n");
1592
newedi = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1593
newesi = cli_readint32(dest + 4) - EC32(optional_hdr32.ImageBase);
1594
newebx = cli_readint32(dest + 16) - EC32(optional_hdr32.ImageBase);
1595
newedx = cli_readint32(dest + 20);
1597
if(newedi != exe_sections[i].rva) {
1598
cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
1602
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1603
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1607
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
1608
cli_dbgmsg("FSG: Array of functions out of bounds\n");
1612
newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
1613
cli_dbgmsg("FSG: found old EP @%x\n",newedx);
1615
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1485
dest = src + newedx - exe_sections[i + 1].rva;
1486
if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
1487
cli_dbgmsg("FSG: New stack out of bounds\n");
1492
newedi = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
1493
newesi = cli_readint32(dest + 4) - EC32(optional_hdr32.ImageBase);
1494
newebx = cli_readint32(dest + 16) - EC32(optional_hdr32.ImageBase);
1495
newedx = cli_readint32(dest + 20);
1497
if(newedi != exe_sections[i].rva) {
1498
cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
1503
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1504
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1509
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
1510
cli_dbgmsg("FSG: Array of functions out of bounds\n");
1515
newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
1516
cli_dbgmsg("FSG: found old EP @%x\n",newedx);
1518
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1525
if(!(tempfile = cli_gentemp(NULL))) {
1533
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1534
cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1543
switch (unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)) {
1544
case 1: /* Everything OK */
1545
cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1549
lseek(ndesc, 0, SEEK_SET);
1551
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1552
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1556
if(!cli_leavetemps_flag)
1563
if(!cli_leavetemps_flag)
1570
case 0: /* We've got an unpacked buffer, no exe though */
1571
cli_dbgmsg("FSG: Successfully decompressed\n");
1577
break; /* Go and scan the buffer! */
1579
default: /* Everything gone wrong */
1580
cli_dbgmsg("FSG: Unpacking failed\n");
1582
unlink(tempfile); /* It's empty anyway */
1589
break; /* were done with 2 */
1593
if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1595
/* FSG support - v. 1.33 (thx trog for the many samples) */
1597
ssize = exe_sections[i + 1].rsz;
1598
dsize = exe_sections[i].vsz;
1603
uint32_t newesi, newedi, newebx, oldep, gp, t;
1604
struct cli_exe_section *sections;
1607
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1608
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize);
1612
*ctx->virname = "PE.FSG.ExceededFileSize";
1619
if(ssize <= 0x19 || dsize <= ssize) {
1620
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1626
if(!(gp = cli_rawaddr(cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize)) && err ) {
1627
cli_dbgmsg("FSG: Support data out of padding area\n");
1631
lseek(desc, gp, SEEK_SET);
1632
gp = exe_sections[i + 1].raw - gp;
1634
if(ctx->limits && ctx->limits->maxfilesize && (unsigned int) gp > ctx->limits->maxfilesize) {
1635
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize);
1639
*ctx->virname = "PE.FSG.ExceededFileSize";
1646
if((support = (char *) cli_malloc(gp)) == NULL) {
1652
if((int)cli_readn(desc, support, gp) != (int)gp) {
1653
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
1660
/* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase); Unused */
1661
newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
1662
newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
1664
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1665
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1670
if(newedi != exe_sections[i].rva) {
1671
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1676
/* Counting original sections */
1677
for(t = 12; t < gp - 4; t += 4) {
1678
uint32_t rva = cli_readint32(support+t);
1683
rva -= EC32(optional_hdr32.ImageBase)+1;
1687
/* FIXME: really need to bother? */
1688
cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
1690
if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1691
cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1696
if(t >= gp - 4 || cli_readint32(support + t)) {
1701
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1708
sections[0].rva = newedi;
1709
for(t = 1; t <= (uint32_t)sectcnt; t++)
1710
sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
1714
if((src = (char *) cli_malloc(ssize)) == NULL) {
1721
lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1722
if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1723
cli_dbgmsg("Can't read raw data of section %d\n", i);
1731
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1739
oldep = vep + 161 + 6 + cli_readint32(buff+163);
1740
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1742
if(!(tempfile = cli_gentemp(NULL))) {
1751
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1752
cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1762
switch(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) {
1763
case 1: /* Everything OK */
1764
cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1769
lseek(ndesc, 0, SEEK_SET);
1771
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1772
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1776
if(!cli_leavetemps_flag)
1783
if(!cli_leavetemps_flag)
1790
case 0: /* We've got an unpacked buffer, no exe though */
1791
cli_dbgmsg("FSG: Successfully decompressed\n");
1798
break; /* Go and scan the buffer! */
1800
default: /* Everything gone wrong */
1801
cli_dbgmsg("FSG: Unpacking failed\n");
1803
unlink(tempfile); /* It's empty anyway */
1811
break; /* were done with 1.33 */
1815
/* FIXME: easy 2 hack */
1816
if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbb' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min && buff[5] == '\xbf' && buff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1818
/* FSG support - v. 1.31 */
1820
ssize = exe_sections[i + 1].rsz;
1821
dsize = exe_sections[i].vsz;
1826
uint32_t gp = cli_rawaddr(cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize);
1828
uint32_t newesi = cli_readint32(buff+11) - EC32(optional_hdr32.ImageBase);
1829
uint32_t newedi = cli_readint32(buff+6) - EC32(optional_hdr32.ImageBase);
1830
uint32_t oldep = vep - exe_sections[i + 1].rva;
1831
struct cli_exe_section *sections;
1834
cli_dbgmsg("FSG: Support data out of padding area\n");
1838
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
1839
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1843
if(newedi != exe_sections[i].rva) {
1844
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1848
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
1849
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize);
1853
*ctx->virname = "PE.FSG.ExceededFileSize";
1860
if(ssize <= 0x19 || dsize <= ssize) {
1861
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1867
lseek(desc, gp, SEEK_SET);
1868
gp = exe_sections[i + 1].raw - gp;
1870
if(ctx->limits && ctx->limits->maxfilesize && gp > ctx->limits->maxfilesize) {
1871
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize);
1875
*ctx->virname = "PE.FSG.ExceededFileSize";
1882
if((support = (char *) cli_malloc(gp)) == NULL) {
1888
if(cli_readn(desc, support, gp) != (int)gp) {
1889
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
1896
/* Counting original sections */
1897
for(t = 0; t < gp - 2; t += 2) {
1898
uint32_t rva = support[t]|(support[t+1]<<8);
1900
if (rva == 2 || rva == 1)
1903
rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
1906
if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1907
cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1912
if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
1917
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1924
sections[0].rva = newedi;
1925
for(t = 0; t <= (uint32_t)sectcnt - 1; t++) {
1926
sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
1931
if((src = (char *) cli_malloc(ssize)) == NULL) {
1938
lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
1939
if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1940
cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
1948
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1956
/* Better not increasing buff size any further, let's go the hard way */
1957
gp = 0xda + 6*(buff[16]=='\xe8');
1958
oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
1959
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1961
if(!(tempfile = cli_gentemp(NULL))) {
1970
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
1971
cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
1981
switch(unfsg_133(src + newesi - EC32(section_hdr[i + 1].VirtualAddress), dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) {
1982
case 1: /* Everything OK */
1983
cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
1988
lseek(ndesc, 0, SEEK_SET);
1990
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
1991
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1995
if(!cli_leavetemps_flag)
2002
if(!cli_leavetemps_flag)
2009
case 0: /* We've got an unpacked buffer, no exe though */
2010
cli_dbgmsg("FSG: FSG: Successfully decompressed\n");
2017
break; /* Go and scan the buffer! */
2019
default: /* Everything gone wrong */
2020
cli_dbgmsg("FSG: Unpacking failed\n");
2022
unlink(tempfile); /* It's empty anyway */
2030
break; /* were done with 1.31 */
2035
if(found && (DCONF & PE_CONF_UPX)) {
2039
strncpy(sname, (char *) section_hdr[i].Name, 8);
2041
cli_dbgmsg("UPX: Section %d name: %s\n", i, sname);
2042
strncpy(sname, (char *) section_hdr[i + 1].Name, 8);
2044
cli_dbgmsg("UPX: Section %d name: %s\n", i + 1, sname);
2046
if(strncmp((char *) section_hdr[i].Name, "UPX0", 4) || strncmp((char *) section_hdr[i + 1].Name, "UPX1", 4))
2047
cli_dbgmsg("UPX: Possibly hacked UPX section headers\n");
2049
/* we assume (i + 1) is UPX1 */
2050
ssize = exe_sections[i + 1].rsz;
2051
dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
2053
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
2054
cli_dbgmsg("UPX: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize);
2058
*ctx->virname = "PE.UPX.ExceededFileSize";
2065
if(ssize <= 0x19 || dsize <= ssize) { /* FIXME: What are reasonable values? */
2066
cli_dbgmsg("UPX: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
2072
/* FIXME: use file operations in case of big files */
2073
if((src = (char *) cli_malloc(ssize)) == NULL) {
2079
if(dsize > CLI_MAX_ALLOCATION) {
2080
cli_errmsg("UPX: Too big value of dsize\n");
2087
if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
2094
lseek(desc, exe_sections[i + 1].raw, SEEK_SET);
2095
if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
2096
cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
2104
/* try to detect UPX code */
2106
if(lseek(desc, ep, SEEK_SET) == -1) {
2107
cli_dbgmsg("UPX: lseek() failed\n");
2115
if(cli_readn(desc, buff, 126) != 126) { /* i.e. 0x69 + 13 + 8 */
2116
cli_dbgmsg("UPX: Can't read 126 bytes at 0x%x (%d)\n", ep, ep);
2117
cli_dbgmsg("UPX: Broken or not UPX compressed file\n");
2124
if(cli_memstr(UPX_NRV2B, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, buff + 0x69 + 8, 13)) {
2125
cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
2126
upxfn = upx_inflate2b;
2127
} else if(cli_memstr(UPX_NRV2D, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, buff + 0x69 + 8, 13)) {
2128
cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
2129
upxfn = upx_inflate2d;
2130
} else if(cli_memstr(UPX_NRV2E, 24, buff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, buff + 0x69 + 8, 13)) {
2131
cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
2132
upxfn = upx_inflate2e;
2137
int skew = cli_readint32(buff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
2139
if(buff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
2141
if(upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
2145
cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
2146
if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0 || upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
2151
cli_dbgmsg("UPX: Successfully decompressed\n");
2153
cli_dbgmsg("UPX: Preferred decompressor failed\n");
2156
if(!upx_success && upxfn != upx_inflate2b) {
2157
if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2159
cli_dbgmsg("UPX: NRV2B decompressor failed\n");
2162
cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
2166
if(!upx_success && upxfn != upx_inflate2d) {
2167
if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2169
cli_dbgmsg("UPX: NRV2D decompressor failed\n");
2172
cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
2176
if(!upx_success && upxfn != upx_inflate2e) {
2177
if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
2178
cli_dbgmsg("UPX: NRV2E decompressor failed\n");
2181
cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
2186
cli_dbgmsg("UPX: All decompressors failed\n");
1621
CLI_UNPTEMP("FSG",(dest,exe_sections,0));
1622
CLI_UNPRESULTSFSG2("FSG",(unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)),1,(dest,0));
1627
while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1629
/* FSG support - v. 1.33 (thx trog for the many samples) */
1633
uint32_t newesi, newedi, oldep, gp, t;
1634
struct cli_exe_section *sections;
1636
ssize = exe_sections[i + 1].rsz;
1637
dsize = exe_sections[i].vsz;
1639
CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1641
if(ssize <= 0x19 || dsize <= ssize) {
1642
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1647
if(!(t = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
1648
cli_dbgmsg("FSG: Support data out of padding area\n");
1652
gp = exe_sections[i + 1].raw - t;
1654
CLI_UNPSIZELIMITS("FSG", gp);
1656
if(!(support = fmap_need_off_once(map, t, gp))) {
1657
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
1662
/* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase); Unused */
1663
newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
1664
newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
1666
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
1667
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1671
if(newedi != exe_sections[i].rva) {
1672
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1676
/* Counting original sections */
1677
for(t = 12; t < gp - 4; t += 4) {
1678
uint32_t rva = cli_readint32(support+t);
1683
rva -= EC32(optional_hdr32.ImageBase)+1;
1686
if(rva % 0x1000) cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
1688
if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1689
cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1694
if(t >= gp - 4 || cli_readint32(support + t)) {
1698
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1703
sections[0].rva = newedi;
1704
for(t = 1; t <= (uint32_t)sectcnt; t++)
1705
sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
1707
if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
1708
cli_dbgmsg("Can't read raw data of section %d\n", i);
1714
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1720
oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
1721
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1723
CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
1724
CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
1725
break; /* were done with 1.33 */
1729
while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbb' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min && epbuff[5] == '\xbf' && epbuff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1731
/* FSG support - v. 1.31 */
1734
uint32_t gp, t = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
1736
uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
1737
uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
1738
uint32_t oldep = vep - exe_sections[i + 1].rva;
1739
struct cli_exe_section *sections;
1741
ssize = exe_sections[i + 1].rsz;
1742
dsize = exe_sections[i].vsz;
1745
cli_dbgmsg("FSG: Support data out of padding area\n");
1749
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
1750
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
1754
if(newedi != exe_sections[i].rva) {
1755
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
1759
CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
1761
if(ssize <= 0x19 || dsize <= ssize) {
1762
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
1767
gp = exe_sections[i + 1].raw - t;
1769
CLI_UNPSIZELIMITS("FSG", gp)
1771
if(!(support = fmap_need_off_once(map, t, gp))) {
1772
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
1777
/* Counting original sections */
1778
for(t = 0; t < gp - 2; t += 2) {
1779
uint32_t rva = support[t]|(support[t+1]<<8);
1781
if (rva == 2 || rva == 1)
1784
rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
1787
if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
1788
cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
1793
if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
1797
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
1802
sections[0].rva = newedi;
1803
for(t = 0; t <= (uint32_t)sectcnt - 1; t++) {
1804
sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
1807
if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
1808
cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
1814
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
1820
gp = 0xda + 6*(epbuff[16]=='\xe8');
1821
oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
1822
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
1824
CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
1825
CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
1826
break; /* were done with 1.31 */
1830
if(found && (DCONF & PE_CONF_UPX)) {
1834
/* we assume (i + 1) is UPX1 */
1835
ssize = exe_sections[i + 1].rsz;
1836
dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
1838
CLI_UNPSIZELIMITS("UPX", MAX(dsize, ssize));
1840
if(ssize <= 0x19 || dsize <= ssize || dsize > CLI_MAX_ALLOCATION ) {
1841
cli_dbgmsg("UPX: Size mismatch or dsize too big (ssize: %d, dsize: %d)\n", ssize, dsize);
1846
if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
1847
cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
1852
if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
1857
/* try to detect UPX code */
1858
if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
1859
cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
1860
upxfn = upx_inflate2b;
1861
} else if(cli_memstr(UPX_NRV2D, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, epbuff + 0x69 + 8, 13)) {
1862
cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
1863
upxfn = upx_inflate2d;
1864
} else if(cli_memstr(UPX_NRV2E, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, epbuff + 0x69 + 8, 13)) {
1865
cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
1866
upxfn = upx_inflate2e;
1870
int skew = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
1872
if(epbuff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
1874
if(upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
1878
cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
1879
if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0 || upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)
1884
cli_dbgmsg("UPX: Successfully decompressed\n");
1886
cli_dbgmsg("UPX: Preferred decompressor failed\n");
1889
if(!upx_success && upxfn != upx_inflate2b) {
1890
if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1892
cli_dbgmsg("UPX: NRV2B decompressor failed\n");
1895
cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
1899
if(!upx_success && upxfn != upx_inflate2d) {
1900
if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1902
cli_dbgmsg("UPX: NRV2D decompressor failed\n");
1905
cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
1909
if(!upx_success && upxfn != upx_inflate2e) {
1910
if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
1911
cli_dbgmsg("UPX: NRV2E decompressor failed\n");
1914
cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
1918
if(cli_memstr(UPX_LZMA2, 20, epbuff + 0x2f, 20)) {
1919
uint32_t strictdsize=cli_readint32(epbuff+0x21), skew = 0;
1920
if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
1921
skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
1922
if(skew!=0x15) skew = 0;
1924
if(strictdsize<=dsize)
1925
upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
1926
} else if (cli_memstr(UPX_LZMA1, 20, epbuff + 0x39, 20)) {
1927
uint32_t strictdsize=cli_readint32(epbuff+0x2b), skew = 0;
1928
if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
1929
skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
1930
if(skew!=0x15) skew = 0;
1932
if(strictdsize<=dsize)
1933
upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
1937
cli_dbgmsg("UPX: All decompressors failed\n");
1945
CLI_UNPTEMP("UPX/FSG",(dest,0));
1947
if((unsigned int) write(ndesc, dest, dsize) != dsize) {
1948
cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
1956
lseek(ndesc, 0, SEEK_SET);
1958
if(ctx->engine->keeptmp)
1959
cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
1961
cli_dbgmsg("***** Scanning decompressed file *****\n");
1963
if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
2197
if(!(tempfile = cli_gentemp(NULL))) {
2202
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2203
cli_dbgmsg("UPX/FSG: Can't create file %s\n", tempfile);
2209
if((unsigned int) write(ndesc, dest, dsize) != dsize) {
2210
cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
2219
lseek(ndesc, 0, SEEK_SET);
2221
if(cli_leavetemps_flag)
2222
cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
2224
cli_dbgmsg("***** Scanning decompressed file *****\n");
2225
if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
2227
if(!cli_leavetemps_flag)
2234
if(!cli_leavetemps_flag)
1988
if(epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 1].rva + EC32(optional_hdr32.ImageBase)) {
1989
if(nsections < 2 || epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase))
2245
lseek(desc, ep, SEEK_SET);
2246
memset(buff, 0, sizeof(buff));
2247
if(cli_readn(desc, buff, 200) == -1) {
2248
cli_dbgmsg("cli_readn() failed\n");
2254
if(buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(optional_hdr32.ImageBase)) {
2255
if(nsections < 2 || buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != EC32(section_hdr[nsections - 2].VirtualAddress) + EC32(optional_hdr32.ImageBase))
1995
if(found && (DCONF & PE_CONF_PETITE)) {
2261
if((DCONF & PE_CONF_PETITE) && found) {
1996
2262
cli_dbgmsg("Petite: v2.%d compression detected\n", found);
1998
if(cli_readint32(epbuff + 0x80) == 0x163c988d) {
2264
if(cli_readint32(buff + 0x80) == 0x163c988d) {
1999
2265
cli_dbgmsg("Petite: level zero compression is not supported yet\n");
2001
2267
dsize = max - min;
2003
CLI_UNPSIZELIMITS("Petite", dsize);
2269
if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) {
2270
cli_dbgmsg("Petite: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize);
2274
*ctx->virname = "PE.Petite.ExceededFileSize";
2005
2281
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
2006
2282
cli_dbgmsg("Petite: Can't allocate %d bytes\n", dsize);
2007
2284
free(exe_sections);
2008
2285
return CL_EMEM;
2011
2288
for(i = 0 ; i < nsections; i++) {
2012
if(exe_sections[i].raw) {
2013
if(!exe_sections[i].rsz || fmap_readn(map, dest + exe_sections[i].rva - min, exe_sections[i].raw, exe_sections[i].ursz) != exe_sections[i].ursz) {
2289
if(section_hdr[i].SizeOfRawData) {
2290
uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), exe_sections, nsections, &err, fsize);
2292
if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
2014
2294
free(exe_sections);
2021
CLI_UNPTEMP("Petite",(dest,exe_sections,0));
2022
CLI_UNPRESULTS("Petite",(petite_inflate2x_1to9(dest, min, max - min, exe_sections, nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),EC32(optional_hdr32.DataDirectory[2].Size))),0,(dest,0));
2301
if(!(tempfile = cli_gentemp(NULL))) {
2308
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2309
cli_dbgmsg("Petite: Can't create file %s\n", tempfile);
2317
/* aCaB: Fixed to allow petite v2.1 unpacking (last section is a ghost) */
2318
if (!petite_inflate2x_1to9(dest, min, max - min, section_hdr,
2319
nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),
2320
vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),
2321
EC32(optional_hdr32.DataDirectory[2].Size))) {
2322
cli_dbgmsg("Petite: Unpacked and rebuilt executable saved in %s\n", tempfile);
2323
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
2326
lseek(ndesc, 0, SEEK_SET);
2327
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2331
if(!cli_leavetemps_flag) {
2339
cli_dbgmsg("Petite: Unpacking failed\n");
2343
if(!cli_leavetemps_flag) {
2026
2350
/* PESpin 1.1 */
2028
2352
if((DCONF & PE_CONF_PESPIN) && nsections > 1 &&
2029
vep >= exe_sections[nsections - 1].rva &&
2030
vep < exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz - 0x3217 - 4 &&
2031
memcmp(epbuff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0) {
2035
CLI_UNPSIZELIMITS("PEspin", fsize);
2353
vep >= EC32(section_hdr[nsections - 1].VirtualAddress) &&
2354
vep < EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(section_hdr[nsections - 1].SizeOfRawData) - 0x3217 - 4 &&
2355
memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0) {
2359
if(ctx->limits && ctx->limits->maxfilesize && fsize > ctx->limits->maxfilesize) {
2360
cli_dbgmsg("PEspin: Size exceeded (fsize: %u, max: %lu)\n", fsize, ctx->limits->maxfilesize);
2364
*ctx->virname = "PE.Pespin.ExceededFileSize";
2037
2371
if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2038
2373
free(exe_sections);
2039
2374
return CL_EMEM;
2042
if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
2043
cli_dbgmsg("PESpin: Can't read %lu bytes\n", (unsigned long)fsize);
2049
CLI_UNPTEMP("PESpin",(spinned,exe_sections,0));
2050
CLI_UNPRESULTS_("PEspin",SPINCASE(),(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)),0,(spinned,0));
2377
lseek(desc, 0, SEEK_SET);
2378
if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
2379
cli_dbgmsg("PESpin: Can't read %d bytes\n", fsize);
2386
if(!(tempfile = cli_gentemp(NULL))) {
2393
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2394
cli_dbgmsg("PESpin: Can't create file %s\n", tempfile);
2402
switch(unspin(spinned, fsize, section_hdr, nsections - 1, vep, ndesc, ctx)) {
2405
if(cli_leavetemps_flag)
2406
cli_dbgmsg("PESpin: Unpacked and rebuilt executable saved in %s\n", tempfile);
2408
cli_dbgmsg("PESpin: Unpacked and rebuilt executable\n");
2410
lseek(ndesc, 0, SEEK_SET);
2411
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2413
if(!cli_leavetemps_flag)
2421
if(!cli_leavetemps_flag)
2428
cli_dbgmsg("PESpin: Rebuilding failed\n");
2434
cli_dbgmsg("PESpin: Size exceeded\n");
2439
*ctx->virname = "PE.Pespin.ExceededFileSize";
2054
/* yC 1.3 & variants */
2055
2450
if((DCONF & PE_CONF_YC) && nsections > 1 &&
2056
(EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60)) {
2062
if (!memcmp(epbuff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED", 15) &&
2063
!memcmp(epbuff+0x26, "\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 13) &&
2064
((uint8_t)epbuff[0x13] == 0xB9) &&
2065
((uint16_t)(cli_readint16(epbuff+0x18)) == 0xE981) &&
2066
!memcmp(epbuff+0x1e,"\x8B\xD5\x81\xC2", 4)) {
2069
if (0x6c - cli_readint32(epbuff+0xf) + cli_readint32(epbuff+0x22) == 0xC6)
2070
ecx = cli_readint32(epbuff+0x14) - cli_readint32(epbuff+0x1a);
2073
/* yC 1.3 variant */
2074
if (!ecx && !memcmp(epbuff, "\x55\x8B\xEC\x83\xEC\x40\x53\x56\x57", 9) &&
2075
!memcmp(epbuff+0x17, "\xe8\x00\x00\x00\x00\x5d\x81\xed", 8) &&
2076
((uint8_t)epbuff[0x23] == 0xB9)) {
2079
if (0x6c - cli_readint32(epbuff+0x1f) + cli_readint32(epbuff+0x32) == 0xC6)
2080
ecx = cli_readint32(epbuff+0x24) - cli_readint32(epbuff+0x2a);
2083
/* yC 1.x/modified */
2084
if (!ecx && !memcmp(epbuff, "\x60\xe8\x00\x00\x00\x00\x5d\x81\xed",9) &&
2085
((uint8_t)epbuff[0xd] == 0xb9) &&
2086
((uint16_t)cli_readint16(epbuff + 0x12)== 0xbd8d) &&
2087
!memcmp(epbuff+0x18, "\x8b\xf7\xac", 3)) {
2090
if (0x66 - cli_readint32(epbuff+0x9) + cli_readint32(epbuff+0x14) == 0xae)
2091
ecx = cli_readint32(epbuff+0xe);
2094
if (ecx > 0x800 && ecx < 0x2000 &&
2095
!memcmp(epbuff+0x63+offset, "\xaa\xe2\xcc", 3) &&
2096
(fsize >= exe_sections[nsections-1].raw + 0xC6 + ecx + offset)) {
2100
if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2105
if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
2106
cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
2112
cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
2113
CLI_UNPTEMP("yC",(spinned,exe_sections,0));
2114
CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
2451
EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) + 0x60 &&
2452
memcmp(buff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0) {
2456
if ( fsize >= EC32(section_hdr[nsections - 1].PointerToRawData) + 0xC6 + 0xb97 ) { /* size check on yC sect */
2457
if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2463
lseek(desc, 0, SEEK_SET);
2464
if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
2465
cli_dbgmsg("yC: Can't read %d bytes\n", fsize);
2472
if(!(tempfile = cli_gentemp(NULL))) {
2479
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2480
cli_dbgmsg("yC: Can't create file %s\n", tempfile);
2488
if(!yc_decrypt(spinned, fsize, section_hdr, nsections-1, e_lfanew, ndesc)) {
2490
cli_dbgmsg("yC: Unpacked and rebuilt executable saved in %s\n", tempfile);
2492
lseek(ndesc, 0, SEEK_SET);
2494
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2498
if(!cli_leavetemps_flag) {
2509
cli_dbgmsg("yC: Rebuilding failed\n");
2513
if(!cli_leavetemps_flag) {
2120
while ((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
2526
if((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
2527
exe_sections[nsections-1].raw>0x2b1 &&
2121
2528
vep == exe_sections[nsections - 1].rva &&
2122
memcmp(epbuff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
2123
memcmp(epbuff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0) {
2124
uint32_t head = exe_sections[nsections - 1].raw;
2129
if(exe_sections[i].raw<head)
2130
head=exe_sections[i].raw;
2131
if(i+1==nsections) break;
2132
if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
2133
ssize=exe_sections[i].rva+exe_sections[i].vsz;
2135
if(!head || !ssize || head>ssize) break;
2137
CLI_UNPSIZELIMITS("WWPack", ssize);
2139
if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
2143
if((size_t) fmap_readn(map, src, 0, head) != head) {
2144
cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
2149
for(i = 0 ; i < (unsigned int)nsections-1; i++) {
2150
if(!exe_sections[i].rsz) continue;
2151
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
2152
if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
2154
if(i+1!=nsections) {
2155
cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
2159
if((packer = (uint8_t *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
2164
if(!exe_sections[nsections - 1].rsz || (size_t) fmap_readn(map, packer, exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
2165
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
2172
CLI_UNPTEMP("WWPack",(src,packer,exe_sections,0));
2173
CLI_UNPRESULTS("WWPack",(wwunpack((uint8_t *)src, ssize, packer, exe_sections, nsections-1, e_lfanew, ndesc)),0,(src,packer,0));
2178
/* ASPACK support */
2179
while((DCONF & PE_CONF_ASPACK) && ep+58+0x70e < fsize && !memcmp(epbuff,"\x60\xe8\x03\x00\x00\x00\xe9\xeb",8)) {
2181
if(epsize<0x3bf || memcmp(epbuff+0x3b9, "\x68\x00\x00\x00\x00\xc3",6)) break;
2183
for(i=0 ; i< nsections ; i++)
2184
if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
2185
ssize=exe_sections[i].rva+exe_sections[i].vsz;
2188
CLI_UNPSIZELIMITS("Aspack", ssize);
2190
if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
2194
for(i = 0 ; i < (unsigned int)nsections; i++) {
2195
if(!exe_sections[i].rsz) continue;
2196
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
2197
if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
2200
cli_dbgmsg("Aspack: Probably hacked/damaged Aspack file.\n");
2205
CLI_UNPTEMP("Aspack",(src,exe_sections,0));
2206
CLI_UNPRESULTS("Aspack",(unaspack212((uint8_t *)src, ssize, exe_sections, nsections, vep-1, EC32(optional_hdr32.ImageBase), ndesc)),1,(src,0));
2529
exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz == max &&
2530
memcmp(buff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
2531
memcmp(buff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0) {
2532
uint32_t headsize=exe_sections[nsections - 1].raw;
2535
for(i = 0 ; i < (unsigned int)nsections-1; i++)
2536
if (!err && exe_sections[i].raw<headsize) headsize=exe_sections[i].raw;
2538
dsize = max-min+headsize-exe_sections[nsections - 1].rsz;
2540
if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) {
2541
cli_dbgmsg("WWPack: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize);
2545
*ctx->virname = "PE.WWPack.ExceededFileSize";
2552
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
2553
cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
2558
memset(dest, 0, dsize);
2560
lseek(desc, 0, SEEK_SET);
2561
if((size_t) cli_readn(desc, dest, headsize) != headsize) {
2562
cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
2569
for(i = 0 ; i < (unsigned int)nsections-1; i++) {
2570
if(exe_sections[i].rsz) {
2571
uint32_t offset = exe_sections[i].raw;
2573
if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + headsize + exe_sections[i].rva - min, exe_sections[i].rsz) != exe_sections[i].rsz) {
2582
if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
2583
cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz);
2590
lseek(desc, exe_sections[nsections - 1].raw, SEEK_SET);
2591
if((size_t) cli_readn(desc, wwp, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
2592
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
2600
if (!wwunpack(dest, dsize, headsize, min, exe_sections[nsections-1].rva, e_lfanew, wwp, exe_sections[nsections - 1].rsz, nsections-1)) {
2604
if(!(tempfile = cli_gentemp(NULL))) {
2611
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2612
cli_dbgmsg("WWPack: Can't create file %s\n", tempfile);
2620
if((unsigned int) write(ndesc, dest, dsize) != dsize) {
2621
cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
2631
if (cli_leavetemps_flag)
2632
cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
2634
cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
2637
lseek(ndesc, 0, SEEK_SET);
2639
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2643
if(!cli_leavetemps_flag)
2650
if(!cli_leavetemps_flag)
2656
cli_dbgmsg("WWPpack: Decompression failed\n");
2212
2662
while (DCONF & PE_CONF_NSPACK) {
2213
uint32_t eprva = vep;
2214
uint32_t start_of_stuff, ssize, dsize, rep = ep;
2215
unsigned int nowinldr;
2217
char *src=epbuff, *dest;
2219
if (*epbuff=='\xe9') { /* bitched headers */
2220
eprva = cli_readint32(epbuff+1)+vep+5;
2221
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
2222
if (!(nbuff = fmap_need_off_once(map, rep, 24))) break;
2226
if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13)) break;
2228
nowinldr = 0x54-cli_readint32(src+17);
2229
cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
2231
if(!(nbuff = fmap_need_off_once(map, rep-nowinldr, 4))) break;
2232
start_of_stuff=rep+cli_readint32(nbuff);
2233
if(!(nbuff = fmap_need_off_once(map, start_of_stuff, 20))) break;
2663
uint32_t eprva = vep;
2664
uint32_t start_of_stuff, ssize, dsize, rep = ep;
2665
unsigned int nowinldr;
2667
char *src=buff, *dest;
2670
if (*buff=='\xe9') { /* bitched headers */
2671
eprva = cli_readint32(buff+1)+vep+5;
2672
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize)) && err) break;
2673
if (lseek(desc, rep, SEEK_SET)==-1) break;
2674
if (cli_readn(desc, nbuff, 24)!=24) break;
2235
if (!cli_readint32(nbuff)) {
2236
start_of_stuff+=4; /* FIXME: more to do */
2240
ssize = cli_readint32(src+5)|0xff;
2241
dsize = cli_readint32(src+9);
2243
CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
2245
if (!ssize || !dsize || dsize != exe_sections[0].vsz) break;
2246
if (!(dest=cli_malloc(dsize))) break;
2247
/* memset(dest, 0xfc, dsize); */
2249
if(!(src = fmap_need_off(map, start_of_stuff, ssize))) {
2253
/* memset(src, 0x00, ssize); */
2256
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
2260
if(!(nbuff = fmap_need_off_once(map, rep, 5))) {
2264
fmap_unneed_off(map, start_of_stuff, ssize);
2265
eprva=eprva+5+cli_readint32(nbuff+1);
2266
cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
2268
CLI_UNPTEMP("NsPack",(dest,exe_sections,0));
2269
CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(dest,0));
2678
if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13)) break;
2680
nowinldr = 0x54-cli_readint32(src+17);
2681
cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
2683
if (lseek(desc, rep-nowinldr, SEEK_SET)==-1) break;
2684
if (cli_readn(desc, nbuff, 4)!=4) break;
2685
start_of_stuff=rep+cli_readint32(nbuff);
2686
if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2687
if (cli_readn(desc, nbuff, 20)!=20) break;
2689
if (!cli_readint32(nbuff)) {
2690
start_of_stuff+=4; /* FIXME: more to do */
2694
ssize = cli_readint32(src+5)|0xff;
2695
dsize = cli_readint32(src+9);
2697
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) {
2698
cli_dbgmsg("NsPack: Size exceeded\n");
2702
*ctx->virname = "PE.NsPack.ExceededFileSize";
2709
if ( !ssize || !dsize || dsize != exe_sections[0].vsz) break;
2710
if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
2711
if (!(dest=cli_malloc(dsize))) break;
2712
/* memset(dest, 0xfc, dsize); */
2714
if (!(src=cli_malloc(ssize))) {
2718
/* memset(src, 0x00, ssize); */
2719
cli_readn(desc, src, ssize);
2722
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize)) && err) break;
2723
if (lseek(desc, rep, SEEK_SET)==-1) break;
2724
if (cli_readn(desc, nbuff, 5)!=5) break;
2725
eprva=eprva+5+cli_readint32(nbuff+1);
2726
cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
2728
if(!(tempfile = cli_gentemp(NULL))) {
2736
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
2737
cli_dbgmsg("NsPack: Can't create file %s\n", tempfile);
2746
if (!unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)) {
2749
if (cli_leavetemps_flag)
2750
cli_dbgmsg("NsPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
2752
cli_dbgmsg("NsPack: Unpacked and rebuilt executable\n");
2754
lseek(ndesc, 0, SEEK_SET);
2756
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
2760
if(!cli_leavetemps_flag) unlink(tempfile);
2767
cli_dbgmsg("NsPack: Unpacking failed\n");
2770
if(!cli_leavetemps_flag) unlink(tempfile);
2273
2775
/* to be continued ... */
2275
/* Bytecode BC_PE_UNPACKER hook */
2276
bc_ctx = cli_bytecode_context_alloc();
2278
cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
2281
cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections);
2282
cli_bytecode_context_setctx(bc_ctx, ctx);
2283
ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
2287
cli_bytecode_context_destroy(bc_ctx);
2290
ndesc = cli_bytecode_context_getresult_file(bc_ctx, &tempfile);
2291
cli_bytecode_context_destroy(bc_ctx);
2292
if (ndesc != -1 && tempfile) {
2293
CLI_UNPRESULTS("bytecode PE hook", 1, 1, (0));
2297
cli_bytecode_context_destroy(bc_ctx);
2300
2778
free(exe_sections);
2301
2779
return CL_CLEAN;
2304
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo)
2782
int cli_peheader(int desc, struct cli_exe_info *peinfo)
2306
2784
uint16_t e_magic; /* DOS signature ("MZ") */
2307
2785
uint32_t e_lfanew; /* address of new exe header */