user32: Fix icon extraction from non-native PE executables. (try 2)
Hans Leidekker
hans at codeweavers.com
Thu Jun 6 12:30:05 CDT 2013
This version uses the RtlImage* functions. It doesn't preserve all
validation checks.
---
dlls/user32/exticon.c | 87 ++++++++++---------------------------------------
1 file changed, 17 insertions(+), 70 deletions(-)
diff --git a/dlls/user32/exticon.c b/dlls/user32/exticon.c
index 5b9d681..0dbbef1 100644
--- a/dlls/user32/exticon.c
+++ b/dlls/user32/exticon.c
@@ -420,47 +420,19 @@ static UINT ICO_ExtractIconExW(
/* exe/dll */
else if( sig == IMAGE_NT_SIGNATURE )
{
- LPBYTE idata,igdata;
- PIMAGE_DOS_HEADER dheader;
- PIMAGE_NT_HEADERS pe_header;
- PIMAGE_SECTION_HEADER pe_sections;
- const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
- const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
- const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
- UINT i, j;
-
- dheader = (PIMAGE_DOS_HEADER)peimage;
- pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */
- pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)
- + pe_header->FileHeader.SizeOfOptionalHeader);
- rootresdir = NULL;
-
- /* search for the root resource directory */
- for (i=0;i<pe_header->FileHeader.NumberOfSections;i++)
- {
- if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- continue;
- if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) {
- FIXME("File %s too short (section is at %d bytes, real size is %d)\n",
- debugstr_w(lpszExeFileName),
- pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData,
- fsizel
- );
- goto end;
- }
- /* FIXME: doesn't work when the resources are not in a separate section */
- if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
- {
- rootresdir = (PIMAGE_RESOURCE_DIRECTORY)(peimage+pe_sections[i].PointerToRawData);
- break;
- }
- }
-
- if (!rootresdir)
- {
- WARN("haven't found section for resource directory.\n");
- goto end; /* failure */
- }
+ BYTE *idata, *igdata;
+ const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir;
+ const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent;
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
+ ULONG size;
+ UINT i;
+
+ rootresdir = RtlImageDirectoryEntryToData((HMODULE)peimage, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size);
+ if (!rootresdir)
+ {
+ WARN("haven't found section for resource directory.\n");
+ goto end;
+ }
/* search for the group icon directory */
if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
@@ -529,24 +501,8 @@ static UINT ICO_ExtractIconExW(
igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;
/* lookup address in mapped image for virtual address */
- igdata = NULL;
-
- for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
- {
- if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
- continue;
- if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
- continue;
-
- if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) {
- FIXME("overflow in PE lookup (%s has len %d, have offset %d), short file?\n", debugstr_w(lpszExeFileName), fsizel,
- igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size);
- goto end; /* failure */
- }
- igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
- }
-
- if (!igdata)
+ igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL);
+ if (!igdata)
{
FIXME("no matching real address for icongroup!\n");
goto end; /* failure */
@@ -573,18 +529,9 @@ static UINT ICO_ExtractIconExW(
}
xresdir = find_entry_default(xresdir, rootresdir);
idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
- idata = NULL;
- /* map virtual to address in image */
- for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
- {
- if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
- continue;
- if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
- continue;
- idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
- }
- if (!idata)
+ idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL);
+ if (!idata)
{
WARN("no matching real address found for icondata!\n");
RetPtr[i]=0;
--
1.7.10.4
More information about the wine-patches
mailing list