помогите с упаковкой ресурсов

Тема в разделе "WASM.WIN32", создана пользователем doctor_Ice, 13 авг 2007.

  1. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    пишу пакер. подскажите кто знает как в ресурсах найти иконку. чень бы хотелось сжимать ресурс оставляя только иконку.
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Код (Text):
    1. void Align4(IMAGEINFORMATION* Info)
    2. {
    3.     Info->NowOffset=AlignUp(Info->NowOffset,4);
    4.     Info->NowRva=AlignUp(Info->NowRva,4);
    5.     return;
    6. }
    7.  
    8. byte*   GetNowPointer(IMAGEINFORMATION* Info)
    9. {
    10.     return ((byte*)Info->pFile+Info->NowOffset);
    11. }
    12.  
    13. VOID CopyBlock(IMAGEINFORMATION* Info,BYTE* StartBlock,DWORD BlockSize)
    14. {
    15. BYTE* Pointer = GetNowPointer(Info);
    16.     Info->NowOffset+=BlockSize;
    17.     Info->NowRva+=BlockSize;
    18.     for (DWORD i=0;i!=BlockSize;i++) *(Pointer + i)=*((StartBlock)+i);
    19.     return;
    20. }
    21.  
    22. VOID CopyDword(IMAGEINFORMATION* Info,DWORD nDword)
    23. {
    24. DWORD* Pointer=(DWORD*)GetNowPointer(Info);
    25.     Info->NowOffset+=4;
    26.     Info->NowRva+=4;
    27.     *Pointer=nDword;
    28.     return;
    29. }
    30.  
    31.  
    32. //Resource_processing:
    33. /*
    34. Обработка директории ресурсов.
    35. Вырезаютя не нужные ресурсы
    36. */
    37.  
    38.  
    39. //================================================================================
    40. //вход      указатель на начало директории ресурсов
    41. //          и указатель на 1 из IMAGE_RESOURCE_DIRECTORY_ENTRY
    42. //выход    указаатель на первый IMAGE_RESOURCE_DATA_ENTRY для
    43. //          указанного IMAGE_RESOURCE_DIRECTORY_ENTRY
    44. PIMAGE_RESOURCE_DATA_ENTRY GetResource  (PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY_ENTRY CurrDirEntry)
    45.     {
    46. PIMAGE_RESOURCE_DIRECTORY pCurrResDir;
    47.     while (CurrDirEntry->DataIsDirectory)
    48.         {
    49.         pCurrResDir=(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory);
    50.         CurrDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrResDir+1);
    51.         }
    52.     return (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory);
    53.     }
    54. //===============================================================================
    55. //Функция вычисляет RVA первого ресурса для ветки заданной в pCurrDir
    56. // pMainDir-указатель на начало ресурсов
    57. DWORD GetFirstResourceRVA (PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY pCurrDir)
    58.     {
    59. DWORD MaxResSze=-1;
    60. PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry;
    61. PIMAGE_RESOURCE_DATA_ENTRY  pDataEntry;
    62.  
    63.     WORD nNumberOfItem= pCurrDir->NumberOfIdEntries+pCurrDir->NumberOfNamedEntries;
    64.     pDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrDir+1);
    65.     while (nNumberOfItem)
    66.         {
    67.         if (pDirEntry->DataIsDirectory)
    68.             {
    69.             DWORD Temple=GetFirstResourceRVA(pMainDir,(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+pDirEntry->OffsetToDirectory));
    70.             if (Temple<MaxResSze) MaxResSze=Temple;
    71.             }
    72.            
    73.         else
    74.             {
    75.             pDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)((BYTE *)pMainDir+pDirEntry->OffsetToDirectory);
    76.             if (pDataEntry->OffsetToData<MaxResSze) MaxResSze=pDataEntry->OffsetToData;//+pDataEntry->Size;
    77.             }
    78.         pDirEntry++;
    79.         nNumberOfItem--;
    80.         }
    81.     return (MaxResSze);
    82.     }
    83. DWORD CopyResourceBranch(IMAGEINFORMATION* Info,PIMAGE_RESOURCE_DIRECTORY pMainDir,PIMAGE_RESOURCE_DIRECTORY_ENTRY CurrDirEntry,WORD nNumberOfItemsForCopy)
    84. {
    85. PIMAGE_RESOURCE_DIRECTORY pCurrResDir;
    86. PIMAGE_RESOURCE_DATA_ENTRY pDataDir;
    87. DWORD BranchSize=0;
    88.     pCurrResDir=(PIMAGE_RESOURCE_DIRECTORY)((BYTE *)pMainDir+CurrDirEntry->OffsetToDirectory);
    89.     CurrDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pCurrResDir+1);
    90.     WORD nNumberOfItem=pCurrResDir->NumberOfIdEntries+pCurrResDir->NumberOfNamedEntries;
    91.         //если на входе >ресурсов чеместь на самом деле, то копируем всё что есть
    92.     if (nNumberOfItemsForCopy>nNumberOfItem) nNumberOfItemsForCopy=nNumberOfItem;
    93.     while (nNumberOfItemsForCopy)
    94.         {
    95.         pDataDir=GetResource(pMainDir,CurrDirEntry);
    96.         DWORD ResRva=pDataDir->OffsetToData;
    97.         BranchSize+=pDataDir->Size;
    98.         pDataDir->OffsetToData=Info->NowRva;//NowOffset;
    99.         CopyBlock(Info,((BYTE*)Info->hMappAddr+ResRva),pDataDir->Size);
    100.         //затираем ресурс на старом месте
    101. //      DWORD i=pDataDir->Size;
    102. //      while ()
    103.        
    104.         CurrDirEntry++;
    105.         nNumberOfItemsForCopy--;
    106.         }
    107.     return (BranchSize);
    108. }
    109.  
    110.  
    111. //========================================================
    112. //========================================================
    113. void ResourceProtection(IMAGEINFORMATION* Info,UNPAKED_DATA* UnpackerInfo)
    114. {  
    115. DWORD ResSize=Info->pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
    116. DWORD ResRVA=Info->pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
    117. DWORD NewResourceSize=0;
    118. DWORD NewResRVA=Info->NowRva;
    119.     if (! ResSize)
    120.         {
    121.         OutputDebugStringW(L"Resource directory not found");
    122.         return ;
    123.         }
    124. PIMAGE_RESOURCE_DIRECTORY pMainResourceDir,pNewMainResourceDir;//pCurrResDir,
    125. PIMAGE_RESOURCE_DIRECTORY_ENTRY pMainDirEntry,pDirEntry;
    126. PIMAGE_RESOURCE_DATA_ENTRY pDataDir;
    127. WORD nNumderOfIcon;
    128.  
    129. /*получаем количество иконок которые надо сохранить*/
    130.     pMainResourceDir=(PIMAGE_RESOURCE_DIRECTORY)(((BYTE *)Info->hMappAddr)+ResRVA);
    131.     pMainDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pMainResourceDir+1);
    132.     pDirEntry=pMainDirEntry;
    133.  
    134.     WORD nNumderOfItem=pMainResourceDir->NumberOfIdEntries+pMainResourceDir->NumberOfNamedEntries;
    135.     WORD i=nNumderOfItem;
    136.     while (i)
    137.         {
    138.         if (pDirEntry->Id==0xe) //RT_GROUP_ICON
    139.             {
    140.             pDataDir=GetResource(pMainResourceDir,pDirEntry);
    141.             nNumderOfIcon=(pDataDir->Size-4)/0xe;
    142.             break;         
    143.             }
    144.         pDirEntry++;
    145.         i--;
    146.         }
    147. //получаем размер директории ресурсов без самих ресурсов
    148.     DWORD ResHeadSize=GetFirstResourceRVA (pMainResourceDir,pMainResourceDir)-ResRVA;
    149.     NewResourceSize=ResHeadSize;
    150.     pNewMainResourceDir=(PIMAGE_RESOURCE_DIRECTORY)GetNowPointer(Info);
    151.     pMainDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pNewMainResourceDir+1);
    152.                         //теперь всю информацию берём из копии ресурсов. можно всё тереть.
    153.     CopyBlock(Info,(BYTE*)pMainResourceDir,ResHeadSize);
    154. //Копируем нужные ветки
    155.     pDirEntry=pMainDirEntry;
    156.     i=nNumderOfItem;
    157.     while (i)
    158.         {
    159. DWORD BranchSize;
    160.         switch (pDirEntry->Id)
    161.             {
    162.             case RT_ICON:       //icon
    163.                 BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,nNumderOfIcon);
    164.                 NewResourceSize+=BranchSize;
    165.                 break;
    166.             case RT_GROUP_ICON: //group icon
    167.                 BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,1);
    168.                 NewResourceSize+=BranchSize;
    169.                 break;
    170.             case RT_MANIFEST:   //manifest
    171.                 BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,-1);
    172.                 NewResourceSize+=BranchSize;
    173.                 break;
    174.             case RT_VERSION:        // versio information
    175.                 BranchSize=CopyResourceBranch(Info,pNewMainResourceDir,pDirEntry,1);
    176.                 NewResourceSize+=BranchSize;
    177.                 break;
    178.             }
    179.         pDirEntry++;
    180.         i--;
    181.         }
    182.     Info->pPEHeaderInFile->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress=NewResRVA;
    183.     Info->pPEHeaderInFile->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size=NewResourceSize;
    184.     return ;       
    185. }
    Вызывать надо ф-ию ResourceProtection.
    Для работы нам понадобятся следующие входные параметры, установленные в IMAGEINFORMATION -
    hMappAddr - указатель на образ обрабатываемого файла, отмапленного с атрибутом SEC_IMAGE
    pPEHeader - указатель на оригинальный PE заголовок.
    pFile - указатель на область памяти в которой создаётся запакованный образ
    pPEHeaderInFile - указатель на PE заголовок, который будет записан в запакованный файл.
    NowOffset и NowRVA , хм как бы это объяснить понятнее. Смотри есть указатель на собираемый образ pFile и есть текущая позиция, куда идёт запись. Так вот NowOffset - смещение этой позиции, а NowRVA - это RVA этой позиции во время выполнения запакованного образа.
    Вот, вроде ничего не забыл.

    Вообще как это делать правильно я не знаю, всё что здесь написано просто-напросто рнезультаты моих копаний в pe формате, но работает.
    Если надо - то вечером выложу код а асме, но он старый, ужасный и вообще без комментов.

    p.s. Можно порыться в сорцах upx
     
  3. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    мапинг файла делать некатит.

    несмог заставить упикс сжать ресурс и оставить иконку.

    былоб неплохо если там без мапинга.

    а лучше всего будет без кода тоесть простое объяснение где именно в ресурсе сидит иконка. всмысле как оличить иконку от всего остального. а код я уже свой напишу.
     
  4. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Что же так?:) В принципе маппинг здесь совершенно не причём - это лишь способ облегчить себе жизнь при доступе к полям всяких директорий.

    На словах всё довольно просто в PIMAGE_RESOURCE_DIRECTORY_ENTRY есть поле Id, которое и есть тип ресурса. Чтобы иконка выжила нужно оставить незапакованными ресурсы с Id = RT_ICON, и первый ресурс с Id = RT_GROUP_ICON. Так же, чтобы файл работал нужно оставить ресурсы с Id = RT_MANIFEST. Id = RT_VERSION - отвечает за информацию о версии файла - тоже желательно оставить незапакованными.
     
  5. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    asd
    во спасибо! именно такого ответа я и хотел.