git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@600 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2004/06/12 05:17:18... | ... |
@@ -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 |
} |