ReactOS 0.4.15-dev-7958-gcd0bb1a
integrity.c
Go to the documentation of this file.
1/*
2 * IMAGEHLP library
3 *
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2003 Mike McCormack
6 * Copyright 2009 Owen Rudge for CodeWeavers
7 * Copyright 2010 Juan Lang
8 * Copyright 2010 Andrey Turkin
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <stdarg.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "winerror.h"
30#include "winternl.h"
31#include "winnt.h"
32#include "imagehlp.h"
33#include "wine/debug.h"
34
36
37/*
38 * These functions are partially documented at:
39 * http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
40 */
41
42#define HDR_FAIL -1
43#define HDR_NT32 0
44#define HDR_NT64 1
45
46/***********************************************************************
47 * IMAGEHLP_GetNTHeaders (INTERNAL)
48 *
49 * Return the IMAGE_NT_HEADERS for a PE file, after validating magic
50 * numbers and distinguishing between 32-bit and 64-bit files.
51 */
53{
54 IMAGE_DOS_HEADER dos_hdr;
56 BOOL r;
57
58 TRACE("handle %p\n", handle);
59
60 if ((!nt32) || (!nt64))
61 return HDR_FAIL;
62
63 /* read the DOS header */
65
67 return HDR_FAIL;
68
69 count = 0;
70
71 r = ReadFile(handle, &dos_hdr, sizeof dos_hdr, &count, NULL);
72
73 if (!r)
74 return HDR_FAIL;
75
76 if (count != sizeof dos_hdr)
77 return HDR_FAIL;
78
79 /* verify magic number of 'MZ' */
80 if (dos_hdr.e_magic != IMAGE_DOS_SIGNATURE)
81 return HDR_FAIL;
82
83 if (pe_offset != NULL)
84 *pe_offset = dos_hdr.e_lfanew;
85
86 /* read the PE header */
88
90 return HDR_FAIL;
91
92 count = 0;
93
94 r = ReadFile(handle, nt32, sizeof(IMAGE_NT_HEADERS32), &count, NULL);
95
96 if (!r)
97 return HDR_FAIL;
98
99 if (count != sizeof(IMAGE_NT_HEADERS32))
100 return HDR_FAIL;
101
102 /* verify NT signature */
103 if (nt32->Signature != IMAGE_NT_SIGNATURE)
104 return HDR_FAIL;
105
106 /* check if we have a 32-bit or 64-bit executable */
107 switch (nt32->OptionalHeader.Magic)
108 {
110 return HDR_NT32;
111
113 /* Re-read as 64-bit */
114
116
118 return HDR_FAIL;
119
120 count = 0;
121
122 r = ReadFile(handle, nt64, sizeof(IMAGE_NT_HEADERS64), &count, NULL);
123
124 if (!r)
125 return HDR_FAIL;
126
127 if (count != sizeof(IMAGE_NT_HEADERS64))
128 return HDR_FAIL;
129
130 /* verify NT signature */
131 if (nt64->Signature != IMAGE_NT_SIGNATURE)
132 return HDR_FAIL;
133
134 return HDR_NT64;
135 }
136
137 return HDR_FAIL;
138}
139
140/***********************************************************************
141 * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
142 *
143 * Read a file's PE header, and return the offset and size of the
144 * security directory.
145 */
147 DWORD *pdwOfs, DWORD *pdwSize )
148{
149 IMAGE_NT_HEADERS32 nt_hdr32;
150 IMAGE_NT_HEADERS64 nt_hdr64;
152 int ret;
153
154 ret = IMAGEHLP_GetNTHeaders(handle, NULL, &nt_hdr32, &nt_hdr64);
155
156 if (ret == HDR_NT32)
158 else if (ret == HDR_NT64)
160 else
161 return FALSE;
162
163 TRACE("ret = %d size = %x addr = %x\n", ret, sd->Size, sd->VirtualAddress);
164
165 *pdwSize = sd->Size;
166 *pdwOfs = sd->VirtualAddress;
167
168 return TRUE;
169}
170
171/***********************************************************************
172 * IMAGEHLP_SetSecurityDirOffset (INTERNAL)
173 *
174 * Read a file's PE header, and update the offset and size of the
175 * security directory.
176 */
178 DWORD dwOfs, DWORD dwSize)
179{
180 IMAGE_NT_HEADERS32 nt_hdr32;
181 IMAGE_NT_HEADERS64 nt_hdr64;
183 int ret, nt_hdr_size = 0;
184 DWORD pe_offset;
185 void *nt_hdr;
186 DWORD count;
187 BOOL r;
188
189 ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64);
190
191 if (ret == HDR_NT32)
192 {
194
195 nt_hdr = &nt_hdr32;
196 nt_hdr_size = sizeof(IMAGE_NT_HEADERS32);
197 }
198 else if (ret == HDR_NT64)
199 {
201
202 nt_hdr = &nt_hdr64;
203 nt_hdr_size = sizeof(IMAGE_NT_HEADERS64);
204 }
205 else
206 return FALSE;
207
208 sd->Size = dwSize;
209 sd->VirtualAddress = dwOfs;
210
211 TRACE("size = %x addr = %x\n", sd->Size, sd->VirtualAddress);
212
213 /* write the header back again */
214 count = SetFilePointer(handle, pe_offset, NULL, FILE_BEGIN);
215
217 return FALSE;
218
219 count = 0;
220
221 r = WriteFile(handle, nt_hdr, nt_hdr_size, &count, NULL);
222
223 if (!r)
224 return FALSE;
225
226 if (count != nt_hdr_size)
227 return FALSE;
228
229 return TRUE;
230}
231
232/***********************************************************************
233 * IMAGEHLP_GetCertificateOffset (INTERNAL)
234 *
235 * Read a file's PE header, and return the offset and size of the
236 * security directory.
237 */
239 DWORD *pdwOfs, DWORD *pdwSize )
240{
241 DWORD size, count, offset, len, sd_VirtualAddr;
242 BOOL r;
243
244 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
245 if( !r )
246 return FALSE;
247
248 offset = 0;
249 /* take the n'th certificate */
250 while( 1 )
251 {
252 /* read the length of the current certificate */
253 count = SetFilePointer( handle, sd_VirtualAddr + offset,
254 NULL, FILE_BEGIN );
256 return FALSE;
257 r = ReadFile( handle, &len, sizeof len, &count, NULL );
258 if( !r )
259 return FALSE;
260 if( count != sizeof len )
261 return FALSE;
262
263 /* check the certificate is not too big or too small */
264 if( len < sizeof len )
265 return FALSE;
266 if( len > (size-offset) )
267 return FALSE;
268 if( !num-- )
269 break;
270
271 /* calculate the offset of the next certificate */
272 offset += len;
273
274 /* padded out to the nearest 8-byte boundary */
275 if( len % 8 )
276 offset += 8 - (len % 8);
277
278 if( offset >= size )
279 return FALSE;
280 }
281
282 *pdwOfs = sd_VirtualAddr + offset;
283 *pdwSize = len;
284
285 TRACE("len = %x addr = %x\n", len, sd_VirtualAddr + offset);
286
287 return TRUE;
288}
289
290/***********************************************************************
291 * IMAGEHLP_RecalculateChecksum (INTERNAL)
292 *
293 * Update the NT header checksum for the specified file.
294 */
296{
297 DWORD FileLength, count, HeaderSum, pe_offset, nt_hdr_size;
298 IMAGE_NT_HEADERS32 nt_hdr32;
299 IMAGE_NT_HEADERS64 nt_hdr64;
301 HANDLE hMapping;
302 DWORD *CheckSum;
303 void *nt_hdr;
304 int ret;
305 BOOL r;
306
307 TRACE("handle %p\n", handle);
308
309 ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64);
310
311 if (ret == HDR_NT32)
312 {
313 CheckSum = &nt_hdr32.OptionalHeader.CheckSum;
314
315 nt_hdr = &nt_hdr32;
316 nt_hdr_size = sizeof(IMAGE_NT_HEADERS32);
317 }
318 else if (ret == HDR_NT64)
319 {
320 CheckSum = &nt_hdr64.OptionalHeader.CheckSum;
321
322 nt_hdr = &nt_hdr64;
323 nt_hdr_size = sizeof(IMAGE_NT_HEADERS64);
324 }
325 else
326 return FALSE;
327
328 hMapping = CreateFileMappingW(handle, NULL, PAGE_READONLY, 0, 0, NULL);
329
330 if (!hMapping)
331 return FALSE;
332
333 BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
334
335 if (!BaseAddress)
336 {
337 CloseHandle(hMapping);
338 return FALSE;
339 }
340
342
343 *CheckSum = 0;
344 CheckSumMappedFile(BaseAddress, FileLength, &HeaderSum, CheckSum);
345
347 CloseHandle(hMapping);
348
349 if (*CheckSum)
350 {
351 /* write the header back again */
352 count = SetFilePointer(handle, pe_offset, NULL, FILE_BEGIN);
353
355 return FALSE;
356
357 count = 0;
358
359 r = WriteFile(handle, nt_hdr, nt_hdr_size, &count, NULL);
360
361 if (!r)
362 return FALSE;
363
364 if (count != nt_hdr_size)
365 return FALSE;
366
367 return TRUE;
368 }
369
370 return FALSE;
371}
372
373/***********************************************************************
374 * ImageAddCertificate (IMAGEHLP.@)
375 *
376 * Adds the specified certificate to the security directory of
377 * open PE file.
378 */
379
382{
383 DWORD size = 0, count = 0, offset = 0, sd_VirtualAddr = 0, index = 0;
385 const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
386 BOOL r;
387
388 TRACE("(%p, %p, %p)\n", FileHandle, Certificate, Index);
389
390 r = IMAGEHLP_GetSecurityDirOffset(FileHandle, &sd_VirtualAddr, &size);
391
392 /* If we've already got a security directory, find the end of it */
393 if ((r) && (sd_VirtualAddr != 0))
394 {
395 /* Check if the security directory is at the end of the file.
396 If not, we should probably relocate it. */
397 if (GetFileSize(FileHandle, NULL) != sd_VirtualAddr + size)
398 {
399 FIXME("Security directory already present but not located at EOF, not adding certificate\n");
400
402 return FALSE;
403 }
404
405 while (offset < size)
406 {
407 /* read the length of the current certificate */
408 count = SetFilePointer (FileHandle, sd_VirtualAddr + offset,
410
412 return FALSE;
413
414 r = ReadFile(FileHandle, &hdr, cert_hdr_size, &count, NULL);
415
416 if (!r)
417 return FALSE;
418
419 if (count != cert_hdr_size)
420 return FALSE;
421
422 /* check the certificate is not too big or too small */
423 if (hdr.dwLength < cert_hdr_size)
424 return FALSE;
425
426 if (hdr.dwLength > (size-offset))
427 return FALSE;
428
429 /* next certificate */
430 offset += hdr.dwLength;
431
432 /* padded out to the nearest 8-byte boundary */
433 if (hdr.dwLength % 8)
434 offset += 8 - (hdr.dwLength % 8);
435
436 index++;
437 }
438
439 count = SetFilePointer (FileHandle, sd_VirtualAddr + offset, NULL, FILE_BEGIN);
440
442 return FALSE;
443 }
444 else
445 {
446 sd_VirtualAddr = SetFilePointer(FileHandle, 0, NULL, FILE_END);
447
448 if (sd_VirtualAddr == INVALID_SET_FILE_POINTER)
449 return FALSE;
450 }
451
452 /* Write the certificate to the file */
454
455 if (!r)
456 return FALSE;
457
458 /* Pad out if necessary */
459 if (Certificate->dwLength % 8)
460 {
461 char null[8];
462
463 ZeroMemory(null, 8);
464 WriteFile(FileHandle, null, 8 - (Certificate->dwLength % 8), &count, NULL);
465
466 size += 8 - (Certificate->dwLength % 8);
467 }
468
469 size += Certificate->dwLength;
470
471 /* Update the security directory offset and size */
472 if (!IMAGEHLP_SetSecurityDirOffset(FileHandle, sd_VirtualAddr, size))
473 return FALSE;
474
476 return FALSE;
477
478 if(Index)
479 *Index = index;
480 return TRUE;
481}
482
483/***********************************************************************
484 * ImageEnumerateCertificates (IMAGEHLP.@)
485 */
487 HANDLE handle, WORD TypeFilter, PDWORD CertificateCount,
488 PDWORD Indices, DWORD IndexCount)
489{
490 DWORD size, count, offset, sd_VirtualAddr, index;
492 const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
493 BOOL r;
494
495 TRACE("%p %hd %p %p %d\n",
496 handle, TypeFilter, CertificateCount, Indices, IndexCount);
497
498 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
499 if( !r )
500 return FALSE;
501
502 offset = 0;
503 index = 0;
504 *CertificateCount = 0;
505 while( offset < size )
506 {
507 /* read the length of the current certificate */
508 count = SetFilePointer( handle, sd_VirtualAddr + offset,
509 NULL, FILE_BEGIN );
511 return FALSE;
512 r = ReadFile( handle, &hdr, cert_hdr_size, &count, NULL );
513 if( !r )
514 return FALSE;
515 if( count != cert_hdr_size )
516 return FALSE;
517
518 TRACE("Size = %08x id = %08hx\n",
519 hdr.dwLength, hdr.wCertificateType );
520
521 /* check the certificate is not too big or too small */
522 if( hdr.dwLength < cert_hdr_size )
523 return FALSE;
524 if( hdr.dwLength > (size-offset) )
525 return FALSE;
526
527 if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
528 (TypeFilter == hdr.wCertificateType) )
529 {
530 (*CertificateCount)++;
531 if(Indices && *CertificateCount <= IndexCount)
532 *Indices++ = index;
533 }
534
535 /* next certificate */
536 offset += hdr.dwLength;
537
538 /* padded out to the nearest 8-byte boundary */
539 if (hdr.dwLength % 8)
540 offset += 8 - (hdr.dwLength % 8);
541
542 index++;
543 }
544
545 return TRUE;
546}
547
548/***********************************************************************
549 * ImageGetCertificateData (IMAGEHLP.@)
550 *
551 * FIXME: not sure that I'm dealing with the Index the right way
552 */
556{
557 DWORD r, offset, ofs, size, count;
558
559 TRACE("%p %d %p %p\n", handle, Index, Certificate, RequiredLength);
560
561 if( !RequiredLength)
562 {
564 return FALSE;
565 }
566
568 return FALSE;
569
570 if( *RequiredLength < size )
571 {
574 return FALSE;
575 }
576
577 if( !Certificate )
578 {
580 return FALSE;
581 }
582
584
587 return FALSE;
588
590 if( !r )
591 return FALSE;
592 if( count != size )
593 return FALSE;
594
595 TRACE("OK\n");
597
598 return TRUE;
599}
600
601/***********************************************************************
602 * ImageGetCertificateHeader (IMAGEHLP.@)
603 */
606{
607 DWORD r, offset, ofs, size, count;
608 const size_t cert_hdr_size = sizeof *pCert - sizeof pCert->bCertificate;
609
610 TRACE("%p %d %p\n", handle, index, pCert);
611
613 return FALSE;
614
615 if( size < cert_hdr_size )
616 return FALSE;
617
620 return FALSE;
621
622 r = ReadFile( handle, pCert, cert_hdr_size, &count, NULL );
623 if( !r )
624 return FALSE;
625 if( count != cert_hdr_size )
626 return FALSE;
627
628 TRACE("OK\n");
629
630 return TRUE;
631}
632
633/* Finds the section named section in the array of IMAGE_SECTION_HEADERs hdr. If
634 * found, returns the offset to the section. Otherwise returns 0. If the section
635 * is found, optionally returns the size of the section (in size) and the base
636 * address of the section (in base.)
637 */
639 DWORD num_sections, LPCSTR section, PDWORD size, PDWORD base )
640{
641 DWORD i, offset = 0;
642
643 for( i = 0; !offset && i < num_sections; i++, hdr++ )
644 {
645 if( !memcmp( hdr->Name, section, strlen(section) ) )
646 {
647 offset = hdr->PointerToRawData;
648 if( size )
649 *size = hdr->SizeOfRawData;
650 if( base )
651 *base = hdr->VirtualAddress;
652 }
653 }
654 return offset;
655}
656
657/* Calls DigestFunction e bytes at offset offset from the file mapped at map.
658 * Returns the return value of DigestFunction, or FALSE if the data is not available.
659 */
661 BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle )
662{
663 if( offset + size > fileSize )
664 {
666 return FALSE;
667 }
668 return DigestFunction( DigestHandle, map + offset, size );
669}
670
671/* Finds the section named section among the IMAGE_SECTION_HEADERs in
672 * section_headers and calls DigestFunction for this section. Returns
673 * the return value from DigestFunction, or FALSE if the data could not be read.
674 */
676 DWORD num_sections, LPCSTR section, BYTE *map, DWORD fileSize,
677 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle )
678{
679 DWORD offset, size = 0;
680
682 &size, NULL );
683 if( !offset )
684 return FALSE;
686 DigestFunction, DigestHandle );
687}
688
689/* Calls DigestFunction for all sections with the IMAGE_SCN_CNT_CODE flag set.
690 * Returns the return value from * DigestFunction, or FALSE if a section could not be read.
691 */
693 BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle )
694{
695 DWORD i;
696 BOOL ret = TRUE;
697
698 for( i = 0; ret && i < num_sections; i++, hdr++ )
699 {
700 if( hdr->Characteristics & IMAGE_SCN_CNT_CODE )
701 ret = IMAGEHLP_ReportSectionFromOffset( hdr->PointerToRawData,
702 hdr->SizeOfRawData, map, fileSize, DigestFunction, DigestHandle );
703 }
704 return ret;
705}
706
707/* Reports the import section from the file FileHandle. If
708 * CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO is set in DigestLevel, reports the entire
709 * import section.
710 * FIXME: if it's not set, the function currently fails.
711 */
713 DWORD num_sections, BYTE *map, DWORD fileSize, DWORD DigestLevel,
714 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle )
715{
716 BOOL ret = FALSE;
718
719 /* Get import data */
720 offset = IMAGEHLP_GetSectionOffset( hdr, num_sections, ".idata", &size,
721 &base );
722 if( !offset )
723 return FALSE;
724
725 /* If CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO is set, the entire
726 * section is reported. Otherwise, the debug info section is
727 * decoded and reported piecemeal. See tests. However, I haven't been
728 * able to figure out how the native implementation decides which values
729 * to report. Either it's buggy or my understanding is flawed.
730 */
731 if( DigestLevel & CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO )
733 DigestFunction, DigestHandle );
734 else
735 {
736 FIXME("not supported except for CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO\n");
738 ret = FALSE;
739 }
740
741 return ret;
742}
743
744/***********************************************************************
745 * ImageGetDigestStream (IMAGEHLP.@)
746 *
747 * Gets a stream of bytes from a PE file over which a hash might be computed to
748 * verify that the image has not changed. Useful for creating a certificate to
749 * be added to the file with ImageAddCertificate.
750 *
751 * PARAMS
752 * FileHandle [In] File for which to return a stream.
753 * DigestLevel [In] Flags to control which portions of the file to return.
754 * 0 is allowed, as is any combination of:
755 * CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO: reports the entire
756 * import section rather than selected portions of it.
757 * CERT_PE_IMAGE_DIGEST_DEBUG_INFO: reports the debug section.
758 * CERT_PE_IMAGE_DIGEST_RESOURCES: reports the resources
759 section.
760 * DigestFunction [In] Callback function.
761 * DigestHandle [In] Handle passed as first parameter to DigestFunction.
762 *
763 * RETURNS
764 * TRUE if successful.
765 * FALSE if unsuccessful. GetLastError returns more about the error.
766 *
767 * NOTES
768 * Only supports 32-bit PE files, not tested with any other format.
769 * Reports data in the following order:
770 * 1. The file headers are reported first
771 * 2. Any code sections are reported next.
772 * 3. The data (".data" and ".rdata") sections are reported next.
773 * 4. The import section is reported next.
774 * 5. If CERT_PE_IMAGE_DIGEST_DEBUG_INFO is set in DigestLevel, the debug section is
775 * reported next.
776 * 6. If CERT_PE_IMAGE_DIGEST_RESOURCES is set in DigestLevel, the resources section
777 * is reported next.
778 *
779 * BUGS
780 * CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO must be specified, returns an error if not.
781 */
783 HANDLE FileHandle, DWORD DigestLevel,
784 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
785{
786 DWORD error = 0;
787 BOOL ret = FALSE;
788 DWORD offset, size, num_sections, fileSize;
790 BYTE *map = NULL;
791 IMAGE_DOS_HEADER *dos_hdr;
792 IMAGE_NT_HEADERS *nt_hdr;
794
795 TRACE("(%p, %d, %p, %p)\n", FileHandle, DigestLevel, DigestFunction,
796 DigestHandle);
797
798 /* Get the file size */
799 if( !FileHandle )
800 goto invalid_parameter;
801 fileSize = GetFileSize( FileHandle, NULL );
802 if(fileSize == INVALID_FILE_SIZE )
803 goto invalid_parameter;
804
805 /* map file */
807 if( hMap == INVALID_HANDLE_VALUE )
808 goto invalid_parameter;
809 map = MapViewOfFile( hMap, FILE_MAP_COPY, 0, 0, 0 );
810 if( !map )
811 goto invalid_parameter;
812
813 /* Read the file header */
814 if( fileSize < sizeof(IMAGE_DOS_HEADER) )
815 goto invalid_parameter;
816 dos_hdr = (IMAGE_DOS_HEADER *)map;
817
818 if( dos_hdr->e_magic != IMAGE_DOS_SIGNATURE )
819 goto invalid_parameter;
820 offset = dos_hdr->e_lfanew;
821 if( !offset || offset > fileSize )
822 goto invalid_parameter;
823 ret = DigestFunction( DigestHandle, map, offset );
824 if( !ret )
825 goto end;
826
827 /* Read the NT header */
828 if( offset + sizeof(IMAGE_NT_HEADERS) > fileSize )
829 goto invalid_parameter;
830 nt_hdr = (IMAGE_NT_HEADERS *)(map + offset);
831 if( nt_hdr->Signature != IMAGE_NT_SIGNATURE )
832 goto invalid_parameter;
833 /* It's clear why the checksum is cleared, but why only these size headers?
834 */
836 nt_hdr->OptionalHeader.SizeOfImage = 0;
837 nt_hdr->OptionalHeader.CheckSum = 0;
838 size = sizeof(nt_hdr->Signature) + sizeof(nt_hdr->FileHeader) +
840 ret = DigestFunction( DigestHandle, map + offset, size );
841 if( !ret )
842 goto end;
843
844 /* Read the section headers */
845 offset += size;
846 num_sections = nt_hdr->FileHeader.NumberOfSections;
847 size = num_sections * sizeof(IMAGE_SECTION_HEADER);
848 if( offset + size > fileSize )
849 goto invalid_parameter;
850 ret = DigestFunction( DigestHandle, map + offset, size );
851 if( !ret )
852 goto end;
853
856 map, fileSize, DigestFunction, DigestHandle );
857 IMAGEHLP_ReportSection( section_headers, num_sections, ".data",
858 map, fileSize, DigestFunction, DigestHandle );
859 IMAGEHLP_ReportSection( section_headers, num_sections, ".rdata",
860 map, fileSize, DigestFunction, DigestHandle );
862 map, fileSize, DigestLevel, DigestFunction, DigestHandle );
863 if( DigestLevel & CERT_PE_IMAGE_DIGEST_DEBUG_INFO )
864 IMAGEHLP_ReportSection( section_headers, num_sections, ".debug",
865 map, fileSize, DigestFunction, DigestHandle );
866 if( DigestLevel & CERT_PE_IMAGE_DIGEST_RESOURCES )
867 IMAGEHLP_ReportSection( section_headers, num_sections, ".rsrc",
868 map, fileSize, DigestFunction, DigestHandle );
869
870end:
871 if( map )
873 if( hMap != INVALID_HANDLE_VALUE )
874 CloseHandle( hMap );
875 if( error )
877 return ret;
878
879invalid_parameter:
881 goto end;
882}
883
884/***********************************************************************
885 * ImageRemoveCertificate (IMAGEHLP.@)
886 */
888{
889 DWORD size = 0, count = 0, sd_VirtualAddr = 0, offset = 0;
890 DWORD data_size = 0, cert_size = 0, cert_size_padded = 0, ret = 0;
891 LPVOID cert_data;
892 BOOL r;
893
894 TRACE("(%p, %d)\n", FileHandle, Index);
895
897
898 if ((!r) || (count == 0))
899 return FALSE;
900
901 if ((!IMAGEHLP_GetSecurityDirOffset(FileHandle, &sd_VirtualAddr, &size)) ||
903 return FALSE;
904
905 /* Ignore any padding we have, too */
906 if (cert_size % 8)
907 cert_size_padded = cert_size + (8 - (cert_size % 8));
908 else
909 cert_size_padded = cert_size;
910
911 data_size = size - (offset - sd_VirtualAddr) - cert_size_padded;
912
913 if (data_size == 0)
914 {
915 ret = SetFilePointer(FileHandle, sd_VirtualAddr, NULL, FILE_BEGIN);
916
918 return FALSE;
919 }
920 else
921 {
922 cert_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, data_size);
923
924 if (!cert_data)
925 return FALSE;
926
927 ret = SetFilePointer(FileHandle, offset + cert_size_padded, NULL, FILE_BEGIN);
928
930 goto error;
931
932 /* Read any subsequent certificates */
933 r = ReadFile(FileHandle, cert_data, data_size, &count, NULL);
934
935 if ((!r) || (count != data_size))
936 goto error;
937
939
940 /* Write them one index back */
941 r = WriteFile(FileHandle, cert_data, data_size, &count, NULL);
942
943 if ((!r) || (count != data_size))
944 goto error;
945
946 HeapFree(GetProcessHeap(), 0, cert_data);
947 }
948
949 /* If security directory is at end of file, trim the file */
950 if (GetFileSize(FileHandle, NULL) == sd_VirtualAddr + size)
952
953 if (count == 1)
955 else
956 r = IMAGEHLP_SetSecurityDirOffset(FileHandle, sd_VirtualAddr, size - cert_size_padded);
957
958 if (!r)
959 return FALSE;
960
962 return FALSE;
963
964 return TRUE;
965
966error:
967 HeapFree(GetProcessHeap(), 0, cert_data);
968 return FALSE;
969}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
int null(void)
Definition: ftp.c:1794
#define FIXME(fmt,...)
Definition: debug.h:111
Definition: _map.h:48
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define INVALID_SET_FILE_POINTER
Definition: compat.h:732
#define UnmapViewOfFile
Definition: compat.h:746
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL WINAPI ImageGetCertificateData(HANDLE handle, DWORD Index, LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
Definition: integrity.c:553
BOOL WINAPI ImageAddCertificate(HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index)
Definition: integrity.c:380
static int IMAGEHLP_GetNTHeaders(HANDLE handle, DWORD *pe_offset, IMAGE_NT_HEADERS32 *nt32, IMAGE_NT_HEADERS64 *nt64)
Definition: integrity.c:52
#define HDR_FAIL
Definition: integrity.c:42
static BOOL IMAGEHLP_RecalculateChecksum(HANDLE handle)
Definition: integrity.c:295
static BOOL IMAGEHLP_ReportSectionFromOffset(DWORD offset, DWORD size, BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:660
BOOL WINAPI ImageEnumerateCertificates(HANDLE handle, WORD TypeFilter, PDWORD CertificateCount, PDWORD Indices, DWORD IndexCount)
Definition: integrity.c:486
static BOOL IMAGEHLP_ReportCodeSections(IMAGE_SECTION_HEADER *hdr, DWORD num_sections, BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:692
static BOOL IMAGEHLP_ReportImportSection(IMAGE_SECTION_HEADER *hdr, DWORD num_sections, BYTE *map, DWORD fileSize, DWORD DigestLevel, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:712
BOOL WINAPI ImageGetDigestStream(HANDLE FileHandle, DWORD DigestLevel, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:782
static BOOL IMAGEHLP_GetSecurityDirOffset(HANDLE handle, DWORD *pdwOfs, DWORD *pdwSize)
Definition: integrity.c:146
static BOOL IMAGEHLP_GetCertificateOffset(HANDLE handle, DWORD num, DWORD *pdwOfs, DWORD *pdwSize)
Definition: integrity.c:238
BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
Definition: integrity.c:887
static BOOL IMAGEHLP_ReportSection(IMAGE_SECTION_HEADER *section_headers, DWORD num_sections, LPCSTR section, BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:675
#define HDR_NT64
Definition: integrity.c:44
BOOL WINAPI ImageGetCertificateHeader(HANDLE handle, DWORD index, LPWIN_CERTIFICATE pCert)
Definition: integrity.c:604
static DWORD IMAGEHLP_GetSectionOffset(IMAGE_SECTION_HEADER *hdr, DWORD num_sections, LPCSTR section, PDWORD size, PDWORD base)
Definition: integrity.c:638
static BOOL IMAGEHLP_SetSecurityDirOffset(HANDLE handle, DWORD dwOfs, DWORD dwSize)
Definition: integrity.c:177
#define HDR_NT32
Definition: integrity.c:43
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static const WCHAR Certificate[]
Definition: register.c:76
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _IMAGE_NT_HEADERS IMAGE_NT_HEADERS32
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(LPVOID BaseAddress, DWORD FileLength, LPDWORD HeaderSum, LPDWORD CheckSum)
Definition: modify.c:187
BOOL(WINAPI * DIGEST_FUNCTION)(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)
Definition: imagehlp.h:314
#define CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO
Definition: imagehlp.h:45
#define CERT_PE_IMAGE_DIGEST_DEBUG_INFO
Definition: imagehlp.h:43
#define CERT_PE_IMAGE_DIGEST_RESOURCES
Definition: imagehlp.h:44
#define CERT_SECTION_TYPE_ANY
Definition: imagehlp.h:47
char hdr[14]
Definition: iptest.cpp:33
#define error(str)
Definition: mkdosfs.c:1605
static IMAGE_SECTION_HEADER section_headers[]
Definition: data.c:95
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static const WCHAR sd[]
Definition: suminfo.c:286
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3228
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
struct _IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS64
DWORD * PDWORD
Definition: pedump.c:68
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
#define TRACE(s)
Definition: solgame.cpp:4
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
BYTE bCertificate[ANYSIZE_ARRAY]
Definition: wintrust.h:620
Definition: parser.c:56
int ret
_In_ WDFCOLLECTION _In_ ULONG Index
#define ZeroMemory
Definition: winbase.h:1712
#define FILE_END
Definition: winbase.h:114
#define FILE_MAP_COPY
Definition: winbase.h:153
#define INVALID_FILE_SIZE
Definition: winbase.h:548
#define WINAPI
Definition: msvc.h:6
#define IMAGE_FILE_SECURITY_DIRECTORY
Definition: winnt_old.h:616
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char BYTE
Definition: xxhash.c:193