...
|
...
|
@@ -5607,7 +5607,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
|
5607
|
5607
|
}
|
5608
|
5608
|
nregions = 0;
|
5609
|
5609
|
|
5610
|
|
-#define hash_chunk(where, _size, isStatAble, section) \
|
|
5610
|
+#define hash_chunk(where, _size) \
|
5611
|
5611
|
do { \
|
5612
|
5612
|
const uint8_t *hptr; \
|
5613
|
5613
|
if(!(_size)) break; \
|
...
|
...
|
@@ -5621,21 +5621,13 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
|
5621
|
5621
|
regions[nregions].size = _size; \
|
5622
|
5622
|
nregions++; \
|
5623
|
5623
|
} \
|
5624
|
|
- if (isStatAble && flags & CL_CHECKFP_PE_FLAG_STATS) { \
|
5625
|
|
- void *md5ctx; \
|
5626
|
|
- md5ctx = cl_hash_init("md5"); \
|
5627
|
|
- if (md5ctx) { \
|
5628
|
|
- cl_update_hash(md5ctx, (void *)hptr, _size); \
|
5629
|
|
- cl_finish_hash(md5ctx, hashes->sections[section].md5); \
|
5630
|
|
- } \
|
5631
|
|
- } \
|
5632
|
5624
|
} while(0)
|
5633
|
5625
|
|
5634
|
5626
|
while (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
|
5635
|
5627
|
/* MZ to checksum */
|
5636
|
5628
|
at = 0;
|
5637
|
5629
|
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));
|
5638
|
|
- hash_chunk(0, hlen, 0, 0);
|
|
5630
|
+ hash_chunk(0, hlen);
|
5639
|
5631
|
at = hlen + 4;
|
5640
|
5632
|
|
5641
|
5633
|
/* Checksum to security */
|
...
|
...
|
@@ -5643,7 +5635,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
|
5643
|
5643
|
hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4;
|
5644
|
5644
|
else
|
5645
|
5645
|
hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4;
|
5646
|
|
- hash_chunk(at, hlen, 0, 0);
|
|
5646
|
+ hash_chunk(at, hlen);
|
5647
|
5647
|
at += hlen + 8;
|
5648
|
5648
|
|
5649
|
5649
|
if(at > hdr_size) {
|
...
|
...
|
@@ -5659,53 +5651,44 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uin
|
5659
|
5659
|
|
5660
|
5660
|
/* Security to End of header */
|
5661
|
5661
|
hlen = hdr_size - at;
|
5662
|
|
- hash_chunk(at, hlen, 0, 0);
|
|
5662
|
+ hash_chunk(at, hlen);
|
5663
|
5663
|
at += hlen;
|
5664
|
5664
|
break;
|
5665
|
5665
|
}
|
5666
|
5666
|
|
5667
|
5667
|
/* Hash the sections */
|
5668
|
|
- for(i = 0; i < nsections; i++) {
|
5669
|
|
- if(!exe_sections[i].rsz)
|
5670
|
|
- continue;
|
5671
|
|
-
|
5672
|
|
- hash_chunk(exe_sections[i].raw, exe_sections[i].rsz, 1, i);
|
5673
|
|
-
|
5674
|
|
- /* If the section overlaps with the header (the case for UPX binaries)
|
5675
|
|
- * adjust the entry in the authenticode hash regions list to account
|
5676
|
|
- * for the fact that we've already accounted for computing the hash
|
5677
|
|
- * over the header */
|
5678
|
|
- if (exe_sections[i].raw < at)
|
5679
|
|
- {
|
5680
|
|
- uint32_t overlap_size = (at - exe_sections[i].raw);
|
5681
|
|
- if (overlap_size >= exe_sections[i].rsz) {
|
5682
|
|
- /* The section completely overlaps the header. Setting the
|
5683
|
|
- * size to zero should prevent this section from affecting
|
5684
|
|
- * the actual Authenticode hash computation. */
|
5685
|
|
- regions[nregions-1].size = 0;
|
5686
|
|
- } else {
|
5687
|
|
- regions[nregions-1].size -= overlap_size;
|
5688
|
|
- regions[nregions-1].ptr += overlap_size;
|
|
5668
|
+ if (flags & CL_CHECKFP_PE_FLAG_STATS) {
|
|
5669
|
+
|
|
5670
|
+ for(i = 0; i < nsections; i++) {
|
|
5671
|
+ const uint8_t *hptr;
|
|
5672
|
+ void *md5ctx;
|
|
5673
|
+
|
|
5674
|
+ if(!exe_sections[i].rsz)
|
|
5675
|
+ continue;
|
|
5676
|
+
|
|
5677
|
+ if(!(hptr = fmap_need_off_once(map, exe_sections[i].raw, exe_sections[i].rsz))){
|
|
5678
|
+ free(exe_sections);
|
|
5679
|
+ free(regions);
|
|
5680
|
+ return CL_EFORMAT;
|
|
5681
|
+ }
|
|
5682
|
+ md5ctx = cl_hash_init("md5");
|
|
5683
|
+ if (md5ctx) {
|
|
5684
|
+ cl_update_hash(md5ctx, (void *)hptr, exe_sections[i].rsz);
|
|
5685
|
+ cl_finish_hash(md5ctx, hashes->sections[i].md5);
|
5689
|
5686
|
}
|
5690
|
5687
|
}
|
5691
|
5688
|
}
|
5692
|
5689
|
|
5693
|
|
- /* Finally, if there is data after the section with the highest
|
5694
|
|
- * PointerToRawData, hash that too. This is a variation of what
|
5695
|
|
- * the 2008 spec doc says to do (add up all the SizeOfRawData's and
|
5696
|
|
- * start hashing at that point after the PE header), but should also
|
5697
|
|
- * work in the case where a binary has overlapping sections or a section
|
5698
|
|
- * overlaps the PE header (barring some edge cases like a section
|
5699
|
|
- * fully containing another section with a higher starting addr.)
|
|
5690
|
+ free(exe_sections);
|
|
5691
|
+
|
|
5692
|
+ /* Finally, hash everything from the end of the header to the start of
|
|
5693
|
+ * the security section, which must be the last thing in a file
|
5700
|
5694
|
*/
|
5701
|
|
- at = exe_sections[nsections-1].raw + exe_sections[nsections-1].rsz;
|
5702
|
5695
|
if (at < EC32(dirs[4].VirtualAddress)) {
|
5703
|
5696
|
hlen = EC32(dirs[4].VirtualAddress)-at;
|
5704
|
|
- hash_chunk(at, hlen, 0, 0);
|
|
5697
|
+ hash_chunk(at, hlen);
|
5705
|
5698
|
}
|
5706
|
5699
|
|
5707
|
|
- free(exe_sections);
|
5708
|
|
-
|
5709
|
5700
|
if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) {
|
5710
|
5701
|
|
5711
|
5702
|
hlen = EC32(dirs[4].Size);
|