Редактирование PE файла.Вопросы.

Тема в разделе "WASM.BEGINNERS", создана пользователем _nic, 13 ноя 2010.

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Поставил перед собой задачу скопировать из одного экзе в другой экзе секцию ресурсов.
    А вот и вопросы:
    1.Нада ещё какие то структуры менять кроме _IMAGE_SECTION_HEADER секции ресурсов, и идущих после неё?
    2.Я сделал все правильно или где то косяк подкрался незаметно?
    Код (Text):
    1. bool PatchReses(char *source,char *target)
    2. {
    3.     HANDLE src=CreateFileA(source,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    4.     _IMAGE_NT_HEADERS *srcimage=new _IMAGE_NT_HEADERS;
    5.     _IMAGE_NT_HEADERS *targetimage=new _IMAGE_NT_HEADERS;
    6.     DWORD srcressz=0;
    7.     char *srcreses;
    8.     if(src!=INVALID_HANDLE_VALUE)
    9.     {
    10.         LARGE_INTEGER SZ;
    11.         ZeroMemory(&SZ,sizeof(SZ));
    12.         GetFileSizeEx(src,&SZ);
    13.         char *buf=new char[SZ.QuadPart+1024];
    14.         memset(buf,NULL,SZ.QuadPart+1024);
    15.         DWORD rb;
    16.         ReadFile(src,buf,SZ.QuadPart,&rb,0);
    17.         CloseHandle(src);
    18.         _IMAGE_DOS_HEADER stub;
    19.         memcpy(&stub,buf,sizeof(_IMAGE_DOS_HEADER));
    20.         buf+=stub.e_lfanew;
    21.         memcpy(srcimage,buf,sizeof(_IMAGE_NT_HEADERS));
    22.         _IMAGE_SECTION_HEADER *sections=new _IMAGE_SECTION_HEADER[srcimage->FileHeader.NumberOfSections];
    23.         buf+=sizeof(_IMAGE_NT_HEADERS);
    24.         memcpy(sections,buf,(srcimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER)));
    25.         buf-=sizeof(_IMAGE_NT_HEADERS);
    26.         buf-=stub.e_lfanew;
    27.         for(int i=0;i<srcimage->FileHeader.NumberOfSections;i++)
    28.         {
    29.             //printf("%.8s\n",sections[i].Name);
    30.             if(strcmp(".rsrc",(char*)sections[i].Name)==0)
    31.             {
    32.                 srcreses=new char[sections[i].SizeOfRawData];
    33.                 buf+=sections[i].PointerToRawData;
    34.                 memcpy(srcreses,buf,sections[i].SizeOfRawData);
    35.                 buf-=sections[i].PointerToRawData;
    36.                 srcressz=sections[i].SizeOfRawData;
    37.             }
    38.         }
    39.         delete []buf;
    40.     }
    41.     else
    42.     {
    43.         printf("Error open source exe\n");
    44.         return(false);
    45.     }
    46.     HANDLE tg=CreateFileA(target,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    47.     if(tg!=INVALID_HANDLE_VALUE)
    48.     {
    49.         LARGE_INTEGER SZ;
    50.         ZeroMemory(&SZ,sizeof(SZ));
    51.         GetFileSizeEx(tg,&SZ);
    52.         char *buf=new char[SZ.QuadPart+1024];
    53.         memset(buf,NULL,SZ.QuadPart+1024);
    54.         DWORD rb;
    55.         ReadFile(tg,buf,SZ.QuadPart,&rb,0);
    56.         CloseHandle(tg);
    57.         _IMAGE_DOS_HEADER stub;
    58.         memcpy(&stub,buf,sizeof(_IMAGE_DOS_HEADER));
    59.         buf+=stub.e_lfanew;
    60.         memcpy(targetimage,buf,sizeof(_IMAGE_NT_HEADERS));
    61.         _IMAGE_SECTION_HEADER *sections=new _IMAGE_SECTION_HEADER[targetimage->FileHeader.NumberOfSections];
    62.         buf+=sizeof(_IMAGE_NT_HEADERS);
    63.         memcpy(sections,buf,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER)));
    64.         buf-=sizeof(_IMAGE_NT_HEADERS);
    65.         buf-=stub.e_lfanew;
    66.         DWORD resesDelta=0;
    67.         for(int i=0;i<targetimage->FileHeader.NumberOfSections;i++)
    68.         {
    69.             if(strcmp(".rsrc",(char*)sections[i].Name)==0)
    70.             {
    71.                 resesDelta=srcressz-sections[i].SizeOfRawData;
    72.             }
    73.         }
    74.         char *newexe=new char[SZ.QuadPart+resesDelta];
    75.         for(int i=0;i<targetimage->FileHeader.NumberOfSections;i++)
    76.         {
    77.             if(strcmp(".rsrc",(char*)sections[i].Name)==0)
    78.             {
    79.                 memcpy(newexe,buf,sections[i].PointerToRawData);
    80.                 newexe+=sections[i].PointerToRawData;
    81.                 DWORD totalseek=0;
    82.                 _IMAGE_SECTION_HEADER *fixedsections=new _IMAGE_SECTION_HEADER[targetimage->FileHeader.NumberOfSections];
    83.                 memcpy(fixedsections,sections,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER)));
    84.                 fixedsections[i].SizeOfRawData=srcressz;
    85.                 for(int j=i;j<targetimage->FileHeader.NumberOfSections;j++)
    86.                 {
    87.                     buf+=sections[j].PointerToRawData;
    88.                     memcpy(newexe,buf,sections[j].SizeOfRawData);
    89.                     fixedsections[j].PointerToRawData=sections[j].PointerToRawData+resesDelta;
    90.                     newexe+=sections[j].SizeOfRawData;
    91.                     totalseek=totalseek+sections[j].SizeOfRawData;
    92.                 }
    93.                 newexe-=totalseek;
    94.                 newexe-=sections[i].PointerToRawData;
    95.                 _IMAGE_DOS_HEADER stubN;
    96.                 memcpy(&stubN,newexe,sizeof(_IMAGE_DOS_HEADER));
    97.                 newexe+=stubN.e_lfanew;
    98.                 newexe+=sizeof(_IMAGE_NT_HEADERS);
    99.                 memcpy(newexe,fixedsections,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER)));
    100.                 newexe-=stubN.e_lfanew+sizeof(_IMAGE_NT_HEADERS);
    101.                 HANDLE out=CreateFileA(target,GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
    102.                 DWORD wb;
    103.                 WriteFile(out,newexe,SZ.QuadPart+resesDelta,&wb,0);
    104.                 CloseHandle(out);
    105.                 break;
    106.             }
    107.         }
    108.     }
    109.     else
    110.     {
    111.         printf("Error open target exe");
    112.     }
    113.     delete srcimage;
    114.     delete targetimage;
    115.     delete []srcreses;
    116.     return(true);
    117. }
    ЗЫ:ресхакер говорит что неможет секцию с ресурсами загрузить.Но винда показывает иконку от экзешника донора,хоть и рецепиент не запускается.
     
  2. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Сильно в код не вчитывался, но тебе придется править еще саму секцию ресурсов. Кажется, в таблице данных есть поле с RVA. В твоем коде я не увидел этой правки.
     
  3. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    OffsetToData в секции ресурсов это RVA
     
  4. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    - Я не нашел в какой строчке в "target"-file копируется инфа из старой секции ресурсов;
    - Насколько я понял, в целевом файле ищется секция ресурсов и меняется на секцию из исходного файла, затем все последующие секции - делается попытка сдвинуть их далее путем коррекции PtrToRawData. Это все прекрасно но у тех секций также есть RVA. Будет как минимум overlap, поскольку теперь секция ресурсов будет загружена (частично) по тем же самым VA что и секция (секции) далее.
    - PE формат не запрещает иметь секции в одном физическом порядке, а загружать их (VA) в другом;
    - Метод ".rsrc" возможно не самый крутой метод определения секции ресурсов - вроде есть специальное поле в PE_Header.
    - ...
     
  5. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    с оговоркой, что порядок в памяти должен соответствовать порядку заголовков секций в файле. Если заголовки идут в одном порядке, а секции загружены в другом, произойдет ахтунг
     
  6. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Т.е. нада править _IMAGE_RESOURCE_DATA_ENTRY ?
     
  7. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia

    ужасно. так делать нельзя!
    выкинь то, что ты написал, изучи формат PE файла в целом и ресурсов в частности, а потом напиши код, с учётом новых знаний!
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    > ужасно. так делать нельзя!
    в винде можно :)
     
  9. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    С с секцией ресурсов так делать в принципе можно, а вообще это плохой стиль.

    Используйте RVA адреса из заголовка, и сопоставляйте их с секциями. Так элегантней выглядит, и код всегда будет работать правильно.

    А на счет самого сабжа, можно клонировать секцию, но потом надо будет, обойти все дерево ресурсов, и поправить RVA адрес на ресурса в структуре ResourceDataEntry, это все не сложно и делается минут за 10-15.
     
  10. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    RVA ресурсов в секции нада подогнать под размер секций идущих перед секцией ресурсов.Или я ничего непонял?
     
  11. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Ты себе формат ресурсов вообще представляешь? Вообще формат РЕ? Вот в ресурсах есть RVA данных. Чему должно быть равно это RVA? У тебя оно указывает на твои данные?

    Вообще, сначала возьми и попробуй скопировать любую другую секцию. Если получится и файл окажется рабочим, тогда будешь переходить к правке ресурсов. Сейчас мне кажется, что у тебя каша в голове по поводу всех этих секций.
     
  12. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    К старому RVA нужно прибавать дельту между старым и новым RVA секции ресурсов, вроде так.

    Не забывай что ресурсы вообще могут находится вне секции ресурсов, правда я такого изврата не видел, но теоретически могут.
     
  13. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    это как так? приведи теоретический пример
     
  14. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    http://www.sendspace.com/file/6k60nu

    Ресурс с ID == 768, указывает на RVA точки входа. Ес-но ресхаком не читается, но программа работает.

    Это еще не все, сейчас кое что пробую сделать.
     
  15. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Позьми notepad.exe запакуй его аспаком, и посмотри где находятся иконки (в секции аспака, которая никак не пренадлежит секции ресурсов), а где секция ресурсов, в ResourceDataEntry поле Offset указывает на следующую за секцией ресурсов секцию, проводник успешно показывает иконку ;)

    Не согласен?
     
  16. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    sysexit,

    А при чём «секция ресурсов» (я так понимаю, секция с именем ".rsrc") к тому, на что указывает IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]? Хотя это тебе и так понятно, похоже. :derisive:
     
  17. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    baldr, не понял тебя, перефразируй.
     
  18. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    sysexit,

    «Секция ресурсов» — это что? Многим кажется (тебе, вроде, нет), что ресурсы обязательно лежат в секции с именем ".rsrc" (а релоки — в ".reloc"/".rdata" :derisive:, что по сути есть заблуждение. И первые, и вторые живут там, куда указывает соответствующая ссылка из IMAGE_OPTIONAL_HEADER.DataDirectory[]. Вроде так.

    Знакомые с fasm товарищи понимают, что всё может быть в одной секции. Правда антивири кирпичами обделываются от этого. :derisive:
     
  19. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Ооо, я думал ты что-то дельное хотел сказать, по этому поводу я еще в первом своем посте из этого топика отписывался, дураку понятно что не надо опеределять релоки по секции ".reloc".
     
  20. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Также не хотелось бы "ободрять" автора но в этой секции ресурсов наверное могут быть _относительные_ смещения отдельных элементов - их возможно тоже надо тискать (при копировании секции в секцию).

    ... с другой стороны напейсал такую прогу - щитай PE Viewer/editor is almost ready!