pe update

git-svn: trunk@600
This commit is contained in:
Tomasz Kojm 2004-06-11 20:17:18 +00:00
parent 51fc2aa8ba
commit ac75a532b4
6 changed files with 86 additions and 42 deletions

View file

@ -1,3 +1,7 @@
Fri Jun 11 22:11:31 CEST 2004 (tk)
----------------------------------
* libclamav: pe: add dumper; RVA calculation; fix error codes
Wed Jun 9 17:47:29 CEST 2004 (tk)
----------------------------------
* clamd: do not display "Command parser: read() failed." (in SESSION mode)

View file

@ -1,4 +1,4 @@
# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
# aclocal.m4t generated automatically by aclocal 1.6.1 -*- Autoconf -*-
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for
dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created
dnl (the prefix is a bit different, since we add an extra -target- and -host-)
dnl
dnl @version: $Id: aclocal.m4,v 1.40 2004/06/06 01:50:08 kojm Exp $
dnl @version: $Id: aclocal.m4,v 1.41 2004/06/11 20:17:18 kojm Exp $
dnl @author Guido Draheim <guidod@gmx.de> STATUS: used often
AC_DEFUN([AC_CREATE_TARGET_H],
@ -4041,7 +4041,7 @@ dnl AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
dnl AC_COMPILE_CHECK_SIZEOF(off_t, $headers)
dnl
dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu>
dnl @version $Id: aclocal.m4,v 1.40 2004/06/06 01:50:08 kojm Exp $
dnl @version $Id: aclocal.m4,v 1.41 2004/06/11 20:17:18 kojm Exp $
dnl
AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
[changequote(<<, >>)dnl

View file

@ -46,7 +46,7 @@ while test $# -gt 0; do
;;
--version)
echo devel-20040606
echo devel-20040611
exit 0
;;

View file

@ -64,6 +64,7 @@ extern "C"
#define CL_ECVDEXTR -9 /* CVD extraction failure */
#define CL_EMD5 -10 /* MD5 verification error */
#define CL_EDSIG -11 /* digital signature verification error */
#define CL_EIO -12 /* general I/O error */
/* options */
#define CL_RAW 0

View file

@ -103,55 +103,57 @@ const char *cl_strerror(int clerror)
{
switch(clerror) {
case CL_CLEAN:
return "Virus NOT found.";
return "No viruses detected";
case CL_VIRUS:
return "Virus(es) detected.";
return "Virus(es) detected";
case CL_EMAXREC:
return "Recursion limit exceeded.";
return "Recursion limit exceeded";
case CL_EMAXSIZE:
return "File size limit exceeded.";
return "File size limit exceeded";
case CL_EMAXFILES:
return "Files number limit exceeded.";
return "Files number limit exceeded";
case CL_ERAR:
return "RAR module failure.";
return "RAR module failure";
case CL_EZIP:
return "Zip module failure.";
return "Zip module failure";
case CL_EMALFZIP:
return "Malformed Zip detected.";
return "Malformed Zip detected";
case CL_EGZIP:
return "GZip module failure.";
return "GZip module failure";
case CL_EMSCOMP:
return "MS Expand module failure.";
return "MS Expand module failure";
case CL_EMSCAB:
return "MS CAB module failure.";
return "MS CAB module failure";
case CL_EOLE2:
return "OLE2 module failure.";
return "OLE2 module failure";
case CL_ETMPFILE:
return "Unable to create temporary file.";
return "Unable to create temporary file";
case CL_ETMPDIR:
return "Unable to create temporary directory.";
return "Unable to create temporary directory";
case CL_EFSYNC:
return "Unable to synchronize file <-> disk.";
return "Unable to synchronize file <-> disk";
case CL_EMEM:
return "Unable to allocate memory.";
return "Unable to allocate memory";
case CL_EOPEN:
return "Unable to open file or directory.";
return "Unable to open file or directory";
case CL_EMALFDB:
return "Malformed database.";
return "Malformed database";
case CL_EPATSHORT:
return "Too short pattern detected.";
return "Too short pattern detected";
case CL_ECVD:
return "Broken or not a CVD file.";
return "Broken or not a CVD file";
case CL_ECVDEXTR:
return "CVD extraction failure.";
return "CVD extraction failure";
case CL_EMD5:
return "MD5 verification error.";
return "MD5 verification error";
case CL_EDSIG:
return "Digital signature verification error.";
return "Digital signature verification error";
case CL_ENULLARG:
return "Null argument passed while initialized is required.";
return "Null argument passed while initialized is required";
case CL_EIO:
return "Input/Output error";
default:
return "Unknown error code.";
return "Unknown error code";
}
}

View file

@ -109,7 +109,28 @@ struct pe_image_section_hdr {
uint32_t Characteristics;
};
int ddump(int desc, int offset, int size, const char *file)
static uint32_t cli_rawaddr(uint32_t rva, struct pe_image_section_hdr *shp, uint16_t nos)
{
int i, found = 0;
for(i = 0; i < nos; i++) {
if(shp[i].VirtualAddress <= rva && shp[i].VirtualAddress + shp[i].SizeOfRawData > rva) {
found = 1;
break;
}
}
if(!found) {
cli_dbgmsg("Can't calculate raw address from RVA 0x%x\n", rva);
return -1;
}
return rva - shp[i].VirtualAddress + shp[i].PointerToRawData;
}
static int cli_ddump(int desc, int offset, int size, const char *file)
{
int pos, ndesc, bread, sum = 0;
char buff[FILEBUFF];
@ -165,9 +186,10 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
{
uint16_t e_magic; /* DOS signature ("MZ") */
uint32_t e_lfanew; /* address of new exe header */
uint32_t ep; /* entry point (raw) */
struct pe_image_file_hdr file_hdr;
struct pe_image_optional_hdr optional_hdr;
struct pe_image_section_hdr section_hdr;
struct pe_image_section_hdr *section_hdr;
struct stat sb;
char sname[9];
int i;
@ -175,7 +197,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
cli_dbgmsg("Can't read DOS signature\n");
return -1;
return CL_EIO;
}
if(e_magic != IMAGE_DOS_SIGNATURE) {
@ -288,26 +310,34 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
cli_dbgmsg("NumberOfRvaAndSizes: %d\n", optional_hdr.NumberOfRvaAndSizes);
section_hdr = (struct pe_image_section_hdr *) cli_calloc(file_hdr.NumberOfSections, sizeof(struct pe_image_section_hdr));
if(!section_hdr) {
cli_dbgmsg("Can't allocate memory for section headers\n");
return CL_EMEM;
}
for(i = 0; i < file_hdr.NumberOfSections; i++) {
if(read(desc, &section_hdr, sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
cli_dbgmsg("Can't read section header\n");
free(section_hdr);
return -1;
}
strncpy(sname, section_hdr.Name, 8);
strncpy(sname, section_hdr[i].Name, 8);
sname[8] = 0;
cli_dbgmsg("------------------------------------\n");
cli_dbgmsg("Section name: %s\n", sname);
cli_dbgmsg("VirtualSize: %d\n", section_hdr.VirtualSize);
cli_dbgmsg("VirtualAddress: 0x%x\n", section_hdr.VirtualAddress);
cli_dbgmsg("Section size: %d\n", section_hdr.SizeOfRawData);
cli_dbgmsg("PointerToRawData: 0x%x (%d)\n", section_hdr.PointerToRawData, section_hdr.PointerToRawData);
cli_dbgmsg("VirtualSize: %d\n", section_hdr[i].VirtualSize);
cli_dbgmsg("VirtualAddress: 0x%x\n", section_hdr[i].VirtualAddress);
cli_dbgmsg("Section size: %d\n", section_hdr[i].SizeOfRawData);
cli_dbgmsg("PointerToRawData: 0x%x (%d)\n", section_hdr[i].PointerToRawData, section_hdr[i].PointerToRawData);
if(section_hdr.Characteristics & 0x20) {
if(section_hdr[i].Characteristics & 0x20) {
cli_dbgmsg("Section contains executable code\n");
if(section_hdr.VirtualSize < section_hdr.SizeOfRawData) {
if(section_hdr[i].VirtualSize < section_hdr[i].SizeOfRawData) {
cli_dbgmsg("Section contains free space\n");
/*
cli_dbgmsg("Dumping %d bytes\n", section_hdr.SizeOfRawData - section_hdr.VirtualSize);
@ -317,7 +347,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
}
}
if(section_hdr.Characteristics & 0x20000000)
if(section_hdr[i].Characteristics & 0x20000000)
cli_dbgmsg("Section's memory is executable\n");
/*
@ -333,15 +363,22 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
if(fstat(desc, &sb) == -1) {
cli_dbgmsg("fstat failed\n");
free(section_hdr);
return -1;
}
if(section_hdr.PointerToRawData + section_hdr.SizeOfRawData > sb.st_size) {
ep = cli_rawaddr(optional_hdr.AddressOfEntryPoint, section_hdr, file_hdr.NumberOfSections);
if(section_hdr[i].PointerToRawData + section_hdr[i].SizeOfRawData > sb.st_size || ep == -1) {
cli_warnmsg("Possibly broken PE file\n");
free(section_hdr);
return -1;
}
cli_dbgmsg("EntryPoint: 0x%x (%d)\n", ep, ep);
/* to be continued ... */
free(section_hdr);
return 0;
}