mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 18:33:16 +00:00
Use genhash_pe instead of checkfp_pe for section hash computation
cli_checkfp_pe is now effectively the function that just checks the Authenticode hash. This makes the code less complicated, and adds some minor improvements: - section hashes are no longer computed if there is no stats callback function (at least in that part of the code) - We now actually set the len field in the stats_section_t structure - If an error occurs when computing a section hash, we skip that section instead of not computing any hashes
This commit is contained in:
parent
ef24839531
commit
14d52d0c63
4 changed files with 102 additions and 133 deletions
|
@ -567,7 +567,6 @@ int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const ch
|
||||||
uint8_t shash1[SHA1_HASH_SIZE * 2 + 1];
|
uint8_t shash1[SHA1_HASH_SIZE * 2 + 1];
|
||||||
uint8_t shash256[SHA256_HASH_SIZE * 2 + 1];
|
uint8_t shash256[SHA256_HASH_SIZE * 2 + 1];
|
||||||
int have_sha1, have_sha256, do_dsig_check = 1;
|
int have_sha1, have_sha256, do_dsig_check = 1;
|
||||||
stats_section_t sections;
|
|
||||||
|
|
||||||
if (cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) {
|
if (cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) {
|
||||||
cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s), size: %d\n", virname, (int)size);
|
cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s), size: %d\n", virname, (int)size);
|
||||||
|
@ -585,6 +584,8 @@ int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const ch
|
||||||
vname ? vname : "Name");
|
vname ? vname : "Name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Replace this with the ability to actually perform detection with
|
||||||
|
// the blacklisted sig entries
|
||||||
if (vname)
|
if (vname)
|
||||||
do_dsig_check = strncmp("W32S.", vname, 5);
|
do_dsig_check = strncmp("W32S.", vname, 5);
|
||||||
|
|
||||||
|
@ -652,17 +653,10 @@ int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const ch
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(§ions, 0x00, sizeof(stats_section_t));
|
if (do_dsig_check) {
|
||||||
if (do_dsig_check || ctx->engine->cb_stats_add_sample) {
|
switch (cli_checkfp_pe(ctx)) {
|
||||||
uint32_t flags = (do_dsig_check ? CL_CHECKFP_PE_FLAG_AUTHENTICODE : 0);
|
|
||||||
if (!(ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_PE_STATS) && !(ctx->engine->dconf->stats & (DCONF_STATS_DISABLED | DCONF_STATS_PE_SECTION_DISABLED)))
|
|
||||||
flags |= CL_CHECKFP_PE_FLAG_STATS;
|
|
||||||
|
|
||||||
switch (cli_checkfp_pe(ctx, §ions, flags)) {
|
|
||||||
case CL_CLEAN:
|
case CL_CLEAN:
|
||||||
cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid digital signature\n");
|
cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid digital signature\n");
|
||||||
if (sections.sections)
|
|
||||||
free(sections.sections);
|
|
||||||
return CL_CLEAN;
|
return CL_CLEAN;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -672,11 +666,22 @@ int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const ch
|
||||||
if (ctx->engine->cb_hash)
|
if (ctx->engine->cb_hash)
|
||||||
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, vname ? vname : "noname", ctx->cb_ctx);
|
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, vname ? vname : "noname", ctx->cb_ctx);
|
||||||
|
|
||||||
if (ctx->engine->cb_stats_add_sample)
|
if (ctx->engine->cb_stats_add_sample) {
|
||||||
|
stats_section_t sections;
|
||||||
|
memset(§ions, 0x00, sizeof(stats_section_t));
|
||||||
|
|
||||||
|
if (!(ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_PE_STATS) &&
|
||||||
|
!(ctx->engine->dconf->stats & (DCONF_STATS_DISABLED | DCONF_STATS_PE_SECTION_DISABLED)))
|
||||||
|
cli_genhash_pe(ctx, CL_GENHASH_PE_CLASS_SECTION, 1, §ions);
|
||||||
|
|
||||||
|
// TODO We probably only want to call cb_stats_add_sample when
|
||||||
|
// sections.section != NULL... leaving as is for now
|
||||||
ctx->engine->cb_stats_add_sample(vname ? vname : "noname", digest, size, §ions, ctx->engine->stats_data);
|
ctx->engine->cb_stats_add_sample(vname ? vname : "noname", digest, size, §ions, ctx->engine->stats_data);
|
||||||
|
|
||||||
if (sections.sections)
|
if (sections.sections) {
|
||||||
free(sections.sections);
|
free(sections.sections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CL_VIRUS;
|
return CL_VIRUS;
|
||||||
}
|
}
|
||||||
|
|
191
libclamav/pe.c
191
libclamav/pe.c
|
@ -5508,29 +5508,8 @@ static int sort_sects(const void *first, const void *second)
|
||||||
* CL_CLEAN will be returned if the file was whitelisted based on its
|
* CL_CLEAN will be returned if the file was whitelisted based on its
|
||||||
* signature. CL_VIRUS will be returned if the file was blacklisted based on
|
* signature. CL_VIRUS will be returned if the file was blacklisted based on
|
||||||
* its signature. Otherwise, an cl_error_t error value will be returned.
|
* its signature. Otherwise, an cl_error_t error value will be returned.
|
||||||
*
|
*/
|
||||||
* Also, this function computes the hashes of each section (sorted based on the
|
cl_error_t cli_checkfp_pe(cli_ctx *ctx)
|
||||||
* RVAs of the sections) if the CL_CHECKFP_PE_FLAG_STATS flag exists in flags
|
|
||||||
*
|
|
||||||
* TODO The code to compute the section hashes is copied from
|
|
||||||
* cli_genhash_pe - we should use that function instead where this
|
|
||||||
* functionality is needed, since we no longer need to compute the section
|
|
||||||
* hashes as part of the authenticode hash calculation.
|
|
||||||
*
|
|
||||||
* If the section hashes are to be computed and returned, this function
|
|
||||||
* allocates memory for the section hashes, and it's up to the caller to free
|
|
||||||
* it. hashes->sections will be initialized to NULL at the beginning of the
|
|
||||||
* function, and if after the call it's value is non-NULL, the memory should be
|
|
||||||
* freed. Furthermore, if hashes->sections is non-NULL, the hashes can assume
|
|
||||||
* to be valid regardless of the return code.
|
|
||||||
*
|
|
||||||
* Also, a few other notes:
|
|
||||||
* - If a section has a virtual size of zero, it's corresponding hash value
|
|
||||||
* will not be computed and the hash contents will be all zeroes.
|
|
||||||
* - TODO Instead of not providing back any hashes when an invalid section is
|
|
||||||
* encountered, would it be better to still compute hashes for the valid
|
|
||||||
* sections? */
|
|
||||||
cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
|
||||||
{
|
{
|
||||||
size_t at;
|
size_t at;
|
||||||
unsigned int i, hlen;
|
unsigned int i, hlen;
|
||||||
|
@ -5554,15 +5533,6 @@ cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
||||||
if (!(DCONF & PE_CONF_CATALOG))
|
if (!(DCONF & PE_CONF_CATALOG))
|
||||||
return CL_EFORMAT;
|
return CL_EFORMAT;
|
||||||
|
|
||||||
if (flags == CL_CHECKFP_PE_FLAG_NONE)
|
|
||||||
return CL_BREAK;
|
|
||||||
|
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
|
|
||||||
if (!(hashes))
|
|
||||||
return CL_ENULLARG;
|
|
||||||
hashes->sections = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO see if peinfo can be passed in (or lives in ctx or something) and
|
// TODO see if peinfo can be passed in (or lives in ctx or something) and
|
||||||
// if so, use that to avoid having to re-parse the header
|
// if so, use that to avoid having to re-parse the header
|
||||||
cli_exe_info_init(peinfo, 0);
|
cli_exe_info_init(peinfo, 0);
|
||||||
|
@ -5579,68 +5549,12 @@ cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
||||||
// the section hashes), bail out if we don't have any Authenticode hashes
|
// the section hashes), bail out if we don't have any Authenticode hashes
|
||||||
// loaded from .cat files
|
// loaded from .cat files
|
||||||
if (sec_dir_size < 8 && !cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, 2)) {
|
if (sec_dir_size < 8 && !cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, 2)) {
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
|
cli_exe_info_destroy(peinfo);
|
||||||
/* If stats is enabled, continue parsing the sample */
|
return CL_BREAK;
|
||||||
flags ^= CL_CHECKFP_PE_FLAG_AUTHENTICODE;
|
|
||||||
} else {
|
|
||||||
cli_exe_info_destroy(peinfo);
|
|
||||||
return CL_BREAK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fsize = map->len;
|
fsize = map->len;
|
||||||
|
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
|
do {
|
||||||
hashes->nsections = peinfo->nsections;
|
|
||||||
hashes->sections = cli_calloc(peinfo->nsections, sizeof(struct cli_section_hash));
|
|
||||||
;
|
|
||||||
if (!(hashes->sections)) {
|
|
||||||
cli_exe_info_destroy(peinfo);
|
|
||||||
return CL_EMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define free_section_hashes() \
|
|
||||||
do { \
|
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_STATS) { \
|
|
||||||
free(hashes->sections); \
|
|
||||||
hashes->sections = NULL; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// TODO This likely isn't needed anymore, since we no longer compute
|
|
||||||
// the authenticode hash like the 2008 spec doc says (sort sections
|
|
||||||
// and use the section info to compute the hash)
|
|
||||||
cli_qsort(peinfo->sections, peinfo->nsections, sizeof(*peinfo->sections), sort_sects);
|
|
||||||
|
|
||||||
/* Hash the sections */
|
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
|
|
||||||
|
|
||||||
for (i = 0; i < peinfo->nsections; i++) {
|
|
||||||
const uint8_t *hptr;
|
|
||||||
void *md5ctx;
|
|
||||||
|
|
||||||
if (!peinfo->sections[i].rsz)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(hptr = fmap_need_off_once(map, peinfo->sections[i].raw, peinfo->sections[i].rsz))) {
|
|
||||||
cli_exe_info_destroy(peinfo);
|
|
||||||
free_section_hashes();
|
|
||||||
return CL_EFORMAT;
|
|
||||||
}
|
|
||||||
md5ctx = cl_hash_init("md5");
|
|
||||||
if (md5ctx) {
|
|
||||||
cl_update_hash(md5ctx, (void *)hptr, peinfo->sections[i].rsz);
|
|
||||||
cl_finish_hash(md5ctx, hashes->sections[i].md5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After this point it's the caller's responsibility to free
|
|
||||||
* hashes->sections. Also, in the case where we are just computing the
|
|
||||||
* stats, we are finished */
|
|
||||||
|
|
||||||
while (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
|
|
||||||
|
|
||||||
// We'll build a list of the regions that need to be hashed and pass it to
|
// We'll build a list of the regions that need to be hashed and pass it to
|
||||||
// asn1_check_mscat to do hash verification there (the hash algorithm is
|
// asn1_check_mscat to do hash verification there (the hash algorithm is
|
||||||
// specified in the PKCS7 structure). We need to hash up to 4 regions
|
// specified in the PKCS7 structure). We need to hash up to 4 regions
|
||||||
|
@ -5651,13 +5565,11 @@ cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
||||||
}
|
}
|
||||||
nregions = 0;
|
nregions = 0;
|
||||||
|
|
||||||
#define add_chunk_to_hash_list(_offset, _size) \
|
#define add_chunk_to_hash_list(_offset, _size) \
|
||||||
do { \
|
do { \
|
||||||
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) { \
|
regions[nregions].offset = (_offset); \
|
||||||
regions[nregions].offset = (_offset); \
|
regions[nregions].size = (_size); \
|
||||||
regions[nregions].size = (_size); \
|
nregions++; \
|
||||||
nregions++; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Pretty much every case below should return CL_EFORMAT
|
// Pretty much every case below should return CL_EFORMAT
|
||||||
|
@ -5802,7 +5714,8 @@ cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
||||||
|
|
||||||
ret = CL_EVERIFY;
|
ret = CL_EVERIFY;
|
||||||
break;
|
break;
|
||||||
} /* while(flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) */
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
if (NULL != hashctx) {
|
if (NULL != hashctx) {
|
||||||
cl_hash_destroy(hashctx);
|
cl_hash_destroy(hashctx);
|
||||||
|
@ -5816,7 +5729,26 @@ cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
|
/* Print out either the MD5, SHA1, or SHA256 associated with the imphash or
|
||||||
|
* the individual sections. Also, this function computes the hashes of each
|
||||||
|
* section (sorted based on the RVAs of the sections) if hashes is non-NULL.
|
||||||
|
*
|
||||||
|
* If the section hashes are to be computed and returned, this function
|
||||||
|
* allocates memory for the section hashes, and it's up to the caller to free
|
||||||
|
* it. hashes->sections will be initialized to NULL at the beginning of the
|
||||||
|
* function, and if after the call it's value is non-NULL, the memory should be
|
||||||
|
* freed. Furthermore, if hashes->sections is non-NULL, the hashes can assume
|
||||||
|
* to be valid regardless of the return code.
|
||||||
|
*
|
||||||
|
* Also, a few other notes:
|
||||||
|
* - If a section has a virtual size of zero, it's corresponding hash value
|
||||||
|
* will not be computed and the hash contents will be all zeroes.
|
||||||
|
* - If a section extends beyond the end of the file, the section data and
|
||||||
|
* length will be truncated, and the hash generated accordingly
|
||||||
|
* - If a section exists completely outside of the file, it won't be included
|
||||||
|
* in the list of sections, and nsections will be adjusted accordingly.
|
||||||
|
*/
|
||||||
|
int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type, stats_section_t *hashes)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct cli_exe_info _peinfo;
|
struct cli_exe_info _peinfo;
|
||||||
|
@ -5826,9 +5758,20 @@ int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
|
||||||
int genhash[CLI_HASH_AVAIL_TYPES];
|
int genhash[CLI_HASH_AVAIL_TYPES];
|
||||||
int hlen = 0;
|
int hlen = 0;
|
||||||
|
|
||||||
|
if (hashes) {
|
||||||
|
hashes->sections = NULL;
|
||||||
|
|
||||||
|
if (class != CL_GENHASH_PE_CLASS_SECTION || type != 1) {
|
||||||
|
cli_dbgmsg("`hashes` can only be populated with MD5 PE section data\n");
|
||||||
|
return CL_EARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (class >= CL_GENHASH_PE_CLASS_LAST)
|
if (class >= CL_GENHASH_PE_CLASS_LAST)
|
||||||
return CL_EARG;
|
return CL_EARG;
|
||||||
|
|
||||||
|
// TODO see if peinfo can be passed in (or lives in ctx or something) and
|
||||||
|
// if so, use that to avoid having to re-parse the header
|
||||||
cli_exe_info_init(peinfo, 0);
|
cli_exe_info_init(peinfo, 0);
|
||||||
|
|
||||||
if (cli_peheader(*ctx->fmap, peinfo, CLI_PEHEADER_OPT_NONE, NULL) != CLI_PEHEADER_RET_SUCCESS) {
|
if (cli_peheader(*ctx->fmap, peinfo, CLI_PEHEADER_OPT_NONE, NULL) != CLI_PEHEADER_RET_SUCCESS) {
|
||||||
|
@ -5864,35 +5807,54 @@ int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
|
||||||
return CL_EMEM;
|
return CL_EMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hashes) {
|
||||||
|
hashes->nsections = peinfo->nsections;
|
||||||
|
hashes->sections = cli_calloc(peinfo->nsections, sizeof(struct cli_section_hash));
|
||||||
|
|
||||||
|
if (!(hashes->sections)) {
|
||||||
|
cli_exe_info_destroy(peinfo);
|
||||||
|
free(hash);
|
||||||
|
return CL_EMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (class == CL_GENHASH_PE_CLASS_SECTION) {
|
if (class == CL_GENHASH_PE_CLASS_SECTION) {
|
||||||
char *dstr = NULL;
|
char *dstr;
|
||||||
|
|
||||||
for (i = 0; i < peinfo->nsections; i++) {
|
for (i = 0; i < peinfo->nsections; i++) {
|
||||||
/* Generate hashes */
|
/* Generate hashes */
|
||||||
if (cli_hashsect(*ctx->fmap, &peinfo->sections[i], hashset, genhash, genhash) == 1) {
|
if (cli_hashsect(*ctx->fmap, &peinfo->sections[i], hashset, genhash, genhash) == 1) {
|
||||||
dstr = cli_str2hex((char *)hash, hlen);
|
if (cli_debug_flag) {
|
||||||
cli_dbgmsg("Section{%u}: %u:%s\n", i, peinfo->sections[i].rsz, dstr ? (char *)dstr : "(NULL)");
|
dstr = cli_str2hex((char *)hash, hlen);
|
||||||
if (dstr != NULL) {
|
cli_dbgmsg("Section{%u}: %u:%s\n", i, peinfo->sections[i].rsz, dstr ? (char *)dstr : "(NULL)");
|
||||||
free(dstr);
|
if (dstr != NULL) {
|
||||||
dstr = NULL;
|
free(dstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (hashes) {
|
||||||
|
memcpy(hashes->sections[i].md5, hash, sizeof(hashes->sections[i].md5));
|
||||||
|
hashes->sections[i].len = peinfo->sections[i].rsz;
|
||||||
|
}
|
||||||
|
} else if (peinfo->sections[i].rsz) {
|
||||||
cli_dbgmsg("Section{%u}: failed to generate hash for section\n", i);
|
cli_dbgmsg("Section{%u}: failed to generate hash for section\n", i);
|
||||||
|
} else {
|
||||||
|
cli_dbgmsg("Section{%u}: section contains no data\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (class == CL_GENHASH_PE_CLASS_IMPTBL) {
|
} else if (class == CL_GENHASH_PE_CLASS_IMPTBL) {
|
||||||
char *dstr = NULL;
|
char *dstr;
|
||||||
uint32_t impsz = 0;
|
uint32_t impsz = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Generate hash */
|
/* Generate hash */
|
||||||
ret = hash_imptbl(ctx, hashset, &impsz, genhash, peinfo);
|
ret = hash_imptbl(ctx, hashset, &impsz, genhash, peinfo);
|
||||||
if (ret == CL_SUCCESS) {
|
if (ret == CL_SUCCESS) {
|
||||||
dstr = cli_str2hex((char *)hash, hlen);
|
if (cli_debug_flag) {
|
||||||
cli_dbgmsg("Imphash: %s:%u\n", dstr ? (char *)dstr : "(NULL)", impsz);
|
dstr = cli_str2hex((char *)hash, hlen);
|
||||||
if (dstr != NULL) {
|
cli_dbgmsg("Imphash: %s:%u\n", dstr ? (char *)dstr : "(NULL)", impsz);
|
||||||
free(dstr);
|
if (dstr != NULL) {
|
||||||
dstr = NULL;
|
free(dstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cli_dbgmsg("Imphash: failed to generate hash for import table (%d)\n", ret);
|
cli_dbgmsg("Imphash: failed to generate hash for import table (%d)\n", ret);
|
||||||
|
@ -5901,8 +5863,7 @@ int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type)
|
||||||
cli_dbgmsg("cli_genhash_pe: unknown pe genhash class: %u\n", class);
|
cli_dbgmsg("cli_genhash_pe: unknown pe genhash class: %u\n", class);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash)
|
free(hash);
|
||||||
free(hash);
|
|
||||||
cli_exe_info_destroy(peinfo);
|
cli_exe_info_destroy(peinfo);
|
||||||
return CL_SUCCESS;
|
return CL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,8 +98,8 @@ enum {
|
||||||
int cli_pe_targetinfo(fmap_t *map, struct cli_exe_info *peinfo);
|
int cli_pe_targetinfo(fmap_t *map, struct cli_exe_info *peinfo);
|
||||||
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo, uint32_t opts, cli_ctx *ctx);
|
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo, uint32_t opts, cli_ctx *ctx);
|
||||||
|
|
||||||
cl_error_t cli_checkfp_pe(cli_ctx *ctx, stats_section_t *hashes, uint32_t flags);
|
cl_error_t cli_checkfp_pe(cli_ctx *ctx);
|
||||||
int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type);
|
int cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type, stats_section_t *hashes);
|
||||||
|
|
||||||
uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t);
|
uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t);
|
||||||
void findres(uint32_t, uint32_t, fmap_t *map, struct cli_exe_info *, int (*)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *);
|
void findres(uint32_t, uint32_t, fmap_t *map, struct cli_exe_info *, int (*)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *);
|
||||||
|
|
|
@ -255,10 +255,10 @@ static int hashpe(const char *filename, unsigned int class, int type)
|
||||||
/* Send to PE-specific hasher */
|
/* Send to PE-specific hasher */
|
||||||
switch (class) {
|
switch (class) {
|
||||||
case 1:
|
case 1:
|
||||||
ret = cli_genhash_pe(&ctx, CL_GENHASH_PE_CLASS_SECTION, type);
|
ret = cli_genhash_pe(&ctx, CL_GENHASH_PE_CLASS_SECTION, type, NULL);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ret = cli_genhash_pe(&ctx, CL_GENHASH_PE_CLASS_IMPTBL, type);
|
ret = cli_genhash_pe(&ctx, CL_GENHASH_PE_CLASS_IMPTBL, type, NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mprintf("!hashpe: unknown classification(%u) for pe hash!\n", class);
|
mprintf("!hashpe: unknown classification(%u) for pe hash!\n", class);
|
||||||
|
@ -3455,7 +3455,7 @@ static int dumpcerts(const struct optstruct *opts)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cli_checkfp_pe(&ctx, NULL, CL_CHECKFP_PE_FLAG_AUTHENTICODE);
|
ret = cli_checkfp_pe(&ctx);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case CL_CLEAN:
|
case CL_CLEAN:
|
||||||
|
@ -3467,6 +3467,9 @@ static int dumpcerts(const struct optstruct *opts)
|
||||||
case CL_BREAK:
|
case CL_BREAK:
|
||||||
mprintf("*dumpcerts: CL_BREAK after cli_checkfp_pe()!\n");
|
mprintf("*dumpcerts: CL_BREAK after cli_checkfp_pe()!\n");
|
||||||
break;
|
break;
|
||||||
|
case CL_EVERIFY:
|
||||||
|
mprintf("!dumpcerts: CL_EVERIFY after cli_checkfp_pe()!\n");
|
||||||
|
break;
|
||||||
case CL_EFORMAT:
|
case CL_EFORMAT:
|
||||||
mprintf("!dumpcerts: An error occurred when parsing the file\n");
|
mprintf("!dumpcerts: An error occurred when parsing the file\n");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue