better handling of embedded stuff

git-svn: trunk@2965
This commit is contained in:
Tomasz Kojm 2007-03-23 15:11:45 +00:00
parent 154cd836d5
commit d68a73d1a2
3 changed files with 99 additions and 70 deletions

View file

@ -1,3 +1,7 @@
Fri Mar 23 14:19:42 CET 2007 (tk)
---------------------------------
* libclamav: better handling of embedded stuff
Wed Mar 21 01:15:51 CET 2007 (tk)
---------------------------------
* docs/man: use actual version and user names in man pages (bb#408),

View file

@ -425,7 +425,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
int type = CL_CLEAN, j;
unsigned int i, position, curroff;
uint8_t offnum, found;
struct cli_matched_type *tnode;
struct cli_matched_type *tnode, *tnode_last = NULL;
struct cli_target_info info;
@ -510,6 +510,11 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
if(otfrec) {
if(pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) {
cli_dbgmsg("Matched signature for file type %s at %u\n", pt->virname, (unsigned int) mdata->inioff[pt->sigid - 1]);
mdata->offcnt[pt->sigid - 1] = 0;
mdata->offidx[pt->sigid - 1] = 0;
mdata->partcnt[pt->sigid - 1] = 0;
mdata->maxshift[pt->sigid - 1] = -1;
type = pt->type;
if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE))) {
if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) {
@ -522,13 +527,21 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
tnode->type = type;
tnode->offset = mdata->inioff[pt->sigid - 1];
if(*ftoffset)
tnode->cnt = (*ftoffset)->cnt + 1;
else
tnode->cnt = 1;
if(*ftoffset && !tnode_last) {
tnode_last = *ftoffset;
while(tnode_last->next)
tnode_last = tnode_last->next;
}
tnode->next = *ftoffset;
*ftoffset = tnode;
if(tnode_last) {
tnode_last->next = tnode;
tnode_last = tnode;
} else {
*ftoffset = tnode;
tnode_last = tnode;
}
(*ftoffset)->cnt++;
}
}
}
@ -560,13 +573,21 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
tnode->type = type;
tnode->offset = curroff;
if(*ftoffset)
tnode->cnt = (*ftoffset)->cnt + 1;
else
tnode->cnt = 1;
if(*ftoffset && !tnode_last) {
tnode_last = *ftoffset;
while(tnode_last->next)
tnode_last = tnode_last->next;
}
tnode->next = *ftoffset;
*ftoffset = tnode;
if(tnode_last) {
tnode_last->next = tnode;
tnode_last = tnode;
} else {
*ftoffset = tnode;
tnode_last = tnode;
}
(*ftoffset)->cnt++;
}
}
}

View file

@ -1748,7 +1748,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
{
int ret = CL_CLEAN, nret = CL_CLEAN;
unsigned short ftrec;
unsigned short ftrec, break_loop = 0;
struct cli_matched_type *ftoffset = NULL, *fpt;
uint32_t lastzip, lastrar;
struct cli_exe_info peinfo;
@ -1773,7 +1773,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
if(ret >= CL_TYPENO) {
if(ret < CL_TYPE_SFX && ret != CL_TYPE_MSEXE) {
if(type == CL_TYPE_UNKNOWN_TEXT) {
lseek(desc, 0, SEEK_SET);
nret = cli_scandesc(desc, ctx, 0, ret, 1, NULL);
@ -1781,6 +1781,65 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
cli_dbgmsg("%s found in descriptor %d when scanning file type %u\n", *ctx->virname, desc, ret);
}
if(nret != CL_VIRUS && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP)) {
lastzip = lastrar = 0xdeadbeef;
fpt = ftoffset;
while(fpt) {
switch(fpt->type) {
case CL_TYPE_RARSFX:
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_RAR)) {
cli_dbgmsg("RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar);
}
break;
case CL_TYPE_ZIPSFX:
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
cli_dbgmsg("ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset);
nret = cli_scanzip(desc, ctx, fpt->offset, &lastzip);
}
break;
case CL_TYPE_CABSFX:
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_CAB)) {
cli_dbgmsg("CAB-SFX signature found at %u\n", (unsigned int) fpt->offset);
nret = cli_scanmscab(desc, ctx, fpt->offset);
}
break;
case CL_TYPE_MSEXE:
if(SCAN_PE && ctx->dconf->pe && fpt->offset) {
cli_dbgmsg("PE signature found at %u\n", (unsigned int) fpt->offset);
memset(&peinfo, 0, sizeof(struct cli_exe_info));
peinfo.offset = fpt->offset;
lseek(desc, fpt->offset, SEEK_SET);
if(cli_peheader(desc, &peinfo) == 0) {
cli_dbgmsg("*** Detected embedded PE file ***\n");
if(peinfo.section)
free(peinfo.section);
lseek(desc, fpt->offset, SEEK_SET);
nret = cli_scanembpe(desc, ctx);
break_loop = 1; /* we can stop here and other
* embedded executables will
* be found recursively
* through the above call
*/
}
}
break;
default:
cli_warnmsg("cli_scanraw: Type %u not handled in fpt loop\n", fpt->type);
}
if(nret == CL_VIRUS || break_loop)
break;
fpt = fpt->next;
}
}
ret == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++;
if(nret != CL_VIRUS) switch(ret) {
@ -1794,61 +1853,6 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
nret = cli_scanmail(desc, ctx);
break;
case CL_TYPE_RARSFX:
case CL_TYPE_ZIPSFX:
case CL_TYPE_CABSFX:
if(type == CL_TYPE_MSEXE) {
if(SCAN_ARCHIVE) {
lastzip = lastrar = 0xdeadbeef;
fpt = ftoffset;
while(fpt) {
if(fpt->type == CL_TYPE_RARSFX && (DCONF_ARCH & ARCH_CONF_RAR)) {
cli_dbgmsg("RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
if((nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar)) == CL_VIRUS)
break;
} else if(fpt->type == CL_TYPE_ZIPSFX && (DCONF_ARCH & ARCH_CONF_ZIP)) {
cli_dbgmsg("ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset);
if((nret = cli_scanzip(desc, ctx, fpt->offset, &lastzip)) == CL_VIRUS)
break;
} else if(fpt->type == CL_TYPE_CABSFX && (DCONF_ARCH & ARCH_CONF_CAB)) {
cli_dbgmsg("CAB-SFX signature found at %u\n", (unsigned int) fpt->offset);
if((nret = cli_scanmscab(desc, ctx, fpt->offset)) == CL_VIRUS)
break;
}
fpt = fpt->next;
}
}
}
break;
case CL_TYPE_MSEXE:
if(SCAN_PE && ctx->dconf->pe) {
fpt = ftoffset;
while(fpt) {
if(fpt->type == CL_TYPE_MSEXE && fpt->offset) {
cli_dbgmsg("PE signature found at %u\n", (unsigned int) fpt->offset);
memset(&peinfo, 0, sizeof(struct cli_exe_info));
peinfo.offset = fpt->offset;
lseek(desc, fpt->offset, SEEK_SET);
if(cli_peheader(desc, &peinfo) == 0) {
cli_dbgmsg("*** Detected embedded PE file ***\n");
if(peinfo.section)
free(peinfo.section);
lseek(desc, fpt->offset, SEEK_SET);
nret = cli_scanembpe(desc, ctx);
break; /* we can stop here, other embedded
* executables will be found recursively
* through the above call
*/
}
}
fpt = fpt->next;
}
}
break;
default:
break;
}