Browse code

include new function cli_peheader(); fix crash when bm_shift is not initialised

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@804 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2004/08/27 09:19:44
Showing 5 changed files
... ...
@@ -1,3 +1,9 @@
1
+Fri Aug 27 02:14:07 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav/pe.c: include new function cli_peheader() (only dumps specific
4
+		    values from PE files)
5
+  * libclamav/matcher-bm.c: fix crash when bm_shift is not initialised
6
+
1 7
 Thu Aug 26 15:17:03 BST 2004 (trog)
2 8
 -----------------------------------
3 9
   * libclamav/ole2_extract.c: sanitize filenames
... ...
@@ -269,10 +269,8 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
269 269
         unsigned int i;
270 270
 
271 271
 
272
-    if(!root->ac_root) {
273
-	cli_dbgmsg("cli_ac_scanbuff: Pattern matcher not initialised\n");
272
+    if(!root->ac_root)
274 273
 	return CL_CLEAN;
275
-    }
276 274
 
277 275
     if(!partcnt || !partoff) {
278 276
 	cli_dbgmsg("cli_ac_scanbuff(): partcnt == NULL || partoff == NULL\n");
... ...
@@ -124,6 +124,9 @@ int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virnam
124 124
 	char prefix;
125 125
 
126 126
 
127
+    if(!root->bm_shift)
128
+	return CL_CLEAN;
129
+
127 130
     if(length < BM_MIN_LENGTH)
128 131
 	return CL_CLEAN;
129 132
 
... ...
@@ -299,6 +299,11 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
299 299
     cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr.NumberOfRvaAndSizes));
300 300
     cli_dbgmsg("------------------------------------\n");
301 301
 
302
+    if(fstat(desc, &sb) == -1) {
303
+	cli_dbgmsg("fstat failed\n");
304
+	return CL_EIO;
305
+    }
306
+
302 307
     section_hdr = (struct pe_image_section_hdr *) cli_calloc(nsections, sizeof(struct pe_image_section_hdr));
303 308
 
304 309
     if(!section_hdr) {
... ...
@@ -306,12 +311,6 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
306 306
 	return CL_EMEM;
307 307
     }
308 308
 
309
-    if(fstat(desc, &sb) == -1) {
310
-	cli_dbgmsg("fstat failed\n");
311
-	free(section_hdr);
312
-	return CL_EIO;
313
-    }
314
-
315 309
     for(i = 0; i < nsections; i++) {
316 310
 
317 311
 	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
... ...
@@ -1182,3 +1181,132 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
1182 1182
     free(section_hdr);
1183 1183
     return CL_CLEAN;
1184 1184
 }
