git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@600 77e5149b-7576-45b1-b177-96237e5ba77b
| ... | ... |
@@ -1,3 +1,7 @@ |
| 1 |
+Fri Jun 11 22:11:31 CEST 2004 (tk) |
|
| 2 |
+---------------------------------- |
|
| 3 |
+ * libclamav: pe: add dumper; RVA calculation; fix error codes |
|
| 4 |
+ |
|
| 1 | 5 |
Wed Jun 9 17:47:29 CEST 2004 (tk) |
| 2 | 6 |
---------------------------------- |
| 3 | 7 |
* clamd: do not display "Command parser: read() failed." (in SESSION mode) |
| ... | ... |
@@ -1,4 +1,4 @@ |
| 1 |
-# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*- |
|
| 1 |
+# aclocal.m4t generated automatically by aclocal 1.6.1 -*- Autoconf -*- |
|
| 2 | 2 |
|
| 3 | 3 |
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
| 4 | 4 |
# Free Software Foundation, Inc. |
| ... | ... |
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for |
| 81 | 81 |
dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created |
| 82 | 82 |
dnl (the prefix is a bit different, since we add an extra -target- and -host-) |
| 83 | 83 |
dnl |
| 84 |
-dnl @version: $Id: aclocal.m4,v 1.40 2004/06/06 01:50:08 kojm Exp $ |
|
| 84 |
+dnl @version: $Id: aclocal.m4,v 1.41 2004/06/11 20:17:18 kojm Exp $ |
|
| 85 | 85 |
dnl @author Guido Draheim <guidod@gmx.de> STATUS: used often |
| 86 | 86 |
|
| 87 | 87 |
AC_DEFUN([AC_CREATE_TARGET_H], |
| ... | ... |
@@ -4041,7 +4041,7 @@ dnl AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers) |
| 4041 | 4041 |
dnl AC_COMPILE_CHECK_SIZEOF(off_t, $headers) |
| 4042 | 4042 |
dnl |
| 4043 | 4043 |
dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu> |
| 4044 |
-dnl @version $Id: aclocal.m4,v 1.40 2004/06/06 01:50:08 kojm Exp $ |
|
| 4044 |
+dnl @version $Id: aclocal.m4,v 1.41 2004/06/11 20:17:18 kojm Exp $ |
|
| 4045 | 4045 |
dnl |
| 4046 | 4046 |
AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], |
| 4047 | 4047 |
[changequote(<<, >>)dnl |
| ... | ... |
@@ -64,6 +64,7 @@ extern "C" |
| 64 | 64 |
#define CL_ECVDEXTR -9 /* CVD extraction failure */ |
| 65 | 65 |
#define CL_EMD5 -10 /* MD5 verification error */ |
| 66 | 66 |
#define CL_EDSIG -11 /* digital signature verification error */ |
| 67 |
+#define CL_EIO -12 /* general I/O error */ |
|
| 67 | 68 |
|
| 68 | 69 |
/* options */ |
| 69 | 70 |
#define CL_RAW 0 |
| ... | ... |
@@ -103,55 +103,57 @@ const char *cl_strerror(int clerror) |
| 103 | 103 |
{
|
| 104 | 104 |
switch(clerror) {
|
| 105 | 105 |
case CL_CLEAN: |
| 106 |
- return "Virus NOT found."; |
|
| 106 |
+ return "No viruses detected"; |
|
| 107 | 107 |
case CL_VIRUS: |
| 108 |
- return "Virus(es) detected."; |
|
| 108 |
+ return "Virus(es) detected"; |
|
| 109 | 109 |
case CL_EMAXREC: |
| 110 |
- return "Recursion limit exceeded."; |
|
| 110 |
+ return "Recursion limit exceeded"; |
|
| 111 | 111 |
case CL_EMAXSIZE: |
| 112 |
- return "File size limit exceeded."; |
|
| 112 |
+ return "File size limit exceeded"; |
|
| 113 | 113 |
case CL_EMAXFILES: |
| 114 |
- return "Files number limit exceeded."; |
|
| 114 |
+ return "Files number limit exceeded"; |
|
| 115 | 115 |
case CL_ERAR: |
| 116 |
- return "RAR module failure."; |
|
| 116 |
+ return "RAR module failure"; |
|
| 117 | 117 |
case CL_EZIP: |
| 118 |
- return "Zip module failure."; |
|
| 118 |
+ return "Zip module failure"; |
|
| 119 | 119 |
case CL_EMALFZIP: |
| 120 |
- return "Malformed Zip detected."; |
|
| 120 |
+ return "Malformed Zip detected"; |
|
| 121 | 121 |
case CL_EGZIP: |
| 122 |
- return "GZip module failure."; |
|
| 122 |
+ return "GZip module failure"; |
|
| 123 | 123 |
case CL_EMSCOMP: |
| 124 |
- return "MS Expand module failure."; |
|
| 124 |
+ return "MS Expand module failure"; |
|
| 125 | 125 |
case CL_EMSCAB: |
| 126 |
- return "MS CAB module failure."; |
|
| 126 |
+ return "MS CAB module failure"; |
|
| 127 | 127 |
case CL_EOLE2: |
| 128 |
- return "OLE2 module failure."; |
|
| 128 |
+ return "OLE2 module failure"; |
|
| 129 | 129 |
case CL_ETMPFILE: |
| 130 |
- return "Unable to create temporary file."; |
|
| 130 |
+ return "Unable to create temporary file"; |
|
| 131 | 131 |
case CL_ETMPDIR: |
| 132 |
- return "Unable to create temporary directory."; |
|
| 132 |
+ return "Unable to create temporary directory"; |
|
| 133 | 133 |
case CL_EFSYNC: |
| 134 |
- return "Unable to synchronize file <-> disk."; |
|
| 134 |
+ return "Unable to synchronize file <-> disk"; |
|
| 135 | 135 |
case CL_EMEM: |
| 136 |
- return "Unable to allocate memory."; |
|
| 136 |
+ return "Unable to allocate memory"; |
|
| 137 | 137 |
case CL_EOPEN: |
| 138 |
- return "Unable to open file or directory."; |
|
| 138 |
+ return "Unable to open file or directory"; |
|
| 139 | 139 |
case CL_EMALFDB: |
| 140 |
- return "Malformed database."; |
|
| 140 |
+ return "Malformed database"; |
|
| 141 | 141 |
case CL_EPATSHORT: |
| 142 |
- return "Too short pattern detected."; |
|
| 142 |
+ return "Too short pattern detected"; |
|
| 143 | 143 |
case CL_ECVD: |
| 144 |
- return "Broken or not a CVD file."; |
|
| 144 |
+ return "Broken or not a CVD file"; |
|
| 145 | 145 |
case CL_ECVDEXTR: |
| 146 |
- return "CVD extraction failure."; |
|
| 146 |
+ return "CVD extraction failure"; |
|
| 147 | 147 |
case CL_EMD5: |
| 148 |
- return "MD5 verification error."; |
|
| 148 |
+ return "MD5 verification error"; |
|
| 149 | 149 |
case CL_EDSIG: |
| 150 |
- return "Digital signature verification error."; |
|
| 150 |
+ return "Digital signature verification error"; |
|
| 151 | 151 |
case CL_ENULLARG: |
| 152 |
- return "Null argument passed while initialized is required."; |
|
| 152 |
+ return "Null argument passed while initialized is required"; |
|
| 153 |
+ case CL_EIO: |
|
| 154 |
+ return "Input/Output error"; |
|
| 153 | 155 |
default: |
| 154 |
- return "Unknown error code."; |
|
| 156 |
+ return "Unknown error code"; |
|
| 155 | 157 |
} |
| 156 | 158 |
} |
| 157 | 159 |
|
| ... | ... |
@@ -109,7 +109,28 @@ struct pe_image_section_hdr {
|
| 109 | 109 |
uint32_t Characteristics; |
| 110 | 110 |
}; |
| 111 | 111 |
|
| 112 |
-int ddump(int desc, int offset, int size, const char *file) |
|
| 112 |
+ |
|
| 113 |
+static uint32_t cli_rawaddr(uint32_t rva, struct pe_image_section_hdr *shp, uint16_t nos) |
|
| 114 |
+{
|
|
| 115 |
+ int i, found = 0; |
|
| 116 |
+ |
|
| 117 |
+ |
|
| 118 |
+ for(i = 0; i < nos; i++) {
|
|
| 119 |
+ if(shp[i].VirtualAddress <= rva && shp[i].VirtualAddress + shp[i].SizeOfRawData > rva) {
|
|
| 120 |
+ found = 1; |
|
| 121 |
+ break; |
|
| 122 |
+ } |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ if(!found) {
|
|
| 126 |
+ cli_dbgmsg("Can't calculate raw address from RVA 0x%x\n", rva);
|
|
| 127 |
+ return -1; |
|
| 128 |
+ } |
|
| 129 |
+ |
|
| 130 |
+ return rva - shp[i].VirtualAddress + shp[i].PointerToRawData; |
|
| 131 |
+} |
|
| 132 |
+ |
|
| 133 |
+static int cli_ddump(int desc, int offset, int size, const char *file) |
|
| 113 | 134 |
{
|
| 114 | 135 |
int pos, ndesc, bread, sum = 0; |
| 115 | 136 |
char buff[FILEBUFF]; |
| ... | ... |
@@ -165,9 +186,10 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
| 165 | 165 |
{
|
| 166 | 166 |
uint16_t e_magic; /* DOS signature ("MZ") */
|
| 167 | 167 |
uint32_t e_lfanew; /* address of new exe header */ |
| 168 |
+ uint32_t ep; /* entry point (raw) */ |
|
| 168 | 169 |
struct pe_image_file_hdr file_hdr; |
| 169 | 170 |
struct pe_image_optional_hdr optional_hdr; |
| 170 |
- struct pe_image_section_hdr section_hdr; |
|
| 171 |
+ struct pe_image_section_hdr *section_hdr; |
|
| 171 | 172 |
struct stat sb; |
| 172 | 173 |
char sname[9]; |
| 173 | 174 |
int i; |
| ... | ... |
@@ -175,7 +197,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
| 175 | 175 |
|
| 176 | 176 |
if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
|
| 177 | 177 |
cli_dbgmsg("Can't read DOS signature\n");
|
| 178 |
- return -1; |
|
| 178 |
+ return CL_EIO; |
|
| 179 | 179 |
} |
| 180 | 180 |
|
| 181 | 181 |
if(e_magic != IMAGE_DOS_SIGNATURE) {
|
| ... | ... |
@@ -288,26 +310,34 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
| 288 | 288 |
|
| 289 | 289 |
cli_dbgmsg("NumberOfRvaAndSizes: %d\n", optional_hdr.NumberOfRvaAndSizes);
|
| 290 | 290 |
|
| 291 |
+ section_hdr = (struct pe_image_section_hdr *) cli_calloc(file_hdr.NumberOfSections, sizeof(struct pe_image_section_hdr)); |
|
| 292 |
+ |
|
| 293 |
+ if(!section_hdr) {
|
|
| 294 |
+ cli_dbgmsg("Can't allocate memory for section headers\n");
|
|
| 295 |
+ return CL_EMEM; |
|
| 296 |
+ } |
|
| 297 |
+ |
|
| 291 | 298 |
for(i = 0; i < file_hdr.NumberOfSections; i++) {
|
| 292 | 299 |
|
| 293 |
- if(read(desc, §ion_hdr, sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
|
|
| 300 |
+ if(read(desc, §ion_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
|
|
| 294 | 301 |
cli_dbgmsg("Can't read section header\n");
|
| 302 |
+ free(section_hdr); |
|
| 295 | 303 |
return -1; |
| 296 | 304 |
} |
| 297 | 305 |
|
| 298 |
- strncpy(sname, section_hdr.Name, 8); |
|
| 306 |
+ strncpy(sname, section_hdr[i].Name, 8); |
|
| 299 | 307 |
sname[8] = 0; |
| 300 | 308 |
cli_dbgmsg("------------------------------------\n");
|
| 301 | 309 |
cli_dbgmsg("Section name: %s\n", sname);
|
| 302 |
- cli_dbgmsg("VirtualSize: %d\n", section_hdr.VirtualSize);
|
|
| 303 |
- cli_dbgmsg("VirtualAddress: 0x%x\n", section_hdr.VirtualAddress);
|
|
| 304 |
- cli_dbgmsg("Section size: %d\n", section_hdr.SizeOfRawData);
|
|
| 305 |
- cli_dbgmsg("PointerToRawData: 0x%x (%d)\n", section_hdr.PointerToRawData, section_hdr.PointerToRawData);
|
|
| 310 |
+ cli_dbgmsg("VirtualSize: %d\n", section_hdr[i].VirtualSize);
|
|
| 311 |
+ cli_dbgmsg("VirtualAddress: 0x%x\n", section_hdr[i].VirtualAddress);
|
|
| 312 |
+ cli_dbgmsg("Section size: %d\n", section_hdr[i].SizeOfRawData);
|
|
| 313 |
+ cli_dbgmsg("PointerToRawData: 0x%x (%d)\n", section_hdr[i].PointerToRawData, section_hdr[i].PointerToRawData);
|
|
| 306 | 314 |
|
| 307 |
- if(section_hdr.Characteristics & 0x20) {
|
|
| 315 |
+ if(section_hdr[i].Characteristics & 0x20) {
|
|
| 308 | 316 |
cli_dbgmsg("Section contains executable code\n");
|
| 309 | 317 |
|
| 310 |
- if(section_hdr.VirtualSize < section_hdr.SizeOfRawData) {
|
|
| 318 |
+ if(section_hdr[i].VirtualSize < section_hdr[i].SizeOfRawData) {
|
|
| 311 | 319 |
cli_dbgmsg("Section contains free space\n");
|
| 312 | 320 |
/* |
| 313 | 321 |
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 |
| 317 | 317 |
} |
| 318 | 318 |
} |
| 319 | 319 |
|
| 320 |
- if(section_hdr.Characteristics & 0x20000000) |
|
| 320 |
+ if(section_hdr[i].Characteristics & 0x20000000) |
|
| 321 | 321 |
cli_dbgmsg("Section's memory is executable\n");
|
| 322 | 322 |
|
| 323 | 323 |
/* |
| ... | ... |
@@ -333,15 +363,22 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c |
| 333 | 333 |
|
| 334 | 334 |
if(fstat(desc, &sb) == -1) {
|
| 335 | 335 |
cli_dbgmsg("fstat failed\n");
|
| 336 |
+ free(section_hdr); |
|
| 336 | 337 |
return -1; |
| 337 | 338 |
} |
| 338 | 339 |
|
| 339 |
- if(section_hdr.PointerToRawData + section_hdr.SizeOfRawData > sb.st_size) {
|
|
| 340 |
+ ep = cli_rawaddr(optional_hdr.AddressOfEntryPoint, section_hdr, file_hdr.NumberOfSections); |
|
| 341 |
+ |
|
| 342 |
+ if(section_hdr[i].PointerToRawData + section_hdr[i].SizeOfRawData > sb.st_size || ep == -1) {
|
|
| 340 | 343 |
cli_warnmsg("Possibly broken PE file\n");
|
| 344 |
+ free(section_hdr); |
|
| 341 | 345 |
return -1; |
| 342 | 346 |
} |
| 343 | 347 |
|
| 348 |
+ cli_dbgmsg("EntryPoint: 0x%x (%d)\n", ep, ep);
|
|
| 349 |
+ |
|
| 344 | 350 |
/* to be continued ... */ |
| 345 | 351 |
|
| 352 |
+ free(section_hdr); |
|
| 346 | 353 |
return 0; |
| 347 | 354 |
} |