[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
aCaB
acab at clamav.net
Sun Apr 4 01:03:22 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit a5241d274ca0b56fe2d3f380a08cc260d920b935
Author: aCaB <acab at clamav.net>
Date: Mon Aug 31 17:26:22 2009 +0200
scanpe to fmap
diff --git a/libclamav/fmap.c b/libclamav/fmap.c
index 493a293..894da02 100644
--- a/libclamav/fmap.c
+++ b/libclamav/fmap.c
@@ -400,6 +400,20 @@ void fmap_unneed_ptr(struct F_MAP *m, void *ptr, size_t len) {
return fmap_unneed_off(m, (char *)ptr - (char *)m - m->hdrsz, len);
}
+int fmap_readn(struct F_MAP *m, void *dst, size_t at, size_t len) {
+ char *src;
+
+ if(at > m->len)
+ return -1;
+ if(len > m->len - at)
+ len = m->len - at;
+ src = fmap_need_off_once(m, at, len);
+ if(!src)
+ return -1;
+ memcpy(dst, src, len);
+ return len;
+}
+
void fmunmap(struct F_MAP *m) {
void *p = (void *)m;
size_t len = m->pages * m->pgsz + m->hdrsz;
diff --git a/libclamav/fmap.h b/libclamav/fmap.h
index b07a9e2..15d07c2 100644
--- a/libclamav/fmap.h
+++ b/libclamav/fmap.h
@@ -43,4 +43,5 @@ void *fmap_need_ptr(struct F_MAP *m, void *ptr, size_t len);
void *fmap_need_ptr_once(struct F_MAP *m, void *ptr, size_t len);
void fmap_unneed_off(struct F_MAP *m, size_t at, size_t len);
void fmap_unneed_ptr(struct F_MAP *m, void *ptr, size_t len);
+int fmap_readn(struct F_MAP *m, void *dst, size_t at, size_t len);
#endif
diff --git a/libclamav/pe.c b/libclamav/pe.c
index 06b9a26..4ab33fb 100644
--- a/libclamav/pe.c
+++ b/libclamav/pe.c
@@ -38,6 +38,7 @@
#include "cltypes.h"
#include "clamav.h"
#include "others.h"
+#include "fmap.h"
#include "pe.h"
#include "petite.h"
#include "fsg.h"
@@ -290,7 +291,7 @@ static off_t cli_seeksect(int fd, struct cli_exe_section *s) {
return ret+1;
}
-static unsigned int cli_md5sect(int fd, struct cli_exe_section *s, unsigned char *digest) {
+static unsigned int cli_md5sect(struct F_MAP *map, struct cli_exe_section *s, unsigned char *digest) {
void *hashme;
cli_md5_ctx md5;
@@ -299,28 +300,21 @@ static unsigned int cli_md5sect(int fd, struct cli_exe_section *s, unsigned char
return 0;
}
- if(!cli_seeksect(fd, s)) return 0;
-
- if(!(hashme=cli_malloc(s->rsz))) {
- cli_dbgmsg("cli_md5sect: out of memory\n");
- return 0;
- }
-
- if(cli_readn(fd, hashme, s->rsz)!=s->rsz) {
+ if(!s->rsz) return 0;
+ if(!(hashme=fmap_need_off_once(map, s->raw, s->rsz))) {
cli_dbgmsg("cli_md5sect: unable to read section data\n");
return 0;
}
cli_md5_init(&md5);
cli_md5_update(&md5, hashme, s->rsz);
- free(hashme);
cli_md5_final(digest, &md5);
return 1;
}
-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) {
+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) {
unsigned int err = 0, i;
- uint8_t resdir[16];
+ uint8_t *resdir;
uint8_t *entry, *oentry;
uint16_t named, unnamed;
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
if(level>2 || !*maxres) return;
*maxres-=1;
- if(err || (pread(srcfd,resdir, sizeof(resdir), rawaddr) != sizeof(resdir)))
+ if(err || !(resdir = fmap_need_off_once(map, rawaddr, 16)))
return;
named = (uint16_t)cli_readint16(resdir+12);
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
entries = /*named+*/unnamed;
if (!entries)
return;
- oentry = entry = cli_malloc(entries*8);
rawaddr += named*8; /* skip named */
/* this is just used in a heuristic detection, so don't give error on failure */
if (!entry) {
cli_dbgmsg("cli_parseres_special: failed to allocate memory for resource directory:%lu\n", (unsigned long)entries);
return;
}
- if (pread(srcfd, entry, entries*8, rawaddr+16) != entries*8) {
+ if(!(entry = fmap_need_off(map, rawaddr+16, entries*8))) {
cli_dbgmsg("cli_parseres_special: failed to read resource directory at:%lu\n", (unsigned long)rawaddr+16);
- free(oentry);
return;
}
+ oentry = entry;
/*for (i=0; i<named; i++) {
uint32_t id, offs;
id = cli_readint32(entry);
@@ -389,13 +382,13 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
}
offs = cli_readint32(entry+4);
if(offs>>31)
- cli_parseres_special(base, base + (offs&0x7fffffff), srcfd, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats);
+ cli_parseres_special(base, base + (offs&0x7fffffff), map, exe_sections, nsections, fsize, hdr_size, level+1, type, maxres, stats);
else {
offs = cli_readint32(entry+4);
rawaddr = cli_rawaddr(base + offs, exe_sections, nsections, &err, fsize, hdr_size);
- if (!err && pread(srcfd, resdir, sizeof(resdir), rawaddr) == sizeof(resdir)) {
+ if (!err && (resdir = fmap_need_off_once(map, rawaddr, 16))) {
uint32_t isz = cli_readint32(resdir+4);
- char *str;
+ uint8_t *str;
rawaddr = cli_rawaddr(cli_readint32(resdir), exe_sections, nsections, &err, fsize, hdr_size);
if (err || !isz || isz >= fsize || rawaddr+isz >= fsize) {
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
stats->errors++;
continue;
}
- str = cli_malloc(isz);
- if (!str) {
- cli_dbgmsg("cli_parseres_special: failed to allocate string mem: %lu\n", (unsigned long)isz);
- continue;
- }
- if(pread(srcfd, str, isz, rawaddr) == isz) {
+ if((str = fmap_need_off_once(map, rawaddr, isz)))
cli_detect_swizz_str(str, isz, stats, type);
- }
- free (str);
}
}
}
- free (oentry);
+ fmap_unneed_ptr(map, oentry, entries*8);
}
-int cli_scanpe(int desc, cli_ctx *ctx)
+int cli_scanpe(cli_ctx *ctx)
{
uint16_t e_magic; /* DOS signature ("MZ") */
uint16_t nsections;
@@ -433,10 +419,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
struct pe_image_optional_hdr32 opt32;
} pe_opt;
struct pe_image_section_hdr *section_hdr;
- struct stat sb;
- char sname[9], buff[4096], epbuff[4096], *tempfile;
+ char sname[9], epbuff[4096], *tempfile;
uint32_t epsize;
- ssize_t bytes;
+ ssize_t bytes, at;
unsigned int i, found, upx_success = 0, min = 0, max = 0, err, overlays = 0;
unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0;
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)
struct cli_matcher *md5_sect;
char timestr[32];
struct pe_image_data_dir *dirs;
+ struct F_MAP *map;
if(!ctx) {
@@ -455,7 +441,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_ENULLARG;
}
- if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
+ map = *ctx->fmap;
+ if(fmap_readn(map, &e_magic, 0, sizeof(e_magic)) != sizeof(e_magic)) {
cli_dbgmsg("Can't read DOS signature\n");
return CL_CLEAN;
}
@@ -465,15 +452,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
- lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
-
- if(cli_readn(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
+ if(fmap_readn(map, &e_lfanew, 58 + sizeof(e_magic), sizeof(e_lfanew)) != sizeof(e_lfanew)) {
cli_dbgmsg("Can't read new header address\n");
/* truncated header? */
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
@@ -485,13 +470,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
- if(lseek(desc, e_lfanew, SEEK_SET) < 0) {
- /* probably not a PE file */
- cli_dbgmsg("Can't lseek to e_lfanew\n");
- return CL_CLEAN;
- }
-
- if(cli_readn(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
+ if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
/* bad information in e_lfanew - probably not a PE file */
cli_dbgmsg("Can't read file header\n");
return CL_CLEAN;
@@ -609,7 +588,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
if(nsections)
cli_warnmsg("PE file contains %d sections\n", nsections);
@@ -629,20 +608,22 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
- if(cli_readn(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
+ at = e_lfanew + sizeof(struct pe_image_file_hdr);
+ if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
+ at += sizeof(struct pe_image_optional_hdr32);
/* This will be a chicken and egg problem until we drop 9x */
if(EC16(optional_hdr64.Magic)==PE32P_SIGNATURE) {
@@ -652,7 +633,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
@@ -668,7 +649,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
cli_dbgmsg("9x compatibility mode\n");
}
@@ -677,7 +658,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(!pe_plus) { /* PE */
if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
/* Seek to the end of the long header */
- lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR);
+ at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
}
if(DCONF & PE_CONF_UPACK)
@@ -705,16 +686,16 @@ int cli_scanpe(int desc, cli_ctx *ctx)
} else { /* PE+ */
/* read the remaining part of the header */
- 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)) {
+ 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)) {
cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
-
+ at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
vep = EC32(optional_hdr64.AddressOfEntryPoint);
hdr_size = EC32(optional_hdr64.SizeOfHeaders);
cli_dbgmsg("File format: PE32+\n");
@@ -791,22 +772,17 @@ int cli_scanpe(int desc, cli_ctx *ctx)
cli_dbgmsg("Bad virtual alignemnt\n");
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
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)) {
cli_dbgmsg("Bad file alignemnt\n");
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
- if(fstat(desc, &sb) == -1) {
- cli_dbgmsg("fstat failed\n");
- return CL_ESTAT;
- }
-
- fsize = sb.st_size;
+ fsize = map->len;
section_hdr = (struct pe_image_section_hdr *) cli_calloc(nsections, sizeof(struct pe_image_section_hdr));
@@ -826,7 +802,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
falign = (pe_plus)?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment);
- if(cli_readn(desc, section_hdr, sizeof(struct pe_image_section_hdr)*nsections) != (int)(nsections*sizeof(struct pe_image_section_hdr))) {
+ if(fmap_readn(map, section_hdr, at, sizeof(struct pe_image_section_hdr)*nsections) != (int)(nsections*sizeof(struct pe_image_section_hdr))) {
cli_dbgmsg("Can't read section header\n");
cli_dbgmsg("Possibly broken PE file\n");
free(section_hdr);
@@ -834,11 +810,12 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
-
+ at += sizeof(struct pe_image_section_hdr)*nsections;
+
for(i = 0; falign!=0x200 && i<nsections; i++) {
/* file alignment fallback mode - blah */
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)
*ctx->virname = "Broken.Executable";
free(section_hdr);
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
@@ -914,7 +891,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN; /* no ninjas to see here! move along! */
}
@@ -928,12 +905,12 @@ int cli_scanpe(int desc, cli_ctx *ctx)
for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) {
if(md5_sect->soff[j] == exe_sections[i].rsz) {
unsigned char md5_dig[16];
- 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) {
+ 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) {
if(cli_bm_scanbuff(md5_dig, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS) {
free(section_hdr);
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
}
break;
@@ -949,7 +926,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
@@ -961,7 +938,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
*ctx->virname = "Broken.Executable";
free(section_hdr);
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
min = exe_sections[i].rva;
max = exe_sections[i].rva + exe_sections[i].rsz;
@@ -972,7 +949,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
*ctx->virname = "Broken.Executable";
free(section_hdr);
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
if(exe_sections[i].rva < min)
min = exe_sections[i].rva;
@@ -992,7 +969,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(DETECT_BROKEN) {
if(ctx->virname)
*ctx->virname = "Broken.Executable";
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
return CL_CLEAN;
}
@@ -1004,8 +981,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
- lseek(desc, ep, SEEK_SET);
- epsize = cli_readn(desc, epbuff, 4096);
+ epsize = fmap_readn(map, epbuff, ep, 4096);
CLI_UNPTEMP("DISASM",(exe_sections,0));
disasmbuf((unsigned char*)epbuff, epsize, ndesc);
@@ -1022,7 +998,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(overlays) {
int overlays_sz = fsize - overlays;
if(overlays_sz > 0) {
- ret = cli_scanishield(desc, ctx, overlays, overlays_sz);
+ ret = cli_scanishield(map->fd, ctx, overlays, overlays_sz);
if(ret != CL_CLEAN) {
free(exe_sections);
return ret;
@@ -1040,7 +1016,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
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)) {
*ctx->virname = "W32.Parite.B";
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
}
}
@@ -1123,7 +1099,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
*ctx->virname = "W32.Kriz";
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
kzstate++;
@@ -1144,25 +1120,25 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(vsize >= 0x612c && rsize >= 0x612c && ((vsize & 0xff) == 0xec)) {
int bw = rsize < 0x7000 ? rsize : 0x7000;
+ char *tbuff;
- lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET);
- if(cli_readn(desc, buff, 4096) == 4096) {
- if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
+ if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
+ if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
*ctx->virname = dam ? "W32.Magistr.A.dam" : "W32.Magistr.A";
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
}
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
int bw = rsize < 0x8000 ? rsize : 0x8000;
+ char *tbuff;
- lseek(desc, exe_sections[nsections - 1].raw + rsize - bw, SEEK_SET);
- if(cli_readn(desc, buff, 4096) == 4096) {
- if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
+ if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
+ if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
*ctx->virname = dam ? "W32.Magistr.B.dam" : "W32.Magistr.B";
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
}
}
@@ -1175,15 +1151,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
unsigned int xsjs = 0;
if(exe_sections[0].rsz > CLI_MAX_ALLOCATION) break;
- if(!cli_seeksect(desc, &exe_sections[0])) break;
- if(!(code=cli_malloc(exe_sections[0].rsz))) {
- free(exe_sections);
- return CL_EMEM;
- }
- if(cli_readn(desc, code, exe_sections[0].rsz)!=exe_sections[0].rsz) {
- free(exe_sections);
- return CL_EREAD;
- }
+
+ if(!exe_sections[0].rsz) break;
+ if(!(code=fmap_need_off_once(map, exe_sections[0].raw, exe_sections[0].rsz))) break;
for(i=0; i<exe_sections[0].rsz - 5; i++) {
if((uint8_t)(code[i]-0xe8) > 1) continue;
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)
if(xsjs % 128 == 0) {
if(xsjs == 1280) break;
if(!(jumps=(uint32_t *)cli_realloc2(jumps, (xsjs+128)*sizeof(uint32_t)))) {
- free(code);
free(exe_sections);
return CL_EMEM;
}
@@ -1210,17 +1179,15 @@ int cli_scanpe(int desc, cli_ctx *ctx)
jumps[j]=jump;
xsjs++;
}
- free(code);
if(!xsjs) break;
cli_dbgmsg("Polipos: Checking %d xsect jump(s)\n", xsjs);
for(i=0;i<xsjs;i++) {
- lseek(desc, jumps[i], SEEK_SET);
- if(cli_readn(desc, buff, 9) != 9) continue;
- if((jump=cli_readint32(buff))==0x60ec8b55 || (buff[4]=='\xec' && ((jump==0x83ec8b55 && buff[6]=='\x60') || (jump==0x81ec8b55 && !buff[7] && !buff[8])))) {
+ if(!(code = fmap_need_off_once(map, jumps[i], 9))) continue;
+ if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]=='\xec' && ((jump==0x83ec8b55 && code[6]=='\x60') || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
*ctx->virname = "W32.Polipos.A";
free(jumps);
free(exe_sections);
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
}
}
free(jumps);
@@ -1237,7 +1204,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if (!stats)
ret = CL_EMEM;
else {
- cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), desc, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
+ cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
*ctx->virname = "Trojan.Swizzor.Gen";
}
@@ -1246,7 +1213,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if (ret != CL_CLEAN) {
free(exe_sections);
if(ret == CL_VIRUS)
- return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;
return ret;
}
}
@@ -1269,6 +1236,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
/* MEW support */
if (found && (DCONF & PE_CONF_MEW) && epsize>=16 && epbuff[0]=='\xe9') {
uint32_t fileoffset;
+ char *tbuff;
fileoffset = (vep + cli_readint32(epbuff + 1) + 5);
while (fileoffset == 0x154 || fileoffset == 0x158) {
@@ -1277,29 +1245,20 @@ int cli_scanpe(int desc, cli_ctx *ctx)
cli_dbgmsg ("MEW: found MEW characteristics %08X + %08X + 5 = %08X\n",
cli_readint32(epbuff + 1), vep, cli_readint32(epbuff + 1) + vep + 5);
- if(lseek(desc, fileoffset, SEEK_SET) == -1) {
- cli_dbgmsg("MEW: lseek() failed\n");
- free(exe_sections);
- return CL_ESEEK;
- }
-
- if((bytes = read(desc, buff, 0xb0)) != 0xb0) {
- cli_dbgmsg("MEW: Can't read 0xb0 bytes at 0x%x (%d) %lu\n", fileoffset, fileoffset, (unsigned long)bytes);
+ if(!(tbuff = fmap_need_off_once(map, fileoffset, 0xb0)))
break;
- }
-
if (fileoffset == 0x154) cli_dbgmsg("MEW: Win9x compatibility was set!\n");
else cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
- 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) {
+ 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) {
cli_dbgmsg("MEW: ESI is not in proper section\n");
break;
}
offdiff -= exe_sections[i + 1].rva;
- if(!cli_seeksect(desc, &exe_sections[i + 1])) {
- free(exe_sections);
- return CL_ESEEK;
+ if(!exe_sections[i + 1].rsz) {
+ cli_dbgmsg("MEW: mew section is empty\n");
+ break;
}
ssize = exe_sections[i + 1].vsz;
dsize = exe_sections[i].vsz;
@@ -1309,20 +1268,19 @@ int cli_scanpe(int desc, cli_ctx *ctx)
CLI_UNPSIZELIMITS("MEW", MAX(ssize, dsize));
CLI_UNPSIZELIMITS("MEW", MAX(ssize + dsize, exe_sections[i + 1].rsz));
+ if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
+ cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
+ break;
+ }
+
/* allocate needed buffer */
if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
free(exe_sections);
return CL_EMEM;
}
- if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
- cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
- free(src);
- break;
- }
-
- if((bytes = read(desc, src + dsize, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
- cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
+ if((bytes = fmap_readn(map, src + dsize, exe_sections[i + 1].raw, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
+ cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
free(exe_sections);
free(src);
return CL_EREAD;
@@ -1330,13 +1288,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
cli_dbgmsg("MEW: %u (%08x) bytes read\n", (unsigned int)bytes, (unsigned int)bytes);
/* count offset to lzma proc, if lzma used, 0xe8 -> call */
- if (buff[0x7b] == '\xe8') {
- if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(buff + 0x7c) + fileoffset + 0x80, 4)) {
+ if (tbuff[0x7b] == '\xe8') {
+ if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(tbuff + 0x7c) + fileoffset + 0x80, 4)) {
cli_dbgmsg("MEW: lzma proc out of bounds!\n");
free(src);
break; /* to next unpacker in chain */
}
- uselzma = cli_readint32(buff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
+ uselzma = cli_readint32(tbuff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
} else {
uselzma = 0;
}
@@ -1433,8 +1391,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- lseek(desc, 0, SEEK_SET);
- if(read(desc, dest, ssize) != ssize) {
+ if(fmap_readn(map, dest, 0, ssize) != ssize) {
cli_dbgmsg("Upack: Can't read raw data of section 0\n");
free(dest);
break;
@@ -1442,9 +1399,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(upack) memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
- lseek(desc, exe_sections[1].uraw, SEEK_SET);
-
- if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].ursz) != exe_sections[1].ursz) {
+ if(fmap_readn(map, dest + exe_sections[1].rva - off, exe_sections[1].uraw, exe_sections[1].ursz) != exe_sections[1].ursz) {
cli_dbgmsg("Upack: Can't read raw data of section 1\n");
free(dest);
break;
@@ -1485,31 +1440,27 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
free(exe_sections);
- free(src);
return CL_ESEEK;
}
dest = src + newedx - exe_sections[i + 1].rva;
if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dest, 4)) {
cli_dbgmsg("FSG: New ESP out of bounds\n");
- free(src);
break;
}
newedx = cli_readint32(dest) - EC32(optional_hdr32.ImageBase);
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
- free(src);
break;
}
dest = src + newedx - exe_sections[i + 1].rva;
if(!CLI_ISCONTAINED(src, ssize, dest, 32)) {
cli_dbgmsg("FSG: New stack out of bounds\n");
- free(src);
break;
}
@@ -1520,19 +1471,16 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(newedi != exe_sections[i].rva) {
cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
- free(src);
break;
}
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
- free(src);
break;
}
if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
cli_dbgmsg("FSG: Array of functions out of bounds\n");
- free(src);
break;
}
@@ -1545,8 +1493,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- CLI_UNPTEMP("FSG",(src,dest,exe_sections,0));
- 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));
+ CLI_UNPTEMP("FSG",(dest,exe_sections,0));
+ 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));
break;
}
@@ -1571,25 +1519,18 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
- if(!(gp = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
+ if(!(t = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
cli_dbgmsg("FSG: Support data out of padding area\n");
break;
}
- lseek(desc, gp, SEEK_SET);
- gp = exe_sections[i + 1].raw - gp;
+ gp = exe_sections[i + 1].raw - t;
- CLI_UNPSIZELIMITS("FSG", gp)
+ CLI_UNPSIZELIMITS("FSG", gp);
- if((support = (char *) cli_malloc(gp)) == NULL) {
- free(exe_sections);
- return CL_EMEM;
- }
-
- if((int)cli_readn(desc, support, gp) != (int)gp) {
+ if(!(support = fmap_need_off_once(map, t, gp))) {
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
free(exe_sections);
- free(support);
return CL_EREAD;
}
@@ -1599,13 +1540,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
cli_dbgmsg("FSG: Source buffer out of section bounds\n");
- free(support);
break;
}
if(newedi != exe_sections[i].rva) {
cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
- free(support);
break;
}
@@ -1628,13 +1567,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
}
if(t >= gp - 4 || cli_readint32(support + t)) {
- free(support);
break;
}
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
free(exe_sections);
- free(support);
return CL_EMEM;
}
@@ -1642,25 +1579,15 @@ int cli_scanpe(int desc, cli_ctx *ctx)
for(t = 1; t <= (uint32_t)sectcnt; t++)
sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
- free(support);
-
- if((src = (char *) cli_malloc(ssize)) == NULL) {
- free(exe_sections);
- free(sections);
- return CL_EMEM;
- }
-
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
cli_dbgmsg("Can't read raw data of section %d\n", i);
free(exe_sections);
free(sections);
- free(src);
return CL_EREAD;
}
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
free(exe_sections);
- free(src);
free(sections);
return CL_EMEM;
}
@@ -1668,8 +1595,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
- CLI_UNPTEMP("FSG",(src,dest,sections,exe_sections,0));
- 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));
+ CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
+ 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));
break; /* were done with 1.33 */
}
@@ -1679,8 +1606,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
/* FSG support - v. 1.31 */
int sectcnt = 0;
- uint32_t t;
- uint32_t gp = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
+ uint32_t gp, t = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
char *support;
uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
@@ -1690,7 +1616,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
ssize = exe_sections[i + 1].rsz;
dsize = exe_sections[i].vsz;
-
if(err) {
cli_dbgmsg("FSG: Support data out of padding area\n");
break;
@@ -1714,20 +1639,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
- lseek(desc, gp, SEEK_SET);
- gp = exe_sections[i + 1].raw - gp;
+ gp = exe_sections[i + 1].raw - t;
CLI_UNPSIZELIMITS("FSG", gp)
- if((support = (char *) cli_malloc(gp)) == NULL) {
- free(exe_sections);
- return CL_EMEM;
- }
-
- if(cli_readn(desc, support, gp) != (int)gp) {
+ if(!(support = fmap_need_off_once(map, t, gp))) {
cli_dbgmsg("Can't read %d bytes from padding area\n", gp);
free(exe_sections);
- free(support);
return CL_EREAD;
}
@@ -1748,13 +1666,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
}
if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
- free(support);
break;
}
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
free(exe_sections);
- free(support);
return CL_EMEM;
}
@@ -1763,25 +1679,21 @@ int cli_scanpe(int desc, cli_ctx *ctx)
sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
}
- free(support);
-
if((src = (char *) cli_malloc(ssize)) == NULL) {
free(exe_sections);
free(sections);
return CL_EMEM;
}
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
+ if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
free(exe_sections);
free(sections);
- free(src);
return CL_EREAD;
}
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
free(exe_sections);
- free(src);
free(sections);
return CL_EMEM;
}
@@ -1790,8 +1702,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
cli_dbgmsg("FSG: found old EP @%x\n", oldep);
- CLI_UNPTEMP("FSG",(src,dest,sections,exe_sections,0));
- 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));
+ CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
+ 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));
break; /* were done with 1.31 */
}
@@ -1817,20 +1729,19 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
- free(exe_sections);
- free(src);
- return CL_EMEM;
- }
-
- if(!cli_seeksect(desc, &exe_sections[i + 1]) || (unsigned int) cli_readn(desc, src, ssize) != ssize) {
+ if(!exe_sections[i + 1].raw || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
free(exe_sections);
- free(src);
free(dest);
return CL_EREAD;
}
+ if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
+ free(exe_sections);
+ return CL_EMEM;
+ }
+
+
/* try to detect UPX code */
if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
@@ -1904,13 +1815,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
if(!upx_success) {
cli_dbgmsg("UPX: All decompressors failed\n");
- free(src);
free(dest);
}
}
if(upx_success) {
- free(src);
free(exe_sections);
CLI_UNPTEMP("UPX/FSG",(dest,0));
@@ -1978,7 +1887,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
for(i = 0 ; i < nsections; i++) {
if(exe_sections[i].raw) {
- 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) {
+ 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) {
free(exe_sections);
free(dest);
return CL_CLEAN;
@@ -2007,8 +1916,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- lseek(desc, 0, SEEK_SET);
- if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
+ if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
cli_dbgmsg("PESpin: Can't read %lu bytes\n", (unsigned long)fsize);
free(spinned);
free(exe_sections);
@@ -2072,8 +1980,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
return CL_EMEM;
}
- lseek(desc, 0, SEEK_SET);
- if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
+ if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
free(spinned);
free(exe_sections);
@@ -2110,8 +2017,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
free(exe_sections);
return CL_EMEM;
}
- lseek(desc, 0, SEEK_SET);
- if((size_t) cli_readn(desc, src, head) != head) {
+ if((size_t) fmap_readn(map, src, 0, head) != head) {
cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
free(src);
free(exe_sections);
@@ -2119,9 +2025,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
}
for(i = 0 ; i < (unsigned int)nsections-1; i++) {
if(!exe_sections[i].rsz) continue;
- if(!cli_seeksect(desc, &exe_sections[i])) break;
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
- if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
+ if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
}
if(i+1!=nsections) {
cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
@@ -2133,7 +2038,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
free(exe_sections);
return CL_EMEM;
}
- if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, packer, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
+ 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) {
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
free(src);
free(packer);
@@ -2165,9 +2070,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
}
for(i = 0 ; i < (unsigned int)nsections; i++) {
if(!exe_sections[i].rsz) continue;
- if(!cli_seeksect(desc, &exe_sections[i])) break;
if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
- if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
+ if(fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
}
if(i!=nsections) {
cli_dbgmsg("Aspack: Probably hacked/damaged Aspack file.\n");
@@ -2186,14 +2090,13 @@ int cli_scanpe(int desc, cli_ctx *ctx)
uint32_t eprva = vep;
uint32_t start_of_stuff, ssize, dsize, rep = ep;
unsigned int nowinldr;
- char nbuff[24];
+ char *nbuff;
char *src=epbuff, *dest;
if (*epbuff=='\xe9') { /* bitched headers */
eprva = cli_readint32(epbuff+1)+vep+5;
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
- if (lseek(desc, rep, SEEK_SET)==-1) break;
- if (cli_readn(desc, nbuff, 24)!=24) break;
+ if (!(nbuff = fmap_need_off_once(map, rep, 24))) break;
src = nbuff;
}
@@ -2202,11 +2105,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
nowinldr = 0x54-cli_readint32(src+17);
cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
- if (lseek(desc, rep-nowinldr, SEEK_SET)==-1) break;
- if (cli_readn(desc, nbuff, 4)!=4) break;
+ if(!(nbuff = fmap_need_off_once(map, rep-nowinldr, 4))) break;
start_of_stuff=rep+cli_readint32(nbuff);
- if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
- if (cli_readn(desc, nbuff, 20)!=20) break;
+ if(!(nbuff = fmap_need_off_once(map, start_of_stuff, 20))) break;
src = nbuff;
if (!cli_readint32(nbuff)) {
start_of_stuff+=4; /* FIXME: more to do */
@@ -2218,39 +2119,31 @@ int cli_scanpe(int desc, cli_ctx *ctx)
CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
- if ( !ssize || !dsize || dsize != exe_sections[0].vsz) break;
- if (lseek(desc, start_of_stuff, SEEK_SET)==-1) break;
+ if (!ssize || !dsize || dsize != exe_sections[0].vsz) break;
if (!(dest=cli_malloc(dsize))) break;
/* memset(dest, 0xfc, dsize); */
- if (!(src=cli_malloc(ssize))) {
+ if(!(src = fmap_need_off(map, start_of_stuff, ssize))) {
free(dest);
break;
}
/* memset(src, 0x00, ssize); */
- cli_readn(desc, src, ssize);
eprva+=0x27a;
if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
free(dest);
- free(src);
- break;
- }
- if (lseek(desc, rep, SEEK_SET)==-1) {
- free(dest);
- free(src);
break;
}
- if (cli_readn(desc, nbuff, 5)!=5) {
+ if(!(nbuff = fmap_need_off_once(map, rep, 5))) {
free(dest);
- free(src);
break;
}
+ fmap_unneed_off(map, start_of_stuff, ssize);
eprva=eprva+5+cli_readint32(nbuff+1);
cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
- CLI_UNPTEMP("NsPack",(src,dest,exe_sections,0));
- CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(src,dest,0));
+ CLI_UNPTEMP("NsPack",(dest,exe_sections,0));
+ CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(dest,0));
break;
}
diff --git a/libclamav/pe.h b/libclamav/pe.h
index a8ad47a..81c8986 100644
--- a/libclamav/pe.h
+++ b/libclamav/pe.h
@@ -128,7 +128,7 @@ struct pe_image_section_hdr {
uint32_t Characteristics;
};
-int cli_scanpe(int desc, cli_ctx *ctx);
+int cli_scanpe(cli_ctx *ctx);
int cli_peheader(int desc, struct cli_exe_info *peinfo);
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index cad0b98..55edc07 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -2161,7 +2161,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
*/
case CL_TYPE_MSEXE:
if(SCAN_PE && ctx->dconf->pe)
- ret = cli_scanpe(desc, ctx);
+ ret = cli_scanpe(ctx);
break;
default:
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list