Browse code

pe update

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
Showing 6 changed files
... ...
@@ -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
... ...
@@ -46,7 +46,7 @@ while test $# -gt 0; do
46 46
 	;;
47 47
 
48 48
     --version)
49
-	echo devel-20040606
49
+	echo devel-20040611
50 50
 	exit 0
51 51
 	;;
52 52
 
... ...
@@ -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, &section_hdr, sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
300
+	if(read(desc, &section_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
 }