Example #1
0
DWORD   DumpResourceToFile(__in __nullterminated WCHAR*   wzFileName)
{

    BYTE*   pbResBase;
    FILE*   pF = NULL;
    DWORD ret = 0;
    DWORD   dwResDirRVA;
    DWORD   dwResDirSize;
    unsigned ulNumResNodes=0;
    DynamicArray<ResourceNode*> g_prResNodePtr;

    if (g_pPELoader->IsPE32())
    {
        IMAGE_OPTIONAL_HEADER32 *pOptHeader = &(g_pPELoader->ntHeaders32()->OptionalHeader);

        dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
    }
    else
    {
        IMAGE_OPTIONAL_HEADER64 *pOptHeader = &(g_pPELoader->ntHeaders64()->OptionalHeader);

        dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
    }

    if(dwResDirRVA && dwResDirSize)
    {
        if(g_pPELoader->getVAforRVA(dwResDirRVA, (void **) &pbResBase))
        {
            // First, pull out all resource nodes (tree leaves), see ResourceNode struct
            PIMAGE_RESOURCE_DIRECTORY pirdType = (PIMAGE_RESOURCE_DIRECTORY)pbResBase;
            PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeType = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbResBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
            DWORD	dwTypeID;
            unsigned short i = 0,N = pirdType->NumberOfNamedEntries+pirdType->NumberOfIdEntries;
            PAL_CPP_TRY {
                for(i=0; i < N; i++, pirdeType++)
                {
                    dwTypeID = VAL32(IMAGE_RDE_NAME(pirdeType));
                    if(IMAGE_RDE_OFFSET_FIELD(pirdeType, DataIsDirectory))
                    {
                        BYTE*   pbNameBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeType, OffsetToDirectory));
                        PIMAGE_RESOURCE_DIRECTORY pirdName = (PIMAGE_RESOURCE_DIRECTORY)pbNameBase;
                        PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeName = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbNameBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
                        DWORD   dwNameID;
                        unsigned short i,N = VAL16(pirdName->NumberOfNamedEntries)+VAL16(pirdName->NumberOfIdEntries);

                        for(i=0; i < N; i++, pirdeName++)
                        {
                            dwNameID = VAL32(IMAGE_RDE_NAME(pirdeName));
                            if(IMAGE_RDE_OFFSET_FIELD(pirdeName, DataIsDirectory))
                            {
                                BYTE*   pbLangBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeName, OffsetToDirectory));
                                PIMAGE_RESOURCE_DIRECTORY pirdLang = (PIMAGE_RESOURCE_DIRECTORY)pbLangBase;
                                PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeLang = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbLangBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
                                DWORD   dwLangID;
                                unsigned short i,N = VAL16(pirdLang->NumberOfNamedEntries)+VAL16(pirdLang->NumberOfIdEntries);

                                for(i=0; i < N; i++, pirdeLang++)
                                {
                                    dwLangID = VAL32(IMAGE_RDE_NAME(pirdeLang));
                                    if(IMAGE_RDE_OFFSET_FIELD(pirdeLang, DataIsDirectory))
                                    {
                                        _ASSERTE(!"Resource hierarchy exceeds three levels");
                                    }
                                    else
                                    {
                                        g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,dwLangID, VAL32(IMAGE_RDE_OFFSET(pirdeLang)),pbResBase);
                                    }
                                }
                            }
                            else
                            {
                                g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,0,VAL32(IMAGE_RDE_OFFSET(pirdeName)),pbResBase);
                            }
                        }
                    }
                    else
                    {
                        g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,0,0,VAL32(IMAGE_RDE_OFFSET(pirdeType)),pbResBase);
                    }
                }
            } PAL_CPP_CATCH_ALL {
                ret= 0xDFFFFFFF;
                ulNumResNodes = 0;
            }
            PAL_CPP_ENDTRY
            // OK, all tree leaves are in ResourceNode structs, and ulNumResNodes ptrs are in g_prResNodePtr
            if(ulNumResNodes)
            {
                ret = 1;
#ifdef RES_FILE_DUMP_ENABLED

                _wfopen_s(&pF,wzFileName,L"wb");
                if(pF)
                {
                    // Dump them to pF
                    // Write dummy header
                    ResourceHeader  *pRH = new ResourceHeader();
                    fwrite(pRH,sizeof(ResourceHeader),1,pF);
                    SDELETE(pRH);
                    // For each resource write header and data
                    PAL_CPP_TRY {
                        for(i=0; i < ulNumResNodes; i++)
                        {
                            /*
                            sprintf_s(szString,SZSTRING_SIZE,"// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
                                i+1,
                                g_prResNodePtr[i]->ResHdr.dwTypeID,
                                g_prResNodePtr[i]->ResHdr.dwNameID,
                                g_prResNodePtr[i]->ResHdr.wLangID,
                                VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData),
                                VAL32(g_prResNodePtr[i]->DataEntry.Size));
                            printLine(NULL,szString);
                            */
                            g_prResNodePtr[i]->Save(pF);
                            SDELETE(g_prResNodePtr[i]);
                        }
                    }
                    PAL_CPP_CATCH_ALL {
                        ret= 0xDFFFFFFF;
                    }
                    PAL_CPP_ENDTRY
                    fclose(pF);
                }// end if file opened
                else ret = 0xEFFFFFFF;
#else
                // Dump to text, using wzFileName as GUICookie
                //char szString[4096];
                void* GUICookie = (void*)wzFileName;
                BYTE* pbData;
                printLine(GUICookie,"");
                sprintf(szString,"// ========== Win32 Resource Entries (%d) ========",ulNumResNodes);
                for(i=0; i < ulNumResNodes; i++)
                {
                    printLine(GUICookie,"");
                    sprintf(szString,"// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
                        i+1,
                        g_prResNodePtr[i]->ResHdr.dwTypeID,
                        g_prResNodePtr[i]->ResHdr.dwNameID,
                        g_prResNodePtr[i]->ResHdr.wLangID,
                        VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData),
                        VAL32(g_prResNodePtr[i]->DataEntry.Size));
                    printLine(GUICookie,szString);
                    if(g_pPELoader->getVAforRVA(VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData), (void **) &pbData))
                    {
                        strcat(g_szAsmCodeIndent,"//  ");
                        strcpy(szString,g_szAsmCodeIndent);
                        DumpByteArray(szString,pbData,VAL32(g_prResNodePtr[i]->DataEntry.Size),GUICookie);
                        printLine(GUICookie,szString);
                        g_szAsmCodeIndent[strlen(g_szAsmCodeIndent)-4] = 0;
                    }
                    SDELETE(g_prResNodePtr[i]);
                }
                ret = 1;
