ReactOS  0.4.13-dev-645-g69454b4
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;
55  DWORD count;
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;
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,
409  NULL, FILE_BEGIN);
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  {
572  *RequiredLength = size;
574  return FALSE;
575  }
576 
577  if( !Certificate )
578  {
580  return FALSE;
581  }
582 
583  *RequiredLength = size;
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;
717  DWORD offset, size, base;
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;
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 
870 end:
871  if( map )
872  UnmapViewOfFile( map );
873  if( hMap != INVALID_HANDLE_VALUE )
874  CloseHandle( hMap );
875  if( error )
877  return ret;
878 
879 invalid_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 
966 error:
967  HeapFree(GetProcessHeap(), 0, cert_data);
968  return FALSE;
969 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI ImageEnumerateCertificates(HANDLE handle, WORD TypeFilter, PDWORD CertificateCount, PDWORD Indices, DWORD IndexCount)
Definition: integrity.c:486
#define CERT_PE_IMAGE_DIGEST_DEBUG_INFO
Definition: imagehlp.h:43
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3227
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
char hdr[14]
Definition: iptest.cpp:33
#define INVALID_SET_FILE_POINTER
Definition: winbase.h:115
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
int fileSize
Definition: main.cpp:54
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL WINAPI ImageGetDigestStream(HANDLE FileHandle, DWORD DigestLevel, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:782
#define MapViewOfFile
Definition: compat.h:402
#define error(str)
Definition: mkdosfs.c:1605
#define HDR_NT32
Definition: integrity.c:43
static BOOL IMAGEHLP_ReportSectionFromOffset(DWORD offset, DWORD size, BYTE *map, DWORD fileSize, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
Definition: integrity.c:660
static BOOL IMAGEHLP_SetSecurityDirOffset(HANDLE handle, DWORD dwOfs, DWORD dwSize)
Definition: integrity.c:177
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static IMAGE_SECTION_HEADER section_headers[]
Definition: data.c:95
static const WCHAR Certificate[]
Definition: register.c:76
WINE_DEFAULT_DEBUG_CHANNEL(imagehlp)
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define CERT_SECTION_TYPE_ANY
Definition: imagehlp.h:47
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1154
GLintptr offset
Definition: glext.h:5920
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
struct _IMAGE_NT_HEADERS IMAGE_NT_HEADERS32
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define ZeroMemory
Definition: winbase.h:1635
static DWORD IMAGEHLP_GetSectionOffset(IMAGE_SECTION_HEADER *hdr, DWORD num_sections, LPCSTR section, PDWORD size, PDWORD base)
Definition: integrity.c:638
GLuint GLuint end
Definition: gl.h:1545
#define INVALID_FILE_SIZE
Definition: winbase.h:529
Definition: parser.c:55
#define NO_ERROR
Definition: dderror.h:5
BOOL WINAPI ImageGetCertificateData(HANDLE handle, DWORD Index, LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
Definition: integrity.c:553
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO
Definition: imagehlp.h:45
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
Definition: fileinfo.c:204
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
BOOL WINAPI ImageGetCertificateHeader(HANDLE handle, DWORD index, LPWIN_CERTIFICATE pCert)
Definition: integrity.c:604
HANDLE FileHandle
Definition: stats.c:38
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
static BOOL IMAGEHLP_GetCertificateOffset(HANDLE handle, DWORD num, DWORD *pdwOfs, DWORD *pdwSize)
Definition: integrity.c:238
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI ImageAddCertificate(HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index)
Definition: integrity.c:380
GLuint base
Definition: 3dtext.c:35
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
#define FILE_MAP_READ
Definition: compat.h:427
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
BOOL(WINAPI * DIGEST_FUNCTION)(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)
Definition: imagehlp.h:314
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define FILE_END
Definition: winbase.h:114
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:401
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
#define WINAPI
Definition: msvc.h:8
static BOOL IMAGEHLP_RecalculateChecksum(HANDLE handle)
Definition: integrity.c:295
struct _IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS64
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
UCHAR CheckSum(LPSTR p, ULONG Len)
Definition: serial.c:197
BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
Definition: integrity.c:887
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define SetLastError(x)
Definition: compat.h:409
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
Definition: _map.h:44
#define HDR_FAIL
Definition: integrity.c:42
static const WCHAR sd[]
Definition: suminfo.c:287
int ret
#define index(s, c)
Definition: various.h:29
#define FILE_MAP_COPY
Definition: winbase.h:153
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
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
#define FILE_BEGIN
Definition: winbase.h:112
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
BYTE bCertificate[ANYSIZE_ARRAY]
Definition: wintrust.h:620
#define PAGE_READONLY
Definition: compat.h:127
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
DWORD * PDWORD
Definition: pedump.c:68
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
static BOOL IMAGEHLP_GetSecurityDirOffset(HANDLE handle, DWORD *pdwOfs, DWORD *pdwSize)
Definition: integrity.c:146
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
PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(LPVOID BaseAddress, DWORD FileLength, LPDWORD HeaderSum, LPDWORD CheckSum)
Definition: modify.c:187
#define UnmapViewOfFile
Definition: compat.h:403
static int IMAGEHLP_GetNTHeaders(HANDLE handle, DWORD *pe_offset, IMAGE_NT_HEADERS32 *nt32, IMAGE_NT_HEADERS64 *nt64)
Definition: integrity.c:52
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define HDR_NT64
Definition: integrity.c:44
#define IMAGE_FILE_SECURITY_DIRECTORY
Definition: winnt_old.h:649
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define CERT_PE_IMAGE_DIGEST_RESOURCES
Definition: imagehlp.h:44