пишу пакер. подскажите кто знает как в ресурсах найти иконку. чень бы хотелось сжимать ресурс оставляя только иконку.
Код (Text): void Align4(IMAGEINFORMATION* Info) { Info->NowOffset=AlignUp(Info->NowOffset,4); Info->NowRva=AlignUp(Info->NowRva,4); return; } byte* GetNowPointer(IMAGEINFORMATION* Info) { return ((byte*)Info->pFile+Info->NowOffset); } VOID CopyBlock(IMAGEINFORMATION* Info,BYTE* StartBlock,DWORD BlockSize) { BYTE* Pointer = GetNowPointer(Info); Info->NowOffset+=BlockSize; Info->NowRva+=BlockSize; for (DWORD i=0;i!=BlockSize;i++) *(Pointer + i)=*((StartBlock)+i); return; } VOID CopyDword(IMAGEINFORMATION* Info,DWORD nDword) { DWORD* Pointer=(DWORD*)GetNowPointer(Info); Info->NowOffset+=4; Info->NowRva+=4; *Pointer=nDword; return; } //Resource_processing: /* Обработка директории ресурсов. Вырезаютя не нужные ресурсы */ //================================================================================ //вход указатель на начало директории ресурсов // и указатель на 1 из IMAGE_RESOURCE_DIRECTORY_ENTRY //выход указаатель на первый IMAGE_RESOURCE_DATA_ENTRY для // указанного IMAGE_RESOURCE_DIRECTORY_ENTRY PIMAGE_RESOURCE_DATA_ENTRY GetResource (PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY_ENTRY CurrDirEntry) { PIMAGE_RESOURCE_DIRECTORY pCurrResDir; while (CurrDirEntry->DataIsDirectory) { pCurrResDir=(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory); CurrDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrResDir+1); } return (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory); } //=============================================================================== //Функция вычисляет RVA первого ресурса для ветки заданной в pCurrDir // pMainDir-указатель на начало ресурсов DWORD GetFirstResourceRVA (PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY pCurrDir) { DWORD MaxResSze=-1; PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry; PIMAGE_RESOURCE_DATA_ENTRY pDataEntry; WORD nNumberOfItem= pCurrDir->NumberOfIdEntries+pCurrDir->NumberOfNamedEntries; pDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrDir+1); while (nNumberOfItem) { if (pDirEntry->DataIsDirectory) { DWORD Temple=GetFirstResourceRVA(pMainDir,(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+pDirEntry->OffsetToDirectory)); if (Temple<MaxResSze) MaxResSze=Temple; } else { pDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)((BYTE *)pMainDir+pDirEntry->OffsetToDirectory); if (pDataEntry->OffsetToData<MaxResSze) MaxResSze=pDataEntry->OffsetToData;//+pDataEntry->Size; } pDirEntry++; nNumberOfItem--; } return (MaxResSze); } DWORD CopyResourceBranch(IMAGEINFORMATION* Info,PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY_ENTRY CurrDirEntry,WORD nNumberOfItemsForCopy) { PIMAGE_RESOURCE_DIRECTORY pCurrResDir; PIMAGE_RESOURCE_DATA_ENTRY pDataDir; DWORD BranchSize=0; pCurrResDir=(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory); CurrDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrResDir+1); WORD nNumberOfItem=pCurrResDir->NumberOfIdEntries+pCurrResDir->NumberOfNamedEntries; //если на входе >ресурсов чеместь на самом деле, то копируем всё что есть if (nNumberOfItemsForCopy>nNumberOfItem) nNumberOfItemsForCopy=nNumberOfItem; while (nNumberOfItemsForCopy) { pDataDir=GetResource(pMainDir,CurrDirEntry); DWORD ResRva=pDataDir->OffsetToData; BranchSize+=pDataDir->Size; pDataDir->OffsetToData=Info->NowRva;//NowOffset; CopyBlock(Info,((BYTE*)Info->hMappAddr+ResRva),pDataDir->Size); //затираем ресурс на старом месте // DWORD i=pDataDir->Size; // while () CurrDirEntry++; nNumberOfItemsForCopy--; } return (BranchSize); } //======================================================== //======================================================== void ResourceProtection(IMAGEINFORMATION* Info,UNPAKED_DATA* UnpackerInfo) { DWORD ResSize=Info->pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size; DWORD ResRVA=Info->pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; DWORD NewResourceSize=0; DWORD NewResRVA=Info->NowRva; if (! ResSize) { OutputDebugStringW(L"Resource directory not found"); return ; } PIMAGE_RESOURCE_DIRECTORY pMainResourceDir,pNewMainResourceDir;//pCurrResDir, PIMAGE_RESOURCE_DIRECTORY_ENTRY pMainDirEntry,pDirEntry; PIMAGE_RESOURCE_DATA_ENTRY pDataDir; WORD nNumderOfIcon; /*получаем количество иконок которые надо сохранить*/ pMainResourceDir=(PIMAGE_RESOURCE_DIRECTORY)(((BYTE *)Info->hMappAddr)+ResRVA); pMainDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pMainResourceDir+1); pDirEntry=pMainDirEntry; WORD nNumderOfItem=pMainResourceDir->NumberOfIdEntries+pMainResourceDir->NumberOfNamedEntries; WORD i=nNumderOfItem; while (i) { if (pDirEntry->Id==0xe) //RT_GROUP_ICON { pDataDir=GetResource(pMainResourceDir,pDirEntry); nNumderOfIcon=(pDataDir->Size-4)/0xe; break; } pDirEntry++; i--; } //получаем размер директории ресурсов без самих ресурсов DWORD ResHeadSize=GetFirstResourceRVA (pMainResourceDir,pMainResourceDir)-ResRVA; NewResourceSize=ResHeadSize; pNewMainResourceDir=(PIMAGE_RESOURCE_DIRECTORY)GetNowPointer(Info); pMainDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pNewMainResourceDir+1); //теперь всю информацию берём из копии ресурсов. можно всё тереть. CopyBlock(Info,(BYTE*)pMainResourceDir,ResHeadSize); //Копируем нужные ветки pDirEntry=pMainDirEntry; i=nNumderOfItem; while (i) { DWORD BranchSize; switch (pDirEntry->Id) { case RT_ICON: //icon BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,nNumderOfIcon); NewResourceSize+=BranchSize; break; case RT_GROUP_ICON: //group icon BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,1); NewResourceSize+=BranchSize; break; case RT_MANIFEST: //manifest BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,-1); NewResourceSize+=BranchSize; break; case RT_VERSION: // versio information BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,1); NewResourceSize+=BranchSize; break; } pDirEntry++; i--; } Info->pPEHeaderInFile->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress=NewResRVA; Info->pPEHeaderInFile->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size=NewResourceSize; return ; } Вызывать надо ф-ию ResourceProtection. Для работы нам понадобятся следующие входные параметры, установленные в IMAGEINFORMATION - hMappAddr - указатель на образ обрабатываемого файла, отмапленного с атрибутом SEC_IMAGE pPEHeader - указатель на оригинальный PE заголовок. pFile - указатель на область памяти в которой создаётся запакованный образ pPEHeaderInFile - указатель на PE заголовок, который будет записан в запакованный файл. NowOffset и NowRVA , хм как бы это объяснить понятнее. Смотри есть указатель на собираемый образ pFile и есть текущая позиция, куда идёт запись. Так вот NowOffset - смещение этой позиции, а NowRVA - это RVA этой позиции во время выполнения запакованного образа. Вот, вроде ничего не забыл. Вообще как это делать правильно я не знаю, всё что здесь написано просто-напросто рнезультаты моих копаний в pe формате, но работает. Если надо - то вечером выложу код а асме, но он старый, ужасный и вообще без комментов. p.s. Можно порыться в сорцах upx
мапинг файла делать некатит. несмог заставить упикс сжать ресурс и оставить иконку. былоб неплохо если там без мапинга. а лучше всего будет без кода тоесть простое объяснение где именно в ресурсе сидит иконка. всмысле как оличить иконку от всего остального. а код я уже свой напишу.
Что же так? В принципе маппинг здесь совершенно не причём - это лишь способ облегчить себе жизнь при доступе к полям всяких директорий. На словах всё довольно просто в PIMAGE_RESOURCE_DIRECTORY_ENTRY есть поле Id, которое и есть тип ресурса. Чтобы иконка выжила нужно оставить незапакованными ресурсы с Id = RT_ICON, и первый ресурс с Id = RT_GROUP_ICON. Так же, чтобы файл работал нужно оставить ресурсы с Id = RT_MANIFEST. Id = RT_VERSION - отвечает за информацию о версии файла - тоже желательно оставить незапакованными.