#endif
            } // end if there are nodes
        }// end if got ptr to resource
Example #2
0
DWORD	DumpResourceToFile(WCHAR*	wzFileName)
{

	BYTE*	pbResBase;
	FILE*	pF = NULL;
	DWORD ret = 0;
	DWORD	dwResDirRVA;
	DWORD	dwResDirSize;
	
	if (g_pPELoader->IsPE32())
	{
	    IMAGE_OPTIONAL_HEADER32 *pOptHeader = &(g_pPELoader->ntHeaders32()->OptionalHeader);
	
		dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
		dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
	}
	else
	{
	    IMAGE_OPTIONAL_HEADER64 *pOptHeader = &(g_pPELoader->ntHeaders64()->OptionalHeader);

		dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
		dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
	}

	if(dwResDirRVA && dwResDirSize)
	{
		ULONG L = (ULONG)wcslen(wzFileName)*3+3;
		char* szFileNameANSI = new char[L];
		memset(szFileNameANSI,0,L);
		WszWideCharToMultiByte(CP_ACP,0,wzFileName,-1,szFileNameANSI,L,NULL,NULL);
		pF = fopen(szFileNameANSI,"wb");
		delete [] szFileNameANSI;
 		if(pF)
		{
			if(g_pPELoader->getVAforRVA(dwResDirRVA, (void **) &pbResBase))
			{
				// First, pull out all resource nodes (tree leaves), see ResourceNode struct
				PIMAGE_RESOURCE_DIRECTORY pirdType = (PIMAGE_RESOURCE_DIRECTORY)pbResBase;
				PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeType = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbResBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
				DWORD	dwTypeID;
				unsigned short i,N = VAL16(pirdType->NumberOfNamedEntries)+VAL16(pirdType->NumberOfIdEntries);
				
				for(i=0; i < N; i++, pirdeType++)
				{
					dwTypeID = VAL32(IMAGE_RDE_NAME(pirdeType));
					if(IMAGE_RDE_OFFSET_FIELD(pirdeType, DataIsDirectory))
					{
						BYTE*	pbNameBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeType, OffsetToDirectory));
						PIMAGE_RESOURCE_DIRECTORY pirdName = (PIMAGE_RESOURCE_DIRECTORY)pbNameBase;
						PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeName = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbNameBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
						DWORD	dwNameID;
						unsigned short i,N = VAL16(pirdName->NumberOfNamedEntries)+VAL16(pirdName->NumberOfIdEntries);

						for(i=0; i < N; i++, pirdeName++)
						{
							dwNameID = VAL32(IMAGE_RDE_NAME(pirdeName));
							if(IMAGE_RDE_OFFSET_FIELD(pirdeName, DataIsDirectory))
							{
								BYTE*	pbLangBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeName, OffsetToDirectory));
								PIMAGE_RESOURCE_DIRECTORY pirdLang = (PIMAGE_RESOURCE_DIRECTORY)pbLangBase;
								PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeLang = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbLangBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
								DWORD	dwLangID;
								unsigned short i,N = VAL32(pirdLang->NumberOfNamedEntries)+VAL16(pirdLang->NumberOfIdEntries);

								for(i=0; i < N; i++, pirdeLang++)
								{
									dwLangID = IMAGE_RDE_NAME(pirdeLang);
									if(IMAGE_RDE_OFFSET_FIELD(pirdeLang, DataIsDirectory))
									{
										_ASSERTE(!"Resource hierarchy exceeds three levels");
									}
									else
									{
										if (g_prResNodePtr == NULL)
										{
											g_prResNodePtr = new DynamicArray<ResourceNode*>;
										}
										(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,dwLangID,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeLang)));
									}
								}
							}
							else
							{
								if (g_prResNodePtr == NULL)
								{
									g_prResNodePtr = new DynamicArray<ResourceNode*>;
								}
								(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeName)));
							}
						}
					}
					else
					{
						if (g_prResNodePtr == NULL)
						{
							g_prResNodePtr = new DynamicArray<ResourceNode*>;
						}
						(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,0,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeType)));
					}
				}
				// OK, all tree leaves are in ResourceNode structs, and ulNumResNodes ptrs are in g_prResNodePtr
				// Dump them to pF
				if(ulNumResNodes)
				{
					BYTE* pbData;
					// Write dummy header
					ResourceHeader	*pRH = new ResourceHeader();
					fwrite(pRH,sizeof(ResourceHeader),1,pF);
					delete pRH;
					DWORD	dwFiller;
					BYTE	bNil[3] = {0,0,0};
					// For each resource write header and data
					for(i=0; i < ulNumResNodes; i++)
					{
						if(g_pPELoader->getVAforRVA(VAL32((*g_prResNodePtr)[i]->DataEntry.OffsetToData), (void **) &pbData))
						{
							fwrite(&((*g_prResNodePtr)[i]->ResHdr),sizeof(ResourceHeader),1,pF);
							fwrite(pbData,VAL32((*g_prResNodePtr)[i]->DataEntry.Size),1,pF);
							dwFiller = VAL32((*g_prResNodePtr)[i]->DataEntry.Size) & 3;
							if(dwFiller)
							{
								dwFiller = 4 - dwFiller;
								fwrite(bNil,dwFiller,1,pF);
							}
						}
						delete (*g_prResNodePtr)[i];
					}
				}
				if (g_prResNodePtr)
				{
					delete g_prResNodePtr;
					g_prResNodePtr = NULL;
				}
				ulNumResNodes = 0;
				ret = 1;
			}// end if got ptr to resource
			else ret = 0xFFFFFFFF;
			if(pF) fclose(pF);
		}// end if file opened
		else ret = 0xEFFFFFFF;
	} // end if there is resource
	else ret = 0;
	return ret;
}