PATCH: imagehlp: handle security directories after the PE Image
Marcus Meissner
meissner at suse.de
Mon Dec 22 06:51:21 CST 2014
Subject: [PATCH] imagehlp: handle security directories after the PE Image
only comment and whitespace cleanup after last submit
J-Link.exe (some kind of usb programmer?) has the certificate right
after the last PE section. Allow that case.
---
dlls/imagehlp/integrity.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 52 insertions(+), 5 deletions(-)
diff --git a/dlls/imagehlp/integrity.c b/dlls/imagehlp/integrity.c
index d86ec11..24aefb4 100644
--- a/dlls/imagehlp/integrity.c
+++ b/dlls/imagehlp/integrity.c
@@ -141,7 +141,8 @@ static int IMAGEHLP_GetNTHeaders(HANDLE handle, DWORD *pe_offset, IMAGE_NT_HEADE
* IMAGEHLP_GetSecurityDirOffset (INTERNAL)
*
* Read a file's PE header, and return the offset and size of the
- * security directory.
+ * security directory. If there is no security directory, look for it
+ * after the PE file.
*/
static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
DWORD *pdwOfs, DWORD *pdwSize )
@@ -149,15 +150,24 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
IMAGE_NT_HEADERS32 nt_hdr32;
IMAGE_NT_HEADERS64 nt_hdr64;
IMAGE_DATA_DIRECTORY *sd;
+ DWORD maxoffset, hsize, pe_offset;
+ unsigned int i, number_sections;
int ret;
+ IMAGE_SECTION_HEADER *hdr;
+ LPVOID BaseAddress;
+ HANDLE hMapping;
- ret = IMAGEHLP_GetNTHeaders(handle, NULL, &nt_hdr32, &nt_hdr64);
+ ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64);
- if (ret == HDR_NT32)
+ if (ret == HDR_NT32) {
sd = &nt_hdr32.OptionalHeader.DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
- else if (ret == HDR_NT64)
+ number_sections = nt_hdr32.FileHeader.NumberOfSections;
+ hsize = sizeof(nt_hdr32.Signature) + sizeof(nt_hdr32.FileHeader) + nt_hdr32.FileHeader.SizeOfOptionalHeader;
+ } else if (ret == HDR_NT64) {
sd = &nt_hdr64.OptionalHeader.DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
- else
+ number_sections = nt_hdr64.FileHeader.NumberOfSections;
+ hsize = sizeof(nt_hdr64.Signature) + sizeof(nt_hdr64.FileHeader) + nt_hdr64.FileHeader.SizeOfOptionalHeader;
+ } else
return FALSE;
TRACE("ret = %d size = %x addr = %x\n", ret, sd->Size, sd->VirtualAddress);
@@ -165,6 +175,43 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
*pdwSize = sd->Size;
*pdwOfs = sd->VirtualAddress;
+ /* We have a security directory and can use that */
+ if (sd->Size != 0)
+ return TRUE;
+
+ /* The certificate directory might be hiding after the PE image (J-Link.exe) */
+ /* Determine the extent by walking the sections */
+ hMapping = CreateFileMappingW(handle, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (!hMapping)
+ return FALSE;
+
+ BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
+ if (!BaseAddress)
+ {
+ CloseHandle(hMapping);
+ return FALSE;
+ }
+ hdr = (IMAGE_SECTION_HEADER*)((char*)BaseAddress + pe_offset + hsize);
+ maxoffset = 0;
+ for (i = 0; i < number_sections; i++)
+ {
+ DWORD offset = hdr[i].PointerToRawData;
+ DWORD size = hdr[i].SizeOfRawData;
+
+ if (!offset)
+ continue;
+ if (maxoffset < offset+size)
+ maxoffset = offset+size;
+ }
+ UnmapViewOfFile(BaseAddress);
+ CloseHandle(hMapping);
+
+ hsize = GetFileSize(handle, NULL) - maxoffset;
+ if (GetFileSize(handle, NULL) < maxoffset)
+ return FALSE;
+ TRACE("after PE file: size = %x addr = %x\n", hsize, maxoffset);
+ *pdwOfs = maxoffset;
+ *pdwSize = hsize;
return TRUE;
}
--
2.2.0
More information about the wine-patches
mailing list