Phase 2 of gathering PE section hash data

0.98.2
Shawn Webb 12 years ago
parent c9dd1aaaa8
commit 7db9ec7452
  1. 2
      libclamav/json.c
  2. 100
      libclamav/pe.c

@ -192,7 +192,5 @@ char *export_stats_to_json(struct cl_engine *engine, cli_intel_t *intel)
snprintf(buf+curused, bufsz-curused, "\t]\n}\n");
cli_warnmsg("JSON object:\n%s\n", buf);
return buf;
}

@ -2886,9 +2886,6 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
dirs = optional_hdr64.DataDirectory;
}
if(!cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, 2) && dirs[4].Size < 8)
return CL_BREAK;
fsize = map->len;
valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
@ -2946,8 +2943,19 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
cli_qsort(exe_sections, nsections, sizeof(*exe_sections), sort_sects);
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE)
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
/* Check to see if we have a security section. */
if(!cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, 2) && dirs[4].Size < 8) {
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
/* If stats is enabled, continue parsing the sample */
flags ^= CL_CHECKFP_PE_FLAG_AUTHENTICODE;
} else {
return CL_BREAK;
}
}
SHA1Init(&sha1);
}
#define hash_chunk(where, size, isStatAble, section) \
do { \
@ -2967,50 +2975,70 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
} \
} while(0)
/* MZ to checksum */
at = 0;
hlen = e_lfanew + sizeof(struct pe_image_file_hdr) + (pe_plus ? offsetof(struct pe_image_optional_hdr64, CheckSum) : offsetof(struct pe_image_optional_hdr32, CheckSum));
hash_chunk(0, hlen, 0, 0);
at = hlen + 4;
while (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
/* MZ to checksum */
at = 0;
hlen = e_lfanew + sizeof(struct pe_image_file_hdr) + (pe_plus ? offsetof(struct pe_image_optional_hdr64, CheckSum) : offsetof(struct pe_image_optional_hdr32, CheckSum));
hash_chunk(0, hlen, 0, 0);
at = hlen + 4;
/* Checksum to security */
if(pe_plus)
hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4;
else
hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4;
hash_chunk(at, hlen, 0, 0);
at += hlen + 8;
/* Checksum to security */
if(pe_plus)
hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4;
else
hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4;
hash_chunk(at, hlen, 0, 0);
at += hlen + 8;
if(at > hdr_size) {
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
flags ^= CL_CHECKFP_PE_FLAG_AUTHENTICODE;
break;
} else {
free(exe_sections);
return CL_EFORMAT;
}
}
if(at > hdr_size) {
free(exe_sections);
return CL_EFORMAT;
}
/* Security to End of header */
hlen = hdr_size - at;
hash_chunk(at, hlen, 0, 0);
/* Security to End of header */
hlen = hdr_size - at;
hash_chunk(at, hlen, 0, 0);
at = hdr_size;
break;
}
/* Sections */
at = hdr_size;
/* Hash the sections */
for(i = 0; i < nsections; i++) {
if(!exe_sections[i].rsz)
continue;
hash_chunk(exe_sections[i].raw, exe_sections[i].rsz, 1, i);
at += exe_sections[i].rsz;
}
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE)
at += exe_sections[i].rsz;
}
while (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
if(at < fsize) {
hlen = fsize - at;
if(dirs[4].Size > hlen) {
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
flags ^= CL_CHECKFP_PE_FLAG_AUTHENTICODE;
break;
} else {
free(exe_sections);
return CL_EFORMAT;
}
}
if(at < fsize) {
hlen = fsize - at;
if(dirs[4].Size > hlen) {
free(exe_sections);
return CL_EFORMAT;
hlen -= dirs[4].Size;
hash_chunk(at, hlen, 0, 0);
at += hlen;
}
hlen -= dirs[4].Size;
hash_chunk(at, hlen, 0, 0);
at += hlen;
}
break;
} while (0);
free(exe_sections);
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {

Loading…
Cancel
Save