From: Marcus Meissner Subject: PATCH: imagehlp: handle security directories after the PE file Message-Id: <20141212200731.GA25722@suse.de> Date: Fri, 12 Dec 2014 21:07:34 +0100 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