1185
+
1186
+int cli_peheader(int desc, struct cli_pe_info **peinfo)
1187
+{
1188
+	uint16_t e_magic; /* DOS signature ("MZ") */
1189
+	uint32_t e_lfanew; /* address of new exe header */
1190
+	struct pe_image_file_hdr file_hdr;
1191
+	struct pe_image_optional_hdr optional_hdr;
1192
+	struct pe_image_section_hdr *section_hdr;
1193
+	struct stat sb;
1194
+	struct cli_pe_info *info;
1195
+	int i;
1196
+
1197
+
1198
+    cli_dbgmsg("in cli_peheader\n");
1199
+
1200
+    if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
1201
+	cli_dbgmsg("Can't read DOS signature\n");
1202
+	return -1;
1203
+    }
1204
+
1205
+    if(EC16(e_magic) != IMAGE_DOS_SIGNATURE && EC16(e_magic) != IMAGE_DOS_SIGNATURE_OLD) {
1206
+	cli_dbgmsg("Invalid DOS signature\n");
1207
+	return -1;
1208
+    }
1209
+
1210
+    lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
1211
+
1212
+    if(read(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
1213
+	cli_dbgmsg("Can't read new header address\n");
1214
+	/* truncated header? */
1215
+	return -1;
1216
+    }
1217
+
1218
+    e_lfanew = EC32(e_lfanew);
1219
+    if(!e_lfanew) {
1220
+	cli_dbgmsg("Not a PE file\n");
1221
+	return -1;
1222
+    }
1223
+
1224
+    if(lseek(desc, e_lfanew, SEEK_SET) < 0) {
1225
+	/* probably not a PE file */
1226
+	cli_dbgmsg("Can't lseek to e_lfanew\n");
1227
+	return -1;
1228
+    }
1229
+
1230
+    if(read(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
1231
+	/* bad information in e_lfanew - probably not a PE file */
1232
+	cli_dbgmsg("Can't read file header\n");
1233
+	return -1;
1234
+    }
1235
+
1236
+    if(EC32(file_hdr.Magic) != IMAGE_NT_SIGNATURE) {
1237
+	cli_dbgmsg("Invalid PE signature (probably NE file)\n");
1238
+	return -1;
1239
+    }
1240
+
1241
+    if(EC16(file_hdr.SizeOfOptionalHeader) != sizeof(struct pe_image_optional_hdr)) {
1242
+	cli_warnmsg("Broken PE header detected.\n");
1243
+	return -1;
1244
+    }
1245
+
1246
+    if(!(info = cli_calloc(1, sizeof(struct cli_pe_info)))) {
1247
+	cli_dbgmsg("Can't alloc memory\n");
1248
+	return -1;
1249
+    }
1250
+
1251
+    info->nsections = EC16(file_hdr.NumberOfSections);
1252
+
1253
+    if(read(desc, &optional_hdr, sizeof(struct pe_image_optional_hdr)) != sizeof(struct pe_image_optional_hdr)) {
1254
+	cli_dbgmsg("Can't optional file header\n");
1255
+	free(info);
1256
+	return -1;
1257
+    }
1258
+
1259
+    info->section = (struct SECTION *) cli_calloc(info->nsections, sizeof(struct SECTION));
1260
+
1261
+    if(!info->section) {
1262
+	cli_dbgmsg("Can't allocate memory for section headers\n");
1263
+	free(info);
1264
+	return -1;
1265
+    }
1266
+
1267
+    if(fstat(desc, &sb) == -1) {
1268
+	cli_dbgmsg("fstat failed\n");
1269
+	free(info->section);
1270
+	free(info);
1271
+	return -1;
1272
+    }
1273
+
1274
+    section_hdr = (struct pe_image_section_hdr *) cli_calloc(info->nsections, sizeof(struct pe_image_section_hdr));
1275
+
1276
+    if(!section_hdr) {
1277
+	cli_dbgmsg("Can't allocate memory for section headers\n");
1278
+	free(info->section);
1279
+	free(info);
1280
+	return -1;
1281
+    }
1282
+
1283
+    for(i = 0; i < info->nsections; i++) {
1284
+
1285
+	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
1286
+	    cli_dbgmsg("Can't read section header\n");
1287
+	    cli_dbgmsg("Possibly broken PE file\n");
1288
+	    free(section_hdr);
1289
+	    free(info->section);
1290
+	    free(info);
1291
+	    return -1;
1292
+	}
1293
+
1294
+	info->section[i].rva = EC32(section_hdr[i].VirtualAddress);
1295
+	info->section[i].vsz = EC32(section_hdr[i].VirtualSize);
1296
+	info->section[i].raw = EC32(section_hdr[i].PointerToRawData);
1297
+	info->section[i].rsz = EC32(section_hdr[i].SizeOfRawData);
1298
+
1299
+    }
1300
+
1301
+    if((info->ep = cli_rawaddr(EC32(optional_hdr.AddressOfEntryPoint), section_hdr, info->nsections)) == -1) {
1302
+	cli_dbgmsg("Possibly broken PE file\n");
1303
+	free(section_hdr);
1304
+	free(info->section);
1305
+	free(info);
1306
+	return -1;
1307
+    }
1308
+
1309
+    free(section_hdr);
1310
+    *peinfo = info;
1311
+
1312
+    return 0;
1313
+}
... ...
@@ -23,6 +23,7 @@
23 23
 #define __PE_H
24 24
 
25 25
 #include "clamav.h"
26
+#include "rebuildpe.h"
26 27
 
27 28
 struct pe_image_file_hdr {
28 29
     uint32_t Magic;
... ...
@@ -93,6 +94,14 @@ struct pe_image_section_hdr {
93 93
     uint32_t Characteristics;
94 94
 };
95 95
 
96
+struct cli_pe_info {
97
+    uint32_t ep; /* raw entry point */
98
+    uint16_t nsections;
99
+    struct SECTION *section;
100
+};
101
+
96 102
 int cli_scanpe(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *arec, int *mrec);
97 103
 
104
+int cli_peheader(int desc, struct cli_pe_info **peinfo);
105
+
98 106
 #endif