TODO:
- check consistency in elf parser, packers and rebuildpe
- remove hardcoded header size
- fix check for 1st sect rva
- ...
git-svn-id: file:///var/lib/svn/clamav-devel/branches/temp_branch_pe_cleanup@2938 77e5149b-7576-45b1-b177-96237e5ba77b
| ... | ... |
@@ -26,10 +26,14 @@ |
| 26 | 26 |
struct cli_exe_section {
|
| 27 | 27 |
uint32_t rva; |
| 28 | 28 |
uint32_t vsz; |
| 29 |
- uint32_t uvsz; /* unaligned vsz */ |
|
| 30 | 29 |
uint32_t raw; |
| 31 | 30 |
uint32_t rsz; |
| 32 |
- uint32_t ursz; |
|
| 31 |
+ uint32_t chr; |
|
| 32 |
+ uint32_t urva; /* PE - unaligned VirtualAddress */ |
|
| 33 |
+ uint32_t uvsz; /* PE - unaligned VirtualSize */ |
|
| 34 |
+ uint32_t uraw; /* PE - unaligned PointerToRawData */ |
|
| 35 |
+ uint32_t ursz; /* PE - unaligned SizeOfRawData */ |
|
| 36 |
+ |
|
| 33 | 37 |
}; |
| 34 | 38 |
|
| 35 | 39 |
struct cli_exe_info {
|
| ... | ... |
@@ -235,7 +235,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 235 | 235 |
uint16_t nsections; |
| 236 | 236 |
uint32_t e_lfanew; /* address of new exe header */ |
| 237 | 237 |
uint32_t ep, vep; /* entry point (raw, virtual) */ |
| 238 |
- uint8_t polipos = 0, magistr; |
|
| 238 |
+ uint8_t polipos = 0; |
|
| 239 | 239 |
time_t timestamp; |
| 240 | 240 |
struct pe_image_file_hdr file_hdr; |
| 241 | 241 |
union {
|
| ... | ... |
@@ -639,13 +639,16 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 639 | 639 |
sname[8] = 0; |
| 640 | 640 |
exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign); |
| 641 | 641 |
exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign); |
| 642 |
- exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize); |
|
| 643 | 642 |
exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign); |
| 644 | 643 |
exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign); |
| 644 |
+ exe_sections[i].chr = EC32(section_hdr[i].Characteristics); |
|
| 645 |
+ exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */ |
|
| 646 |
+ exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize); |
|
| 647 |
+ exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData); |
|
| 645 | 648 |
exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData); |
| 646 | 649 |
|
| 647 | 650 |
if (!exe_sections[i].vsz && exe_sections[i].rsz) |
| 648 |
- exe_sections[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign); |
|
| 651 |
+ exe_sections[i].vsz=PESALIGN(exe_sections[i].ursz, valign); |
|
| 649 | 652 |
|
| 650 | 653 |
if (exe_sections[i].rsz && fsize>exe_sections[i].raw && !CLI_ISCONTAINED(0, (uint32_t) fsize, exe_sections[i].raw, exe_sections[i].rsz)) |
| 651 | 654 |
exe_sections[i].rsz = fsize - exe_sections[i].raw; |
| ... | ... |
@@ -653,12 +656,12 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 653 | 653 |
cli_dbgmsg("Section %d\n", i);
|
| 654 | 654 |
cli_dbgmsg("Section name: %s\n", sname);
|
| 655 | 655 |
cli_dbgmsg("Section data (from headers - in memory)\n");
|
| 656 |
- cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", EC32(section_hdr[i].VirtualSize), exe_sections[i].vsz);
|
|
| 657 |
- cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", EC32(section_hdr[i].VirtualAddress), exe_sections[i].rva);
|
|
| 658 |
- cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", EC32(section_hdr[i].SizeOfRawData), exe_sections[i].rsz);
|
|
| 659 |
- cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", EC32(section_hdr[i].PointerToRawData), exe_sections[i].raw);
|
|
| 656 |
+ cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", exe_sections[i].uvsz, exe_sections[i].vsz);
|
|
| 657 |
+ cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", exe_sections[i].urva, exe_sections[i].rva);
|
|
| 658 |
+ cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", exe_sections[i].ursz, exe_sections[i].rsz);
|
|
| 659 |
+ cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", exe_sections[i].uraw, exe_sections[i].raw);
|
|
| 660 | 660 |
|
| 661 |
- if(EC32(section_hdr[i].Characteristics) & 0x20) {
|
|
| 661 |
+ if(exe_sections[i].chr & 0x20) {
|
|
| 662 | 662 |
cli_dbgmsg("Section contains executable code\n");
|
| 663 | 663 |
|
| 664 | 664 |
if(exe_sections[i].vsz < exe_sections[i].rsz) {
|
| ... | ... |
@@ -671,15 +674,15 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 671 | 671 |
} |
| 672 | 672 |
} |
| 673 | 673 |
|
| 674 |
- if(EC32(section_hdr[i].Characteristics) & 0x20000000) |
|
| 674 |
+ if(exe_sections[i].chr & 0x20000000) |
|
| 675 | 675 |
cli_dbgmsg("Section's memory is executable\n");
|
| 676 | 676 |
|
| 677 |
- if(EC32(section_hdr[i].Characteristics) & 0x80000000) |
|
| 677 |
+ if(exe_sections[i].chr & 0x80000000) |
|
| 678 | 678 |
cli_dbgmsg("Section's memory is writeable\n");
|
| 679 | 679 |
|
| 680 | 680 |
cli_dbgmsg("------------------------------------\n");
|
| 681 | 681 |
|
| 682 |
- if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)%valign) { /* Bad virtual alignment */
|
|
| 682 |
+ if (DETECT_BROKEN && (exe_sections[i].urva % valign)) { /* Bad virtual alignment */
|
|
| 683 | 683 |
cli_dbgmsg("VirtualAddress is misaligned\n");
|
| 684 | 684 |
if(ctx->virname) |
| 685 | 685 |
*ctx->virname = "Broken.Executable"; |
| ... | ... |
@@ -730,7 +733,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 730 | 730 |
} |
| 731 | 731 |
|
| 732 | 732 |
if(!i) {
|
| 733 |
- if (DETECT_BROKEN && (pe_plus?EC16(optional_hdr64.Subsystem):EC16(optional_hdr32.Subsystem))!= 1 && EC32(section_hdr[i].VirtualAddress)!=valign) { /* Bad first section RVA */
|
|
| 733 |
+ if (DETECT_BROKEN && (pe_plus?EC16(optional_hdr64.Subsystem):EC16(optional_hdr32.Subsystem))!= 1 && exe_sections[i].urva!=valign) { /* Bad first section RVA */
|
|
| 734 | 734 |
cli_dbgmsg("First section is in the wrong place\n");
|
| 735 | 735 |
if(ctx->virname) |
| 736 | 736 |
*ctx->virname = "Broken.Executable"; |
| ... | ... |
@@ -741,7 +744,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 741 | 741 |
min = exe_sections[i].rva; |
| 742 | 742 |
max = exe_sections[i].rva + exe_sections[i].rsz; |
| 743 | 743 |
} else {
|
| 744 |
- if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)-EC32(section_hdr[i-1].VirtualAddress)!= exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
|
|
| 744 |
+ if (DETECT_BROKEN && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
|
|
| 745 | 745 |
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
|
| 746 | 746 |
if(ctx->virname) |
| 747 | 747 |
*ctx->virname = "Broken.Executable"; |
| ... | ... |
@@ -758,7 +761,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 758 | 758 |
|
| 759 | 759 |
if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !strlen(sname)) {
|
| 760 | 760 |
if(exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000) {
|
| 761 |
- if(EC32(section_hdr[i].Characteristics) == 0xe0000060) {
|
|
| 761 |
+ if(exe_sections[i].chr == 0xe0000060) {
|
|
| 762 | 762 |
polipos = i; |
| 763 | 763 |
} |
| 764 | 764 |
} |
| ... | ... |
@@ -766,9 +769,10 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 766 | 766 |
|
| 767 | 767 |
} |
| 768 | 768 |
|
| 769 |
+ free(section_hdr); |
|
| 770 |
+ |
|
| 769 | 771 |
if(!(ep = cli_rawaddr(vep, exe_sections, nsections, &err, fsize)) && err) {
|
| 770 | 772 |
cli_dbgmsg("EntryPoint out of file\n");
|
| 771 |
- free(section_hdr); |
|
| 772 | 773 |
free(exe_sections); |
| 773 | 774 |
if(DETECT_BROKEN) {
|
| 774 | 775 |
if(ctx->virname) |
| ... | ... |
@@ -781,22 +785,10 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 781 | 781 |
cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep);
|
| 782 | 782 |
|
| 783 | 783 |
if(pe_plus) { /* Do not continue for PE32+ files */
|
| 784 |
- free(section_hdr); |
|
| 785 | 784 |
free(exe_sections); |
| 786 | 785 |
return CL_CLEAN; |
| 787 | 786 |
} |
| 788 | 787 |
|
| 789 |
- magistr = (SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)); |
|
| 790 |
- |
|
| 791 |
- /* |
|
| 792 |
- - ENDPASS for section based heuristics - |
|
| 793 |
- |
|
| 794 |
- past this line section names and |
|
| 795 |
- characteristics are not availble |
|
| 796 |
- */ |
|
| 797 |
- free(section_hdr); |
|
| 798 |
- |
|
| 799 |
- |
|
| 800 | 788 |
|
| 801 | 789 |
/* Attempt to detect some popular polymorphic viruses */ |
| 802 | 790 |
|
| ... | ... |
@@ -880,7 +872,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 880 | 880 |
} |
| 881 | 881 |
|
| 882 | 882 |
/* W32.Magistr.A/B */ |
| 883 |
- if(magistr) {
|
|
| 883 |
+ if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) {
|
|
| 884 | 884 |
uint32_t rsize, vsize, dam = 0; |
| 885 | 885 |
|
| 886 | 886 |
vsize = exe_sections[nsections - 1].uvsz; |
| ... | ... |
@@ -1244,7 +1236,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
| 1244 | 1244 |
} |
| 1245 | 1245 |
} while (0); |
| 1246 | 1246 |
} |
| 1247 |
-HERE!!! |
|
| 1247 |
+ |
|
| 1248 | 1248 |
if(found || upack) {
|
| 1249 | 1249 |
/* Check EP for UPX vs. FSG vs. Upack */ |
| 1250 | 1250 |
if(lseek(desc, ep, SEEK_SET) == -1) {
|
| ... | ... |
@@ -1305,30 +1297,29 @@ HERE!!! |
| 1305 | 1305 |
) |
| 1306 | 1306 |
){
|
| 1307 | 1307 |
uint32_t vma, off; |
| 1308 |
- int a,b,c, file; |
|
| 1308 |
+ int a,b,c; |
|
| 1309 | 1309 |
|
| 1310 | 1310 |
cli_dbgmsg("Upack characteristics found.\n");
|
| 1311 |
- a = EC32(section_hdr[0].VirtualSize); |
|
| 1312 |
- b = EC32(section_hdr[1].VirtualSize); |
|
| 1311 |
+ a = exe_sections[0].vsz; |
|
| 1312 |
+ b = exe_sections[1].vsz; |
|
| 1313 | 1313 |
if (upack) {
|
| 1314 |
- cli_dbgmsg("upack var set\n");
|
|
| 1315 |
- c = EC32(section_hdr[2].VirtualSize); |
|
| 1316 |
- ssize = EC32(section_hdr[0].SizeOfRawData) + EC32(section_hdr[0].PointerToRawData); |
|
| 1317 |
- off = EC32(section_hdr[0].VirtualAddress); |
|
| 1318 |
- vma = EC32(optional_hdr32.ImageBase) + EC32(section_hdr[0].VirtualAddress); |
|
| 1314 |
+ cli_dbgmsg("Upack: var set\n");
|
|
| 1315 |
+ c = exe_sections[2].vsz; |
|
| 1316 |
+ ssize = exe_sections[0].ursz + exe_sections[0].uraw; |
|
| 1317 |
+ off = exe_sections[0].rva; |
|
| 1318 |
+ vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva; |
|
| 1319 | 1319 |
} else {
|
| 1320 |
- cli_dbgmsg("upack var NOT set\n");
|
|
| 1321 |
- c = EC32(section_hdr[1].VirtualAddress); |
|
| 1322 |
- ssize = EC32(section_hdr[1].PointerToRawData); |
|
| 1320 |
+ cli_dbgmsg("Upack: var NOT set\n");
|
|
| 1321 |
+ c = exe_sections[1].rva; |
|
| 1322 |
+ ssize = exe_sections[1].uraw; |
|
| 1323 | 1323 |
off = 0; |
| 1324 |
- vma = EC32(section_hdr[1].VirtualAddress) - EC32(section_hdr[1].PointerToRawData); |
|
| 1324 |
+ vma = exe_sections[1].rva - exe_sections[1].uraw; |
|
| 1325 | 1325 |
} |
| 1326 | 1326 |
|
| 1327 | 1327 |
dsize = a+b+c; |
| 1328 |
- if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || EC32(section_hdr[1].SizeOfRawData) > ctx->limits->maxfilesize)) |
|
| 1328 |
+ if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || exe_sections[1].ursz > ctx->limits->maxfilesize)) |
|
| 1329 | 1329 |
{
|
| 1330 | 1330 |
cli_dbgmsg("Upack: Sizes exceeded (a: %u, b: %u, c: %ux, max: %lu)\n", a, b, c, ctx->limits->maxfilesize);
|
| 1331 |
- free(section_hdr); |
|
| 1332 | 1331 |
free(exe_sections); |
| 1333 | 1332 |
if(BLOCKMAX) {
|
| 1334 | 1333 |
*ctx->virname = "PE.Upack.ExceededFileSize"; |
| ... | ... |
@@ -1338,90 +1329,80 @@ HERE!!! |
| 1338 | 1338 |
} |
| 1339 | 1339 |
} |
| 1340 | 1340 |
/* these are unsigned so if vaddr - off < 0, it should be ok */ |
| 1341 |
- 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 |
+ if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize) || ssize > dsize) |
|
| 1342 | 1342 |
{
|
| 1343 | 1343 |
cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
|
| 1344 |
- goto skip_upack_and_go_to_next_unpacker; /* I didn't want to add additional do while + break, can it be this way ? */ |
|
| 1344 |
+ goto skip_upack_and_go_to_next_unpacker; |
|
| 1345 | 1345 |
} |
| 1346 | 1346 |
|
| 1347 | 1347 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
|
| 1348 |
- free(section_hdr); |
|
| 1349 | 1348 |
free(exe_sections); |
| 1350 | 1349 |
return CL_EMEM; |
| 1351 | 1350 |
} |
| 1352 | 1351 |
src = NULL; |
| 1353 |
- cli_dbgmsg("Upack: min: %08x %08x max: %08x\n", dest, a+b+c, dest+a+b+c);
|
|
| 1354 | 1352 |
|
| 1355 | 1353 |
lseek(desc, 0, SEEK_SET); |
| 1356 |
- if(read(desc, dest, ssize) != ssize) { /* 2vGiM: i think this can be overflowed - should you check for ssize < dsize ?
|
|
| 1357 |
- * yup, I think you're right, added above |
|
| 1358 |
- */ |
|
| 1354 |
+ if(read(desc, dest, ssize) != ssize) {
|
|
| 1359 | 1355 |
cli_dbgmsg("Upack: Can't read raw data of section 0\n");
|
| 1360 |
- free(section_hdr); |
|
| 1361 | 1356 |
free(exe_sections); |
| 1362 | 1357 |
free(dest); |
| 1363 | 1358 |
return CL_EIO; |
| 1364 | 1359 |
} |
| 1365 | 1360 |
|
| 1366 | 1361 |
if (upack) |
| 1367 |
- memmove(dest + EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress), dest, ssize); |
|
| 1362 |
+ memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize); |
|
| 1368 | 1363 |
|
| 1369 |
- lseek(desc, EC32(section_hdr[1].PointerToRawData), SEEK_SET); |
|
| 1364 |
+ lseek(desc, exe_sections[1].uraw, SEEK_SET); |
|
| 1370 | 1365 |
|
| 1371 |
- if(read(desc, dest+EC32(section_hdr[1].VirtualAddress) - off, EC32(section_hdr[1].SizeOfRawData)) != EC32(section_hdr[1].SizeOfRawData)) {
|
|
| 1366 |
+ if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].uraw) != exe_sections[1].uraw) {
|
|
| 1372 | 1367 |
cli_dbgmsg("Upack: Can't read raw data of section 1\n");
|
| 1373 |
- free(section_hdr); |
|
| 1374 | 1368 |
free(exe_sections); |
| 1375 | 1369 |
free(dest); |
| 1376 | 1370 |
return CL_EIO; |
| 1377 | 1371 |
} |
| 1378 | 1372 |
|
| 1379 | 1373 |
if(!(tempfile = cli_gentemp(NULL))) {
|
| 1380 |
- free(section_hdr); |
|
| 1381 | 1374 |
free(exe_sections); |
| 1382 | 1375 |
free(dest); |
| 1383 | 1376 |
return CL_EMEM; |
| 1384 | 1377 |
} |
| 1385 | 1378 |
|
| 1386 |
- if((file = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
|
|
| 1379 |
+ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
|
|
| 1387 | 1380 |
cli_dbgmsg("Upack: Can't create file %s\n", tempfile);
|
| 1388 | 1381 |
free(tempfile); |
| 1389 |
- free(section_hdr); |
|
| 1390 | 1382 |
free(exe_sections); |
| 1391 | 1383 |
free(dest); |
| 1392 | 1384 |
return CL_EIO; |
| 1393 | 1385 |
} |
| 1394 | 1386 |
|
| 1395 |
- switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), EC32(section_hdr[0].VirtualAddress), file)) |
|
| 1387 |
+ switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)) |
|
| 1396 | 1388 |
{
|
| 1397 | 1389 |
case 1: /* Everything OK */ |
| 1398 | 1390 |
cli_dbgmsg("Upack: Unpacked and rebuilt executable saved in %s\n", tempfile);
|
| 1399 | 1391 |
free(dest); |
| 1400 |
- fsync(file); |
|
| 1401 |
- lseek(file, 0, SEEK_SET); |
|
| 1392 |
+ fsync(ndesc); |
|
| 1393 |
+ lseek(ndesc, 0, SEEK_SET); |
|
| 1402 | 1394 |
|
| 1403 | 1395 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
|
| 1404 |
- if(cli_magic_scandesc(file, ctx) == CL_VIRUS) {
|
|
| 1405 |
- free(section_hdr); |
|
| 1396 |
+ if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
|
|
| 1406 | 1397 |
free(exe_sections); |
| 1407 |
- close(file); |
|
| 1398 |
+ close(ndesc); |
|
| 1408 | 1399 |
if(!cli_leavetemps_flag) |
| 1409 | 1400 |
unlink(tempfile); |
| 1410 | 1401 |
free(tempfile); |
| 1411 | 1402 |
return CL_VIRUS; |
| 1412 | 1403 |
} |
| 1413 | 1404 |
|
| 1414 |
- close(file); |
|
| 1405 |
+ close(ndesc); |
|
| 1415 | 1406 |
if(!cli_leavetemps_flag) |
| 1416 | 1407 |
unlink(tempfile); |
| 1417 | 1408 |
free(tempfile); |
| 1418 |
- free(section_hdr); |
|
| 1419 | 1409 |
free(exe_sections); |
| 1420 | 1410 |
return CL_CLEAN; |
| 1421 | 1411 |
|
| 1422 | 1412 |
default: /* Everything gone wrong */ |
| 1423 | 1413 |
cli_dbgmsg("Upack: Unpacking failed\n");
|
| 1424 |
- close(file); |
|
| 1414 |
+ close(ndesc); |
|
| 1425 | 1415 |
unlink(tempfile); /* It's empty anyway */ |
| 1426 | 1416 |
free(tempfile); |
| 1427 | 1417 |
free(dest); |
| ... | ... |
@@ -1429,7 +1410,7 @@ HERE!!! |
| 1429 | 1429 |
} |
| 1430 | 1430 |
} |
| 1431 | 1431 |
skip_upack_and_go_to_next_unpacker: |
| 1432 |
- |
|
| 1432 |
+HERE!!! |
|
| 1433 | 1433 |
if((DCONF & PE_CONF_FSG) && buff[0] == '\x87' && buff[1] == '\x25') {
|
| 1434 | 1434 |
|
| 1435 | 1435 |
/* FSG v2.0 support - thanks to aCaB ! */ |