PATCH: imagehlp: handle security directories after the PE file

Marcus Meissner meissner at suse.de
Fri Dec 12 14:07:34 CST 2014


Subject: [PATCH] imagehlp: handle security directories after the PE Image

J-Link.exe (some kind of usb programmer?) has the certificate right
after the last PE section. Implement that case.
---
 dlls/imagehlp/integrity.c | 54 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/dlls/imagehlp/integrity.c b/dlls/imagehlp/integrity.c
index d86ec11..c770e3c 100644
--- a/dlls/imagehlp/integrity.c
+++ b/dlls/imagehlp/integrity.c
@@ -149,15 +149,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 +174,41 @@ 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) */
+    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;
 }
 
@@ -242,7 +286,7 @@ static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num,
     BOOL r;
 
     r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
-    if( !r )
+    if( !r ) 
         return FALSE;
 
     offset = 0;
-- 
2.2.0




More information about the wine-patches mailing list