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... | ... |
@@ -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"); |
... | ... |
@@ -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, §ion_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, §ion_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 |