...
|
...
|
@@ -38,6 +38,7 @@
|
38
|
38
|
#include "cltypes.h"
|
39
|
39
|
#include "clamav.h"
|
40
|
40
|
#include "others.h"
|
|
41
|
+#include "fmap.h"
|
41
|
42
|
#include "pe.h"
|
42
|
43
|
#include "petite.h"
|
43
|
44
|
#include "fsg.h"
|
...
|
...
|
@@ -290,7 +291,7 @@ static off_t cli_seeksect(int fd, struct cli_exe_section *s) {
|
290
|
290
|
return ret+1;
|
291
|
291
|
}
|
292
|
292
|
|
293
|
|
-static unsigned int cli_md5sect(int fd, struct cli_exe_section *s, unsigned char *digest) {
|
|
293
|
+static unsigned int cli_md5sect(struct F_MAP *map, struct cli_exe_section *s, unsigned char *digest) {
|
294
|
294
|
void *hashme;
|
295
|
295
|
cli_md5_ctx md5;
|
296
|
296
|
|
...
|
...
|
@@ -299,28 +300,21 @@ static unsigned int cli_md5sect(int fd, struct cli_exe_section *s, unsigned char
|
299
|
299
|
return 0;
|
300
|
300
|
}
|
301
|
301
|
|
302
|
|
- if(!cli_seeksect(fd, s)) return 0;
|
303
|
|
-
|
304
|
|
- if(!(hashme=cli_malloc(s->rsz))) {
|
305
|
|
- cli_dbgmsg("cli_md5sect: out of memory\n");
|
306
|
|
- return 0;
|
307
|
|
- }
|
308
|
|
-
|
309
|
|
- if(cli_readn(fd, hashme, s->rsz)!=s->rsz) {
|
|
302
|
+ if(!s->rsz) return 0;
|
|
303
|
+ if(!(hashme=fmap_need_off_once(map, s->raw, s->rsz))) {
|
310
|
304
|
cli_dbgmsg("cli_md5sect: unable to read section data\n");
|
311
|
305
|
return 0;
|
312
|
306
|
}
|
313
|
307
|
|
314
|
308
|
cli_md5_init(&md5);
|
315
|
309
|
cli_md5_update(&md5, hashme, s->rsz);
|
316
|
|
- free(hashme);
|
317
|
310
|
cli_md5_final(digest, &md5);
|
318
|
311
|
return 1;
|
319
|
312
|
}
|
320
|
313
|
|
321
|
|
-static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct cli_exe_section *exe_sections, uint16_t nsections, size_t fsize, uint32_t hdr_size, unsigned int level, uint32_t type, unsigned int *maxres, struct swizz_stats *stats) {
|
|
314
|
+static void cli_parseres_special(uint32_t base, uint32_t rva, struct F_MAP *map, struct cli_exe_section *exe_sections, uint16_t nsections, size_t fsize, uint32_t hdr_size, unsigned int level, uint32_t type, unsigned int *maxres, struct swizz_stats *stats) {
|
322
|
315
|
unsigned int err = 0, i;
|
323
|
|
- uint8_t resdir[16];
|
|
316
|
+ uint8_t *resdir;
|
324
|
317
|
uint8_t *entry, *oentry;
|
325
|
318
|
uint16_t named, unnamed;
|
326
|
319
|
uint32_t rawaddr = cli_rawaddr(rva, exe_sections, nsections, &err, fsize, hdr_size);
|
...
|
...
|
@@ -328,7 +322,7 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
|
328
|
328
|
|
329
|
329
|
if(level>2 || !*maxres) return;
|
330
|
330
|
*maxres-=1;
|
331
|
|
- if(err || (pread(srcfd,resdir, sizeof(resdir), rawaddr) != sizeof(resdir)))
|
|
331
|
+ if(err || !(resdir = fmap_need_off_once(map, rawaddr, 16)))
|
332
|
332
|
return;
|
333
|
333
|
named = (uint16_t)cli_readint16(resdir+12);
|
334
|
334
|
unnamed = (uint16_t)cli_readint16(resdir+14);
|
...
|
...
|
@@ -336,18 +330,17 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
|
336
|
336
|
entries = /*named+*/unnamed;
|
337
|
337
|
if (!entries)
|
338
|
338
|
return;
|
339
|
|
- oentry = entry = cli_malloc(entries*8);
|
340
|
339
|
rawaddr += named*8; /* skip named */
|
341
|
340
|
/* this is just used in a heuristic detection, so don't give error on failure */
|
342
|
341
|
if (!entry) {
|
343
|
342
|
cli_dbgmsg("cli_parseres_special: failed to allocate memory for resource directory:%lu\n", (unsigned long)entries);
|
344
|
343
|
return;
|
345
|
344
|
}
|
346
|
|
- if (pread(srcfd, entry, entries*8, rawaddr+16) != entries*8) {
|
|
345
|
+ if(!(entry = fmap_need_off(map, rawaddr+16, entries*8))) {
|
347
|
346
|
cli_dbgmsg("cli_parseres_special: failed to read resource directory at:%lu\n", (unsigned long)rawaddr+16);
|
348
|
|
- free(oentry);
|
349
|
347
|
return;
|
350
|
348
|
}
|
|
349
|
+ oentry = entry;
|
351
|
350
|
/*for (i=0; i<named; i++) {
|
352
|
351
|
uint32_t id, offs;
|
353
|
352
|
id = cli_readint32(entry);
|
...
|
...
|
@@ -389,13 +382,13 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
|
389
|
389
|
}
|
390
|
390
|
offs = cli_readint32(entry+4);
|
391
|
391
|
if(offs>>31)
|
392
|
|
- cli_parseres_special(base, base + (offs&0x7fffffff), srcfd, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats);
|
|
392
|
+ cli_parseres_special(base, base + (offs&0x7fffffff), map, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats);
|
393
|
393
|
else {
|
394
|
394
|
offs = cli_readint32(entry+4);
|
395
|
395
|
rawaddr = cli_rawaddr(base + offs, exe_sections, nsections, &err, fsize, hdr_size);
|
396
|
|
- if (!err && pread(srcfd, resdir, sizeof(resdir), rawaddr) == sizeof(resdir)) {
|
|
396
|
+ if (!err && (resdir = fmap_need_off_once(map, rawaddr, 16))) {
|
397
|
397
|
uint32_t isz = cli_readint32(resdir+4);
|
398
|
|
- char *str;
|
|
398
|
+ uint8_t *str;
|
399
|
399
|
rawaddr = cli_rawaddr(cli_readint32(resdir), exe_sections, nsections, &err, fsize, hdr_size);
|
400
|
400
|
if (err || !isz || isz >= fsize || rawaddr+isz >= fsize) {
|
401
|
401
|
cli_dbgmsg("cli_parseres_special: invalid resource table entry: %lu + %lu\n",
|
...
|
...
|
@@ -404,22 +397,15 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
|
404
|
404
|
stats->errors++;
|
405
|
405
|
continue;
|
406
|
406
|
}
|
407
|
|
- str = cli_malloc(isz);
|
408
|
|
- if (!str) {
|
409
|
|
- cli_dbgmsg("cli_parseres_special: failed to allocate string mem: %lu\n", (unsigned long)isz);
|
410
|
|
- continue;
|
411
|
|
- }
|
412
|
|
- if(pread(srcfd, str, isz, rawaddr) == isz) {
|
|
407
|
+ if((str = fmap_need_off_once(map, rawaddr, isz)))
|
413
|
408
|
cli_detect_swizz_str(str, isz, stats, type);
|
414
|
|
- }
|
415
|
|
- free (str);
|
416
|
409
|
}
|
417
|
410
|
}
|
418
|
411
|
}
|
419
|
|
- free (oentry);
|
|
412
|
+ fmap_unneed_ptr(map, oentry, entries*8);
|
420
|
413
|
}
|
421
|
414
|
|
422
|
|
-int cli_scanpe(int desc, cli_ctx *ctx)
|
|
415
|
+int cli_scanpe(cli_ctx *ctx)
|
423
|
416
|
{
|
424
|
417
|
uint16_t e_magic; /* DOS signature ("MZ") */
|
425
|
418
|
uint16_t nsections;
|
...
|
...
|
@@ -433,10 +419,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
433
|
433
|
struct pe_image_optional_hdr32 opt32;
|
434
|
434
|
} pe_opt;
|
435
|
435
|
struct pe_image_section_hdr *section_hdr;
|
436
|
|
- struct stat sb;
|
437
|
|
- char sname[9], buff[4096], epbuff[4096], *tempfile;
|
|
436
|
+ char sname[9], epbuff[4096], *tempfile;
|
438
|
437
|
uint32_t epsize;
|
439
|
|
- ssize_t bytes;
|
|
438
|
+ ssize_t bytes, at;
|
440
|
439
|
unsigned int i, found, upx_success = 0, min = 0, max = 0, err, overlays = 0;
|
441
|
440
|
unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0;
|
442
|
441
|
int (*upxfn)(char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL;
|
...
|
...
|
@@ -448,6 +433,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
448
|
448
|
struct cli_matcher *md5_sect;
|
449
|
449
|
char timestr[32];
|
450
|
450
|
struct pe_image_data_dir *dirs;
|
|
451
|
+ struct F_MAP *map;
|
451
|
452
|
|
452
|
453
|
|
453
|
454
|
if(!ctx) {
|
...
|
...
|
@@ -455,7 +441,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
455
|
455
|
return CL_ENULLARG;
|
456
|
456
|
}
|
457
|
457
|
|
458
|
|
- if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
|
|
458
|
+ map = *ctx->fmap;
|
|
459
|
+ if(fmap_readn(map, &e_magic, 0, sizeof(e_magic)) != sizeof(e_magic)) {
|
459
|
460
|
cli_dbgmsg("Can't read DOS signature\n");
|
460
|
461
|
return CL_CLEAN;
|
461
|
462
|
}
|
...
|
...
|
@@ -465,15 +452,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
465
|
465
|
return CL_CLEAN;
|
466
|
466
|
}
|
467
|
467
|
|
468
|
|
- lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
|
469
|
|
-
|
470
|
|
- if(cli_readn(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
|
|
468
|
+ if(fmap_readn(map, &e_lfanew, 58 + sizeof(e_magic), sizeof(e_lfanew)) != sizeof(e_lfanew)) {
|
471
|
469
|
cli_dbgmsg("Can't read new header address\n");
|
472
|
470
|
/* truncated header? */
|
473
|
471
|
if(DETECT_BROKEN) {
|
474
|
472
|
if(ctx->virname)
|
475
|
473
|
*ctx->virname = "Broken.Executable";
|
476
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
474
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
477
|
475
|
}
|
478
|
476
|
return CL_CLEAN;
|
479
|
477
|
}
|
...
|
...
|
@@ -485,13 +470,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
485
|
485
|
return CL_CLEAN;
|
486
|
486
|
}
|
487
|
487
|
|
488
|
|
- if(lseek(desc, e_lfanew, SEEK_SET) < 0) {
|
489
|
|
- /* probably not a PE file */
|
490
|
|
- cli_dbgmsg("Can't lseek to e_lfanew\n");
|
491
|
|
- return CL_CLEAN;
|
492
|
|
- }
|
493
|
|
-
|
494
|
|
- if(cli_readn(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
|
|
488
|
+ if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
|
495
|
489
|
/* bad information in e_lfanew - probably not a PE file */
|
496
|
490
|
cli_dbgmsg("Can't read file header\n");
|
497
|
491
|
return CL_CLEAN;
|
...
|
...
|
@@ -609,7 +588,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
609
|
609
|
if(DETECT_BROKEN) {
|
610
|
610
|
if(ctx->virname)
|
611
|
611
|
*ctx->virname = "Broken.Executable";
|
612
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
612
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
613
|
613
|
}
|
614
|
614
|
if(nsections)
|
615
|
615
|
cli_warnmsg("PE file contains %d sections\n", nsections);
|
...
|
...
|
@@ -629,20 +608,22 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
629
|
629
|
if(DETECT_BROKEN) {
|
630
|
630
|
if(ctx->virname)
|
631
|
631
|
*ctx->virname = "Broken.Executable";
|
632
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
632
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
633
|
633
|
}
|
634
|
634
|
return CL_CLEAN;
|
635
|
635
|
}
|
636
|
636
|
|
637
|
|
- if(cli_readn(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
|
|
637
|
+ at = e_lfanew + sizeof(struct pe_image_file_hdr);
|
|
638
|
+ if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
|
638
|
639
|
cli_dbgmsg("Can't read optional file header\n");
|
639
|
640
|
if(DETECT_BROKEN) {
|
640
|
641
|
if(ctx->virname)
|
641
|
642
|
*ctx->virname = "Broken.Executable";
|
642
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
643
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
643
|
644
|
}
|
644
|
645
|
return CL_CLEAN;
|
645
|
646
|
}
|
|
647
|
+ at += sizeof(struct pe_image_optional_hdr32);
|
646
|
648
|
|
647
|
649
|
/* This will be a chicken and egg problem until we drop 9x */
|
648
|
650
|
if(EC16(optional_hdr64.Magic)==PE32P_SIGNATURE) {
|
...
|
...
|
@@ -652,7 +633,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
652
|
652
|
if(DETECT_BROKEN) {
|
653
|
653
|
if(ctx->virname)
|
654
|
654
|
*ctx->virname = "Broken.Executable";
|
655
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
655
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
656
|
656
|
}
|
657
|
657
|
return CL_CLEAN;
|
658
|
658
|
}
|
...
|
...
|
@@ -668,7 +649,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
668
|
668
|
if(DETECT_BROKEN) {
|
669
|
669
|
if(ctx->virname)
|
670
|
670
|
*ctx->virname = "Broken.Executable";
|
671
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
671
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
672
|
672
|
}
|
673
|
673
|
cli_dbgmsg("9x compatibility mode\n");
|
674
|
674
|
}
|
...
|
...
|
@@ -677,7 +658,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
677
|
677
|
if(!pe_plus) { /* PE */
|
678
|
678
|
if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
|
679
|
679
|
/* Seek to the end of the long header */
|
680
|
|
- lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR);
|
|
680
|
+ at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
|
681
|
681
|
}
|
682
|
682
|
|
683
|
683
|
if(DCONF & PE_CONF_UPACK)
|
...
|
...
|
@@ -705,16 +686,16 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
705
|
705
|
|
706
|
706
|
} else { /* PE+ */
|
707
|
707
|
/* read the remaining part of the header */
|
708
|
|
- if(cli_readn(desc, &optional_hdr32 + 1, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
|
|
708
|
+ if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
|
709
|
709
|
cli_dbgmsg("Can't read optional file header\n");
|
710
|
710
|
if(DETECT_BROKEN) {
|
711
|
711
|
if(ctx->virname)
|
712
|
712
|
*ctx->virname = "Broken.Executable";
|
713
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
713
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
714
|
714
|
}
|
715
|
715
|
return CL_CLEAN;
|
716
|
716
|
}
|
717
|
|
-
|
|
717
|
+ at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
|
718
|
718
|
vep = EC32(optional_hdr64.AddressOfEntryPoint);
|
719
|
719
|
hdr_size = EC32(optional_hdr64.SizeOfHeaders);
|
720
|
720
|
cli_dbgmsg("File format: PE32+\n");
|
...
|
...
|
@@ -791,22 +772,17 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
791
|
791
|
cli_dbgmsg("Bad virtual alignemnt\n");
|
792
|
792
|
if(ctx->virname)
|
793
|
793
|
*ctx->virname = "Broken.Executable";
|
794
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
794
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
795
|
795
|
}
|
796
|
796
|
|
797
|
797
|
if (DETECT_BROKEN && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
|
798
|
798
|
cli_dbgmsg("Bad file alignemnt\n");
|
799
|
799
|
if(ctx->virname)
|
800
|
800
|
*ctx->virname = "Broken.Executable";
|
801
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
801
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
802
|
802
|
}
|
803
|
803
|
|
804
|
|
- if(fstat(desc, &sb) == -1) {
|
805
|
|
- cli_dbgmsg("fstat failed\n");
|
806
|
|
- return CL_ESTAT;
|
807
|
|
- }
|
808
|
|
-
|
809
|
|
- fsize = sb.st_size;
|
|
804
|
+ fsize = map->len;
|
810
|
805
|
|
811
|
806
|
section_hdr = (struct pe_image_section_hdr *) cli_calloc(nsections, sizeof(struct pe_image_section_hdr));
|
812
|
807
|
|
...
|
...
|
@@ -826,7 +802,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
826
|
826
|
valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
|
827
|
827
|
falign = (pe_plus)?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment);
|
828
|
828
|
|
829
|
|
- if(cli_readn(desc, section_hdr, sizeof(struct pe_image_section_hdr)*nsections) != (int)(nsections*sizeof(struct pe_image_section_hdr))) {
|
|
829
|
+ if(fmap_readn(map, section_hdr, at, sizeof(struct pe_image_section_hdr)*nsections) != (int)(nsections*sizeof(struct pe_image_section_hdr))) {
|
830
|
830
|
cli_dbgmsg("Can't read section header\n");
|
831
|
831
|
cli_dbgmsg("Possibly broken PE file\n");
|
832
|
832
|
free(section_hdr);
|
...
|
...
|
@@ -834,11 +810,12 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
834
|
834
|
if(DETECT_BROKEN) {
|
835
|
835
|
if(ctx->virname)
|
836
|
836
|
*ctx->virname = "Broken.Executable";
|
837
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
837
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
838
|
838
|
}
|
839
|
839
|
return CL_CLEAN;
|
840
|
840
|
}
|
841
|
|
-
|
|
841
|
+ at += sizeof(struct pe_image_section_hdr)*nsections;
|
|
842
|
+
|
842
|
843
|
for(i = 0; falign!=0x200 && i<nsections; i++) {
|
843
|
844
|
/* file alignment fallback mode - blah */
|
844
|
845
|
if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
|
...
|
...
|
@@ -903,7 +880,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
903
|
903
|
*ctx->virname = "Broken.Executable";
|
904
|
904
|
free(section_hdr);
|
905
|
905
|
free(exe_sections);
|
906
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
906
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
907
|
907
|
}
|
908
|
908
|
|
909
|
909
|
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
|
...
|
...
|
@@ -914,7 +891,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
914
|
914
|
if(DETECT_BROKEN) {
|
915
|
915
|
if(ctx->virname)
|
916
|
916
|
*ctx->virname = "Broken.Executable";
|
917
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
917
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
918
|
918
|
}
|
919
|
919
|
return CL_CLEAN; /* no ninjas to see here! move along! */
|
920
|
920
|
}
|
...
|
...
|
@@ -928,12 +905,12 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
928
|
928
|
for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) {
|
929
|
929
|
if(md5_sect->soff[j] == exe_sections[i].rsz) {
|
930
|
930
|
unsigned char md5_dig[16];
|
931
|
|
- if(cli_md5sect(desc, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_mdb, 0, -1) == CL_VIRUS) {
|
|
931
|
+ if(cli_md5sect(map, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_mdb, 0, -1) == CL_VIRUS) {
|
932
|
932
|
if(cli_bm_scanbuff(md5_dig, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS) {
|
933
|
933
|
|
934
|
934
|
free(section_hdr);
|
935
|
935
|
free(exe_sections);
|
936
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
936
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
937
|
937
|
}
|
938
|
938
|
}
|
939
|
939
|
break;
|
...
|
...
|
@@ -949,7 +926,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
949
|
949
|
if(DETECT_BROKEN) {
|
950
|
950
|
if(ctx->virname)
|
951
|
951
|
*ctx->virname = "Broken.Executable";
|
952
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
952
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
953
|
953
|
}
|
954
|
954
|
return CL_CLEAN;
|
955
|
955
|
}
|
...
|
...
|
@@ -961,7 +938,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
961
|
961
|
*ctx->virname = "Broken.Executable";
|
962
|
962
|
free(section_hdr);
|
963
|
963
|
free(exe_sections);
|
964
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
964
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
965
|
965
|
}
|
966
|
966
|
min = exe_sections[i].rva;
|
967
|
967
|
max = exe_sections[i].rva + exe_sections[i].rsz;
|
...
|
...
|
@@ -972,7 +949,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
972
|
972
|
*ctx->virname = "Broken.Executable";
|
973
|
973
|
free(section_hdr);
|
974
|
974
|
free(exe_sections);
|
975
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
975
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
976
|
976
|
}
|
977
|
977
|
if(exe_sections[i].rva < min)
|
978
|
978
|
min = exe_sections[i].rva;
|
...
|
...
|
@@ -992,7 +969,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
992
|
992
|
if(DETECT_BROKEN) {
|
993
|
993
|
if(ctx->virname)
|
994
|
994
|
*ctx->virname = "Broken.Executable";
|
995
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
995
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
996
|
996
|
}
|
997
|
997
|
return CL_CLEAN;
|
998
|
998
|
}
|
...
|
...
|
@@ -1004,8 +981,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1004
|
1004
|
return CL_CLEAN;
|
1005
|
1005
|
}
|
1006
|
1006
|
|
1007
|
|
- lseek(desc, ep, SEEK_SET);
|
1008
|
|
- epsize = cli_readn(desc, epbuff, 4096);
|
|
1007
|
+ epsize = fmap_readn(map, epbuff, ep, 4096);
|
1009
|
1008
|
|
1010
|
1009
|
CLI_UNPTEMP("DISASM",(exe_sections,0));
|
1011
|
1010
|
disasmbuf((unsigned char*)epbuff, epsize, ndesc);
|
...
|
...
|
@@ -1022,7 +998,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1022
|
1022
|
if(overlays) {
|
1023
|
1023
|
int overlays_sz = fsize - overlays;
|
1024
|
1024
|
if(overlays_sz > 0) {
|
1025
|
|
- ret = cli_scanishield(desc, ctx, overlays, overlays_sz);
|
|
1025
|
+ ret = cli_scanishield(map->fd, ctx, overlays, overlays_sz);
|
1026
|
1026
|
if(ret != CL_CLEAN) {
|
1027
|
1027
|
free(exe_sections);
|
1028
|
1028
|
return ret;
|
...
|
...
|
@@ -1040,7 +1016,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1040
|
1040
|
if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
|
1041
|
1041
|
*ctx->virname = "W32.Parite.B";
|
1042
|
1042
|
free(exe_sections);
|
1043
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1043
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1044
|
1044
|
}
|
1045
|
1045
|
}
|
1046
|
1046
|
}
|
...
|
...
|
@@ -1123,7 +1099,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1123
|
1123
|
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
|
1124
|
1124
|
*ctx->virname = "W32.Kriz";
|
1125
|
1125
|
free(exe_sections);
|
1126
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1126
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1127
|
1127
|
}
|
1128
|
1128
|
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
|
1129
|
1129
|
kzstate++;
|
...
|
...
|
@@ -1144,25 +1120,25 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1144
|
1144
|
|
1145
|
1145
|
if(vsize >= 0x612c && rsize >= 0x612c && ((vsize & 0xff) == 0xec)) {
|
1146
|
1146
|
int bw = rsize < 0x7000 ? rsize : 0x7000;
|
|
1147
|
+ char *tbuff;
|
1147
|
1148
|
|
1148
|
|
- lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET);
|
1149
|
|
- if(cli_readn(desc, buff, 4096) == 4096) {
|
1150
|
|
- if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
|
|
1149
|
+ if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
|
|
1150
|
+ if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
|
1151
|
1151
|
*ctx->virname = dam ? "W32.Magistr.A.dam" : "W32.Magistr.A";
|
1152
|
1152
|
free(exe_sections);
|
1153
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1153
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1154
|
1154
|
}
|
1155
|
1155
|
}
|
1156
|
1156
|
|
1157
|
1157
|
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
|
1158
|
1158
|
int bw = rsize < 0x8000 ? rsize : 0x8000;
|
|
1159
|
+ char *tbuff;
|
1159
|
1160
|
|
1160
|
|
- lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET);
|
1161
|
|
- if(cli_readn(desc, buff, 4096) == 4096) {
|
1162
|
|
- if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
|
|
1161
|
+ if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
|
|
1162
|
+ if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
|
1163
|
1163
|
*ctx->virname = dam ? "W32.Magistr.B.dam" : "W32.Magistr.B";
|
1164
|
1164
|
free(exe_sections);
|
1165
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1165
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1166
|
1166
|
}
|
1167
|
1167
|
}
|
1168
|
1168
|
}
|
...
|
...
|
@@ -1175,15 +1151,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1175
|
1175
|
unsigned int xsjs = 0;
|
1176
|
1176
|
|
1177
|
1177
|
if(exe_sections[0].rsz > CLI_MAX_ALLOCATION) break;
|
1178
|
|
- if(!cli_seeksect(desc, &exe_sections[0])) break;
|
1179
|
|
- if(!(code=cli_malloc(exe_sections[0].rsz))) {
|
1180
|
|
- free(exe_sections);
|
1181
|
|
- return CL_EMEM;
|
1182
|
|
- }
|
1183
|
|
- if(cli_readn(desc, code, exe_sections[0].rsz)!=exe_sections[0].rsz) {
|
1184
|
|
- free(exe_sections);
|
1185
|
|
- return CL_EREAD;
|
1186
|
|
- }
|
|
1178
|
+
|
|
1179
|
+ if(!exe_sections[0].rsz) break;
|
|
1180
|
+ if(!(code=fmap_need_off_once(map, exe_sections[0].raw, exe_sections[0].rsz))) break;
|
1187
|
1181
|
for(i=0; i<exe_sections[0].rsz - 5; i++) {
|
1188
|
1182
|
if((uint8_t)(code[i]-0xe8) > 1) continue;
|
1189
|
1183
|
jump = cli_rawaddr(exe_sections[0].rva+i+5+cli_readint32(&code[i+1]), exe_sections, nsections, &err, fsize, hdr_size);
|
...
|
...
|
@@ -1191,7 +1161,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1191
|
1191
|
if(xsjs % 128 == 0) {
|
1192
|
1192
|
if(xsjs == 1280) break;
|
1193
|
1193
|
if(!(jumps=(uint32_t *)cli_realloc2(jumps, (xsjs+128)*sizeof(uint32_t)))) {
|
1194
|
|
- free(code);
|
1195
|
1194
|
free(exe_sections);
|
1196
|
1195
|
return CL_EMEM;
|
1197
|
1196
|
}
|
...
|
...
|
@@ -1210,17 +1179,15 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1210
|
1210
|
jumps[j]=jump;
|
1211
|
1211
|
xsjs++;
|
1212
|
1212
|
}
|
1213
|
|
- free(code);
|
1214
|
1213
|
if(!xsjs) break;
|
1215
|
1214
|
cli_dbgmsg("Polipos: Checking %d xsect jump(s)\n", xsjs);
|
1216
|
1215
|
for(i=0;i<xsjs;i++) {
|
1217
|
|
- lseek(desc, jumps[i], SEEK_SET);
|
1218
|
|
- if(cli_readn(desc, buff, 9) != 9) continue;
|
1219
|
|
- if((jump=cli_readint32(buff))==0x60ec8b55 || (buff[4]=='\xec' && ((jump==0x83ec8b55 && buff[6]=='\x60') || (jump==0x81ec8b55 && !buff[7] && !buff[8])))) {
|
|
1216
|
+ if(!(code = fmap_need_off_once(map, jumps[i], 9))) continue;
|
|
1217
|
+ if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]=='\xec' && ((jump==0x83ec8b55 && code[6]=='\x60') || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
|
1220
|
1218
|
*ctx->virname = "W32.Polipos.A";
|
1221
|
1219
|
free(jumps);
|
1222
|
1220
|
free(exe_sections);
|
1223
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1221
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1224
|
1222
|
}
|
1225
|
1223
|
}
|
1226
|
1224
|
free(jumps);
|
...
|
...
|
@@ -1237,7 +1204,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1237
|
1237
|
if (!stats)
|
1238
|
1238
|
ret = CL_EMEM;
|
1239
|
1239
|
else {
|
1240
|
|
- cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), desc, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
|
|
1240
|
+ cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
|
1241
|
1241
|
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
|
1242
|
1242
|
*ctx->virname = "Trojan.Swizzor.Gen";
|
1243
|
1243
|
}
|
...
|
...
|
@@ -1246,7 +1213,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1246
|
1246
|
if (ret != CL_CLEAN) {
|
1247
|
1247
|
free(exe_sections);
|
1248
|
1248
|
if(ret == CL_VIRUS)
|
1249
|
|
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
|
|
1249
|
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
|
1250
|
1250
|
return ret;
|
1251
|
1251
|
}
|
1252
|
1252
|
}
|
...
|
...
|
@@ -1269,6 +1236,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1269
|
1269
|
/* MEW support */
|
1270
|
1270
|
if (found && (DCONF & PE_CONF_MEW) && epsize>=16 && epbuff[0]=='\xe9') {
|
1271
|
1271
|
uint32_t fileoffset;
|
|
1272
|
+ char *tbuff;
|
1272
|
1273
|
|
1273
|
1274
|
fileoffset = (vep + cli_readint32(epbuff + 1) + 5);
|
1274
|
1275
|
while (fileoffset == 0x154 || fileoffset == 0x158) {
|
...
|
...
|
@@ -1277,29 +1245,20 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1277
|
1277
|
cli_dbgmsg ("MEW: found MEW characteristics %08X + %08X + 5 = %08X\n",
|
1278
|
1278
|
cli_readint32(epbuff + 1), vep, cli_readint32(epbuff + 1) + vep + 5);
|
1279
|
1279
|
|
1280
|
|
- if(lseek(desc, fileoffset, SEEK_SET) == -1) {
|
1281
|
|
- cli_dbgmsg("MEW: lseek() failed\n");
|
1282
|
|
- free(exe_sections);
|
1283
|
|
- return CL_ESEEK;
|
1284
|
|
- }
|
1285
|
|
-
|
1286
|
|
- if((bytes = read(desc, buff, 0xb0)) != 0xb0) {
|
1287
|
|
- cli_dbgmsg("MEW: Can't read 0xb0 bytes at 0x%x (%d) %lu\n", fileoffset, fileoffset, (unsigned long)bytes);
|
|
1280
|
+ if(!(tbuff = fmap_need_off_once(map, fileoffset, 0xb0)))
|
1288
|
1281
|
break;
|
1289
|
|
- }
|
1290
|
|
-
|
1291
|
1282
|
if (fileoffset == 0x154) cli_dbgmsg("MEW: Win9x compatibility was set!\n");
|
1292
|
1283
|
else cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
|
1293
|
1284
|
|
1294
|
|
- if((offdiff = cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
|
|
1285
|
+ if((offdiff = cli_readint32(tbuff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
|
1295
|
1286
|
cli_dbgmsg("MEW: ESI is not in proper section\n");
|
1296
|
1287
|
break;
|
1297
|
1288
|
}
|
1298
|
1289
|
offdiff -= exe_sections[i + 1].rva;
|
1299
|
1290
|
|
1300
|
|
- if(!cli_seeksect(desc, &exe_sections[i + 1])) {
|
1301
|
|
- free(exe_sections);
|
1302
|
|
- return CL_ESEEK;
|
|
1291
|
+ if(!exe_sections[i + 1].rsz) {
|
|
1292
|
+ cli_dbgmsg("MEW: mew section is empty\n");
|
|
1293
|
+ break;
|
1303
|
1294
|
}
|
1304
|
1295
|
ssize = exe_sections[i + 1].vsz;
|
1305
|
1296
|
dsize = exe_sections[i].vsz;
|
...
|
...
|
@@ -1309,20 +1268,19 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1309
|
1309
|
CLI_UNPSIZELIMITS("MEW", MAX(ssize, dsize));
|
1310
|
1310
|
CLI_UNPSIZELIMITS("MEW", MAX(ssize + dsize, exe_sections[i + 1].rsz));
|
1311
|
1311
|
|
|
1312
|
+ if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
|
|
1313
|
+ cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
|
|
1314
|
+ break;
|
|
1315
|
+ }
|
|
1316
|
+
|
1312
|
1317
|
/* allocate needed buffer */
|
1313
|
1318
|
if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
|
1314
|
1319
|
free(exe_sections);
|
1315
|
1320
|
return CL_EMEM;
|
1316
|
1321
|
}
|
1317
|
1322
|
|
1318
|
|
- if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
|
1319
|
|
- cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
|
1320
|
|
- free(src);
|
1321
|
|
- break;
|
1322
|
|
- }
|
1323
|
|
-
|
1324
|
|
- if((bytes = read(desc, src + dsize, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
|
1325
|
|
- cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
|
|
1323
|
+ if((bytes = fmap_readn(map, src + dsize, exe_sections[i + 1].raw, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
|
|
1324
|
+ cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
|
1326
|
1325
|
free(exe_sections);
|
1327
|
1326
|
free(src);
|
1328
|
1327
|
return CL_EREAD;
|
...
|
...
|
@@ -1330,13 +1288,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1330
|
1330
|
cli_dbgmsg("MEW: %u (%08x) bytes read\n", (unsigned int)bytes, (unsigned int)bytes);
|
1331
|
1331
|
|
1332
|
1332
|
/* count offset to lzma proc, if lzma used, 0xe8 -> call */
|
1333
|
|
- if (buff[0x7b] == '\xe8') {
|
1334
|
|
- if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(buff + 0x7c) + fileoffset + 0x80, 4)) {
|
|
1333
|
+ if (tbuff[0x7b] == '\xe8') {
|
|
1334
|
+ if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(tbuff + 0x7c) + fileoffset + 0x80, 4)) {
|
1335
|
1335
|
cli_dbgmsg("MEW: lzma proc out of bounds!\n");
|
1336
|
1336
|
free(src);
|
1337
|
1337
|
break; /* to next unpacker in chain */
|
1338
|
1338
|
}
|
1339
|
|
- uselzma = cli_readint32(buff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
|
|
1339
|
+ uselzma = cli_readint32(tbuff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
|
1340
|
1340
|
} else {
|
1341
|
1341
|
uselzma = 0;
|
1342
|
1342
|
}
|
...
|
...
|
@@ -1433,8 +1391,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1433
|
1433
|
return CL_EMEM;
|
1434
|
1434
|
}
|
1435
|
1435
|
|
1436
|
|
- lseek(desc, 0, SEEK_SET);
|
1437
|
|
- if(read(desc, dest, ssize) != ssize) {
|
|
1436
|
+ if(fmap_readn(map, dest, 0, ssize) != ssize) {
|
1438
|
1437
|
cli_dbgmsg("Upack: Can't read raw data of section 0\n");
|
1439
|
1438
|
free(dest);
|
1440
|
1439
|
break;
|
...
|
...
|
@@ -1442,9 +1399,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1442
|
1442
|
|
1443
|
1443
|
if(upack) memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
|
1444
|
1444
|
|
1445
|
|
- lseek(desc, exe_sections[1].uraw, SEEK_SET);
|
1446
|
|
-
|
1447
|
|
- if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].ursz) != exe_sections[1].ursz) {
|
|
1445
|
+ if(fmap_readn(map, dest + exe_sections[1].rva - off, exe_sections[1].uraw, exe_sections[1].ursz) != exe_sections[1].ursz) {
|
1448
|
1446
|
cli_dbgmsg("Upack: Can't read raw data of section 1\n");
|
1449
|
1447
|
free(dest);
|
1450
|
1448
|
break;
|
...
|
...
|
@@ -1485,31 +1440,27 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1485
|
1485
|
return CL_EMEM;
|
1486
|
1486
|
}
|
1487
|
1487
|
|
1488
|
|
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
|
|
1488
|
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
|
1489
|
1489
|
cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
|
1490
|
1490
|
free(exe_sections);
|
1491
|
|
- free(src);
|
1492
|
1491
|
return CL_ESEEK;
|
1493
|
1492
|
}
|
1494
|
1493
|
|
1495
|
1494
|
dest = src + newedx - exe_sections[i + 1].rva;
|
1496
|
1495
|
if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
|
1497
|
1496
|
cli_dbgmsg("FSG: New ESP out of bounds\n");
|
1498
|
|
- free(src);
|
1499
|
1497
|
break;
|
1500
|
1498
|
}
|
1501
|
1499
|
|
1502
|
1500
|
newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
|
1503
|
1501
|
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
|
1504
|
1502
|
cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
|
1505
|
|
- free(src);
|
1506
|
1503
|
break;
|
1507
|
1504
|
}
|
1508
|
1505
|
|
1509
|
1506
|
dest = src + newedx - exe_sections[i + 1].rva;
|
1510
|
1507
|
if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
|
1511
|
1508
|
cli_dbgmsg("FSG: New stack out of bounds\n");
|
1512
|
|
- free(src);
|
1513
|
1509
|
break;
|
1514
|
1510
|
}
|
1515
|
1511
|
|
...
|
...
|
@@ -1520,19 +1471,16 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1520
|
1520
|
|
1521
|
1521
|
if(newedi != exe_sections[i].rva) {
|
1522
|
1522
|
cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
|
1523
|
|
- free(src);
|
1524
|
1523
|
break;
|
1525
|
1524
|
}
|
1526
|
1525
|
|
1527
|
1526
|
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
|
1528
|
1527
|
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
|
1529
|
|
- free(src);
|
1530
|
1528
|
break;
|
1531
|
1529
|
}
|
1532
|
1530
|
|
1533
|
1531
|
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
|
1534
|
1532
|
cli_dbgmsg("FSG: Array of functions out of bounds\n");
|
1535
|
|
- free(src);
|
1536
|
1533
|
break;
|
1537
|
1534
|
}
|
1538
|
1535
|
|
...
|
...
|
@@ -1545,8 +1493,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1545
|
1545
|
return CL_EMEM;
|
1546
|
1546
|
}
|
1547
|
1547
|
|
1548
|
|
- CLI_UNPTEMP("FSG",(src,dest,exe_sections,0));
|
1549
|
|
- 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,(src,dest,0));
|
|
1548
|
+ CLI_UNPTEMP("FSG",(dest,exe_sections,0));
|
|
1549
|
+ 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));
|
1550
|
1550
|
break;
|
1551
|
1551
|
}
|
1552
|
1552
|
|
...
|
...
|
@@ -1571,25 +1519,18 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1571
|
1571
|
return CL_CLEAN;
|
1572
|
1572
|
}
|
1573
|
1573
|
|
1574
|
|
- if(!(gp = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
|
|
1574
|
+ if(!(t = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
|
1575
|
1575
|
cli_dbgmsg("FSG: Support data out of padding area\n");
|
1576
|
1576
|
break;
|
1577
|
1577
|
}
|
1578
|
1578
|
|
1579
|
|
- lseek(desc, gp, SEEK_SET);
|
1580
|
|
- gp = exe_sections[i + 1].raw - gp;
|
|
1579
|
+ gp = exe_sections[i + 1].raw - t;
|
1581
|
1580
|
|
1582
|
|
- CLI_UNPSIZELIMITS("FSG", gp)
|
|
1581
|
+ CLI_UNPSIZELIMITS("FSG", gp);
|
1583
|
1582
|
|
1584
|
|
- if((support = (char *) cli_malloc(gp)) == NULL) {
|
1585
|
|
- free(exe_sections);
|
1586
|
|
- return CL_EMEM;
|
1587
|
|
- }
|
1588
|
|
-
|
1589
|
|
- if((int)cli_readn(desc, support, gp) != (int)gp) {
|
|
1583
|
+ if(!(support = fmap_need_off_once(map, t, gp))) {
|
1590
|
1584
|
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
|
1591
|
1585
|
free(exe_sections);
|
1592
|
|
- free(support);
|
1593
|
1586
|
return CL_EREAD;
|
1594
|
1587
|
}
|
1595
|
1588
|
|
...
|
...
|
@@ -1599,13 +1540,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1599
|
1599
|
|
1600
|
1600
|
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
|
1601
|
1601
|
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
|
1602
|
|
- free(support);
|
1603
|
1602
|
break;
|
1604
|
1603
|
}
|
1605
|
1604
|
|
1606
|
1605
|
if(newedi != exe_sections[i].rva) {
|
1607
|
1606
|
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
|
1608
|
|
- free(support);
|
1609
|
1607
|
break;
|
1610
|
1608
|
}
|
1611
|
1609
|
|
...
|
...
|
@@ -1628,13 +1567,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1628
|
1628
|
}
|
1629
|
1629
|
|
1630
|
1630
|
if(t >= gp - 4 || cli_readint32(support + t)) {
|
1631
|
|
- free(support);
|
1632
|
1631
|
break;
|
1633
|
1632
|
}
|
1634
|
1633
|
|
1635
|
1634
|
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
|
1636
|
1635
|
free(exe_sections);
|
1637
|
|
- free(support);
|
1638
|
1636
|
return CL_EMEM;
|
1639
|
1637
|
}
|
1640
|
1638
|
|
...
|
...
|
@@ -1642,25 +1579,15 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1642
|
1642
|
for(t = 1; t <= (uint32_t)sectcnt; t++)
|
1643
|
1643
|
sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
|
1644
|
1644
|
|
1645
|
|
- free(support);
|
1646
|
|
-
|
1647
|
|
- if((src = (char *) cli_malloc(ssize)) == NULL) {
|
1648
|
|
- free(exe_sections);
|
1649
|
|
- free(sections);
|
1650
|
|
- return CL_EMEM;
|
1651
|
|
- }
|
1652
|
|
-
|
1653
|
|
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
|
|
1645
|
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
|
1654
|
1646
|
cli_dbgmsg("Can't read raw data of section %d\n", i);
|
1655
|
1647
|
free(exe_sections);
|
1656
|
1648
|
free(sections);
|
1657
|
|
- free(src);
|
1658
|
1649
|
return CL_EREAD;
|
1659
|
1650
|
}
|
1660
|
1651
|
|
1661
|
1652
|
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
|
1662
|
1653
|
free(exe_sections);
|
1663
|
|
- free(src);
|
1664
|
1654
|
free(sections);
|
1665
|
1655
|
return CL_EMEM;
|
1666
|
1656
|
}
|
...
|
...
|
@@ -1668,8 +1595,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1668
|
1668
|
oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
|
1669
|
1669
|
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
|
1670
|
1670
|
|
1671
|
|
- CLI_UNPTEMP("FSG",(src,dest,sections,exe_sections,0));
|
1672
|
|
- 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,(src,dest,sections,0));
|
|
1671
|
+ CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
|
|
1672
|
+ 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));
|
1673
|
1673
|
break; /* were done with 1.33 */
|
1674
|
1674
|
}
|
1675
|
1675
|
|
...
|
...
|
@@ -1679,8 +1606,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1679
|
1679
|
/* FSG support - v. 1.31 */
|
1680
|
1680
|
|
1681
|
1681
|
int sectcnt = 0;
|
1682
|
|
- uint32_t t;
|
1683
|
|
- uint32_t gp = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
|
|
1682
|
+ uint32_t gp, t = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
|
1684
|
1683
|
char *support;
|
1685
|
1684
|
uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
|
1686
|
1685
|
uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
|
...
|
...
|
@@ -1690,7 +1616,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1690
|
1690
|
ssize = exe_sections[i + 1].rsz;
|
1691
|
1691
|
dsize = exe_sections[i].vsz;
|
1692
|
1692
|
|
1693
|
|
-
|
1694
|
1693
|
if(err) {
|
1695
|
1694
|
cli_dbgmsg("FSG: Support data out of padding area\n");
|
1696
|
1695
|
break;
|
...
|
...
|
@@ -1714,20 +1639,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1714
|
1714
|
return CL_CLEAN;
|
1715
|
1715
|
}
|
1716
|
1716
|
|
1717
|
|
- lseek(desc, gp, SEEK_SET);
|
1718
|
|
- gp = exe_sections[i + 1].raw - gp;
|
|
1717
|
+ gp = exe_sections[i + 1].raw - t;
|
1719
|
1718
|
|
1720
|
1719
|
CLI_UNPSIZELIMITS("FSG", gp)
|
1721
|
1720
|
|
1722
|
|
- if((support = (char *) cli_malloc(gp)) == NULL) {
|
1723
|
|
- free(exe_sections);
|
1724
|
|
- return CL_EMEM;
|
1725
|
|
- }
|
1726
|
|
-
|
1727
|
|
- if(cli_readn(desc, support, gp) != (int)gp) {
|
|
1721
|
+ if(!(support = fmap_need_off_once(map, t, gp))) {
|
1728
|
1722
|
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
|
1729
|
1723
|
free(exe_sections);
|
1730
|
|
- free(support);
|
1731
|
1724
|
return CL_EREAD;
|
1732
|
1725
|
}
|
1733
|
1726
|
|
...
|
...
|
@@ -1748,13 +1666,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1748
|
1748
|
}
|
1749
|
1749
|
|
1750
|
1750
|
if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
|
1751
|
|
- free(support);
|
1752
|
1751
|
break;
|
1753
|
1752
|
}
|
1754
|
1753
|
|
1755
|
1754
|
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
|
1756
|
1755
|
free(exe_sections);
|
1757
|
|
- free(support);
|
1758
|
1756
|
return CL_EMEM;
|
1759
|
1757
|
}
|
1760
|
1758
|
|
...
|
...
|
@@ -1763,25 +1679,21 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1763
|
1763
|
sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
|
1764
|
1764
|
}
|
1765
|
1765
|
|
1766
|
|
- free(support);
|
1767
|
|
-
|
1768
|
1766
|
if((src = (char *) cli_malloc(ssize)) == NULL) {
|
1769
|
1767
|
free(exe_sections);
|
1770
|
1768
|
free(sections);
|
1771
|
1769
|
return CL_EMEM;
|
1772
|
1770
|
}
|
1773
|
1771
|
|
1774
|
|
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
|
|
1772
|
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
|
1775
|
1773
|
cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
|
1776
|
1774
|
free(exe_sections);
|
1777
|
1775
|
free(sections);
|
1778
|
|
- free(src);
|
1779
|
1776
|
return CL_EREAD;
|
1780
|
1777
|
}
|
1781
|
1778
|
|
1782
|
1779
|
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
|
1783
|
1780
|
free(exe_sections);
|
1784
|
|
- free(src);
|
1785
|
1781
|
free(sections);
|
1786
|
1782
|
return CL_EMEM;
|
1787
|
1783
|
}
|
...
|
...
|
@@ -1790,8 +1702,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1790
|
1790
|
oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
|
1791
|
1791
|
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
|
1792
|
1792
|
|
1793
|
|
- CLI_UNPTEMP("FSG",(src,dest,sections,exe_sections,0));
|
1794
|
|
- 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,(src,dest,sections,0));
|
|
1793
|
+ CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
|
|
1794
|
+ 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));
|
1795
|
1795
|
break; /* were done with 1.31 */
|
1796
|
1796
|
}
|
1797
|
1797
|
|
...
|
...
|
@@ -1817,20 +1729,19 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1817
|
1817
|
return CL_EMEM;
|
1818
|
1818
|
}
|
1819
|
1819
|
|
1820
|
|
- if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
|
1821
|
|
- free(exe_sections);
|
1822
|
|
- free(src);
|
1823
|
|
- return CL_EMEM;
|
1824
|
|
- }
|
1825
|
|
-
|
1826
|
|
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
|
|
1820
|
+ if(!exe_sections[i + 1].raw || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
|
1827
|
1821
|
cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
|
1828
|
1822
|
free(exe_sections);
|
1829
|
|
- free(src);
|
1830
|
1823
|
free(dest);
|
1831
|
1824
|
return CL_EREAD;
|
1832
|
1825
|
}
|
1833
|
1826
|
|
|
1827
|
+ if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
|
|
1828
|
+ free(exe_sections);
|
|
1829
|
+ return CL_EMEM;
|
|
1830
|
+ }
|
|
1831
|
+
|
|
1832
|
+
|
1834
|
1833
|
/* try to detect UPX code */
|
1835
|
1834
|
if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
|
1836
|
1835
|
cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
|
...
|
...
|
@@ -1904,13 +1815,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1904
|
1904
|
|
1905
|
1905
|
if(!upx_success) {
|
1906
|
1906
|
cli_dbgmsg("UPX: All decompressors failed\n");
|
1907
|
|
- free(src);
|
1908
|
1907
|
free(dest);
|
1909
|
1908
|
}
|
1910
|
1909
|
}
|
1911
|
1910
|
|
1912
|
1911
|
if(upx_success) {
|
1913
|
|
- free(src);
|
1914
|
1912
|
free(exe_sections);
|
1915
|
1913
|
|
1916
|
1914
|
CLI_UNPTEMP("UPX/FSG",(dest,0));
|
...
|
...
|
@@ -1978,7 +1887,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
1978
|
1978
|
|
1979
|
1979
|
for(i = 0 ; i < nsections; i++) {
|
1980
|
1980
|
if(exe_sections[i].raw) {
|
1981
|
|
- if(!cli_seeksect(desc, &exe_sections[i]) || (unsigned int) cli_readn(desc, dest + exe_sections[i].rva - min, exe_sections[i].ursz) != exe_sections[i].ursz) {
|
|
1981
|
+ 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) {
|
1982
|
1982
|
free(exe_sections);
|
1983
|
1983
|
free(dest);
|
1984
|
1984
|
return CL_CLEAN;
|
...
|
...
|
@@ -2007,8 +1916,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2007
|
2007
|
return CL_EMEM;
|
2008
|
2008
|
}
|
2009
|
2009
|
|
2010
|
|
- lseek(desc, 0, SEEK_SET);
|
2011
|
|
- if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
|
|
2010
|
+ if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
|
2012
|
2011
|
cli_dbgmsg("PESpin: Can't read %lu bytes\n", (unsigned long)fsize);
|
2013
|
2012
|
free(spinned);
|
2014
|
2013
|
free(exe_sections);
|
...
|
...
|
@@ -2072,8 +1980,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2072
|
2072
|
return CL_EMEM;
|
2073
|
2073
|
}
|
2074
|
2074
|
|
2075
|
|
- lseek(desc, 0, SEEK_SET);
|
2076
|
|
- if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
|
|
2075
|
+ if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
|
2077
|
2076
|
cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
|
2078
|
2077
|
free(spinned);
|
2079
|
2078
|
free(exe_sections);
|
...
|
...
|
@@ -2110,8 +2017,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2110
|
2110
|
free(exe_sections);
|
2111
|
2111
|
return CL_EMEM;
|
2112
|
2112
|
}
|
2113
|
|
- lseek(desc, 0, SEEK_SET);
|
2114
|
|
- if((size_t) cli_readn(desc, src, head) != head) {
|
|
2113
|
+ if((size_t) fmap_readn(map, src, 0, head) != head) {
|
2115
|
2114
|
cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
|
2116
|
2115
|
free(src);
|
2117
|
2116
|
free(exe_sections);
|
...
|
...
|
@@ -2119,9 +2025,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2119
|
2119
|
}
|
2120
|
2120
|
for(i = 0 ; i < (unsigned int)nsections-1; i++) {
|
2121
|
2121
|
if(!exe_sections[i].rsz) continue;
|
2122
|
|
- if(!cli_seeksect(desc, &exe_sections[i])) break;
|
2123
|
2122
|
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
|
2124
|
|
- if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
|
|
2123
|
+ if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
|
2125
|
2124
|
}
|
2126
|
2125
|
if(i+1!=nsections) {
|
2127
|
2126
|
cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
|
...
|
...
|
@@ -2133,7 +2038,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2133
|
2133
|
free(exe_sections);
|
2134
|
2134
|
return CL_EMEM;
|
2135
|
2135
|
}
|
2136
|
|
- if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, packer, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
|
|
2136
|
+ 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) {
|
2137
|
2137
|
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
|
2138
|
2138
|
free(src);
|
2139
|
2139
|
free(packer);
|
...
|
...
|
@@ -2165,9 +2070,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2165
|
2165
|
}
|
2166
|
2166
|
for(i = 0 ; i < (unsigned int)nsections; i++) {
|
2167
|
2167
|
if(!exe_sections[i].rsz) continue;
|
2168
|
|
- if(!cli_seeksect(desc, &exe_sections[i])) break;
|
2169
|
2168
|
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
|
2170
|
|
- if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
|
|
2169
|
+ if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
|
2171
|
2170
|
}
|
2172
|
2171
|
if(i!=nsections) {
|
2173
|
2172
|
cli_dbgmsg("Aspack: Probably hacked/damaged Aspack file.\n");
|
...
|
...
|
@@ -2186,14 +2090,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2186
|
2186
|
uint32_t eprva = vep;
|
2187
|
2187
|
uint32_t start_of_stuff, ssize, dsize, rep = ep;
|
2188
|
2188
|
unsigned int nowinldr;
|
2189
|
|
- char nbuff[24];
|
|
2189
|
+ char *nbuff;
|
2190
|
2190
|
char *src=epbuff, *dest;
|
2191
|
2191
|
|
2192
|
2192
|
if (*epbuff=='\xe9') { /* bitched headers */
|
2193
|
2193
|
eprva = cli_readint32(epbuff+1)+vep+5;
|
2194
|
2194
|
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
|
2195
|
|
- if (lseek(desc, rep, SEEK_SET)==-1) break;
|
2196
|
|
- if (cli_readn(desc, nbuff, 24)!=24) break;
|
|
2195
|
+ if (!(nbuff = fmap_need_off_once(map, rep, 24))) break;
|
2197
|
2196
|
src = nbuff;
|
2198
|
2197
|
}
|
2199
|
2198
|
|
...
|
...
|
@@ -2202,11 +2105,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2202
|
2202
|
nowinldr = 0x54-cli_readint32(src+17);
|
2203
|
2203
|
cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
|
2204
|
2204
|
|
2205
|
|
- if (lseek(desc, rep-nowinldr, SEEK_SET)==-1) break;
|
2206
|
|
- if (cli_readn(desc, nbuff, 4)!=4) break;
|
|
2205
|
+ if(!(nbuff = fmap_need_off_once(map, rep-nowinldr, 4))) break;
|
2207
|
2206
|
start_of_stuff=rep+cli_readint32(nbuff);
|
2208
|
|
- if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
|
2209
|
|
- if (cli_readn(desc, nbuff, 20)!=20) break;
|
|
2207
|
+ if(!(nbuff = fmap_need_off_once(map, start_of_stuff, 20))) break;
|
2210
|
2208
|
src = nbuff;
|
2211
|
2209
|
if (!cli_readint32(nbuff)) {
|
2212
|
2210
|
start_of_stuff+=4; /* FIXME: more to do */
|
...
|
...
|
@@ -2218,39 +2119,31 @@ int cli_scanpe(int desc, cli_ctx *ctx)
|
2218
|
2218
|
|
2219
|
2219
|
CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
|
2220
|
2220
|
|
2221
|
|
- if ( !ssize || !dsize || dsize != exe_sections[0].vsz) break;
|
2222
|
|
- if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
|
|
2221
|
+ if (!ssize || !dsize || dsize != exe_sections[0].vsz) break;
|
2223
|
2222
|
if (!(dest=cli_malloc(dsize))) break;
|
2224
|
2223
|
/* memset(dest, 0xfc, dsize); */
|
2225
|
2224
|
|
2226
|
|
- if (!(src=cli_malloc(ssize))) {
|
|
2225
|
+ if(!(src = fmap_need_off(map, start_of_stuff, ssize))) {
|
2227
|
2226
|
free(dest);
|
2228
|
2227
|
break;
|
2229
|
2228
|
}
|
2230
|
2229
|
/* memset(src, 0x00, ssize); */
|
2231
|
|
- cli_readn(desc, src, ssize);
|
2232
|
2230
|
|
2233
|
2231
|
eprva+=0x27a;
|
2234
|
2232
|
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
|
2235
|
2233
|
free(dest);
|
2236
|
|
- free(src);
|
2237
|
|
- break;
|
2238
|
|
- }
|
2239
|
|
- if (lseek(desc, rep, SEEK_SET)==-1) {
|
2240
|
|
- free(dest);
|
2241
|
|
- free(src);
|
2242
|
2234
|
break;
|
2243
|
2235
|
}
|
2244
|
|
- if (cli_readn(desc, nbuff, 5)!=5) {
|
|
2236
|
+ if(!(nbuff = fmap_need_off_once(map, rep, 5))) {
|
2245
|
2237
|
free(dest);
|
2246
|
|
- free(src);
|
2247
|
2238
|
break;
|
2248
|
2239
|
}
|
|
2240
|
+ fmap_unneed_off(map, start_of_stuff, ssize);
|
2249
|
2241
|
eprva=eprva+5+cli_readint32(nbuff+1);
|
2250
|
2242
|
cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
|
2251
|
2243
|
|
2252
|
|
- CLI_UNPTEMP("NsPack",(src,dest,exe_sections,0));
|
2253
|
|
- CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(src,dest,0));
|
|
2244
|
+ CLI_UNPTEMP("NsPack",(dest,exe_sections,0));
|
|
2245
|
+ CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(dest,0));
|
2254
|
2246
|
break;
|
2255
|
2247
|
}
|
2256
|
2248
|
|