Поставил перед собой задачу скопировать из одного экзе в другой экзе секцию ресурсов. А вот и вопросы: 1.Нада ещё какие то структуры менять кроме _IMAGE_SECTION_HEADER секции ресурсов, и идущих после неё? 2.Я сделал все правильно или где то косяк подкрался незаметно? Код (Text): bool PatchReses(char *source,char *target) { HANDLE src=CreateFileA(source,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); _IMAGE_NT_HEADERS *srcimage=new _IMAGE_NT_HEADERS; _IMAGE_NT_HEADERS *targetimage=new _IMAGE_NT_HEADERS; DWORD srcressz=0; char *srcreses; if(src!=INVALID_HANDLE_VALUE) { LARGE_INTEGER SZ; ZeroMemory(&SZ,sizeof(SZ)); GetFileSizeEx(src,&SZ); char *buf=new char[SZ.QuadPart+1024]; memset(buf,NULL,SZ.QuadPart+1024); DWORD rb; ReadFile(src,buf,SZ.QuadPart,&rb,0); CloseHandle(src); _IMAGE_DOS_HEADER stub; memcpy(&stub,buf,sizeof(_IMAGE_DOS_HEADER)); buf+=stub.e_lfanew; memcpy(srcimage,buf,sizeof(_IMAGE_NT_HEADERS)); _IMAGE_SECTION_HEADER *sections=new _IMAGE_SECTION_HEADER[srcimage->FileHeader.NumberOfSections]; buf+=sizeof(_IMAGE_NT_HEADERS); memcpy(sections,buf,(srcimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER))); buf-=sizeof(_IMAGE_NT_HEADERS); buf-=stub.e_lfanew; for(int i=0;i<srcimage->FileHeader.NumberOfSections;i++) { //printf("%.8s\n",sections[i].Name); if(strcmp(".rsrc",(char*)sections[i].Name)==0) { srcreses=new char[sections[i].SizeOfRawData]; buf+=sections[i].PointerToRawData; memcpy(srcreses,buf,sections[i].SizeOfRawData); buf-=sections[i].PointerToRawData; srcressz=sections[i].SizeOfRawData; } } delete []buf; } else { printf("Error open source exe\n"); return(false); } HANDLE tg=CreateFileA(target,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(tg!=INVALID_HANDLE_VALUE) { LARGE_INTEGER SZ; ZeroMemory(&SZ,sizeof(SZ)); GetFileSizeEx(tg,&SZ); char *buf=new char[SZ.QuadPart+1024]; memset(buf,NULL,SZ.QuadPart+1024); DWORD rb; ReadFile(tg,buf,SZ.QuadPart,&rb,0); CloseHandle(tg); _IMAGE_DOS_HEADER stub; memcpy(&stub,buf,sizeof(_IMAGE_DOS_HEADER)); buf+=stub.e_lfanew; memcpy(targetimage,buf,sizeof(_IMAGE_NT_HEADERS)); _IMAGE_SECTION_HEADER *sections=new _IMAGE_SECTION_HEADER[targetimage->FileHeader.NumberOfSections]; buf+=sizeof(_IMAGE_NT_HEADERS); memcpy(sections,buf,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER))); buf-=sizeof(_IMAGE_NT_HEADERS); buf-=stub.e_lfanew; DWORD resesDelta=0; for(int i=0;i<targetimage->FileHeader.NumberOfSections;i++) { if(strcmp(".rsrc",(char*)sections[i].Name)==0) { resesDelta=srcressz-sections[i].SizeOfRawData; } } char *newexe=new char[SZ.QuadPart+resesDelta]; for(int i=0;i<targetimage->FileHeader.NumberOfSections;i++) { if(strcmp(".rsrc",(char*)sections[i].Name)==0) { memcpy(newexe,buf,sections[i].PointerToRawData); newexe+=sections[i].PointerToRawData; DWORD totalseek=0; _IMAGE_SECTION_HEADER *fixedsections=new _IMAGE_SECTION_HEADER[targetimage->FileHeader.NumberOfSections]; memcpy(fixedsections,sections,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER))); fixedsections[i].SizeOfRawData=srcressz; for(int j=i;j<targetimage->FileHeader.NumberOfSections;j++) { buf+=sections[j].PointerToRawData; memcpy(newexe,buf,sections[j].SizeOfRawData); fixedsections[j].PointerToRawData=sections[j].PointerToRawData+resesDelta; newexe+=sections[j].SizeOfRawData; totalseek=totalseek+sections[j].SizeOfRawData; } newexe-=totalseek; newexe-=sections[i].PointerToRawData; _IMAGE_DOS_HEADER stubN; memcpy(&stubN,newexe,sizeof(_IMAGE_DOS_HEADER)); newexe+=stubN.e_lfanew; newexe+=sizeof(_IMAGE_NT_HEADERS); memcpy(newexe,fixedsections,(targetimage->FileHeader.NumberOfSections*sizeof(_IMAGE_SECTION_HEADER))); newexe-=stubN.e_lfanew+sizeof(_IMAGE_NT_HEADERS); HANDLE out=CreateFileA(target,GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); DWORD wb; WriteFile(out,newexe,SZ.QuadPart+resesDelta,&wb,0); CloseHandle(out); break; } } } else { printf("Error open target exe"); } delete srcimage; delete targetimage; delete []srcreses; return(true); } ЗЫ:ресхакер говорит что неможет секцию с ресурсами загрузить.Но винда показывает иконку от экзешника донора,хоть и рецепиент не запускается.
Сильно в код не вчитывался, но тебе придется править еще саму секцию ресурсов. Кажется, в таблице данных есть поле с RVA. В твоем коде я не увидел этой правки.
- Я не нашел в какой строчке в "target"-file копируется инфа из старой секции ресурсов; - Насколько я понял, в целевом файле ищется секция ресурсов и меняется на секцию из исходного файла, затем все последующие секции - делается попытка сдвинуть их далее путем коррекции PtrToRawData. Это все прекрасно но у тех секций также есть RVA. Будет как минимум overlap, поскольку теперь секция ресурсов будет загружена (частично) по тем же самым VA что и секция (секции) далее. - PE формат не запрещает иметь секции в одном физическом порядке, а загружать их (VA) в другом; - Метод ".rsrc" возможно не самый крутой метод определения секции ресурсов - вроде есть специальное поле в PE_Header. - ...
с оговоркой, что порядок в памяти должен соответствовать порядку заголовков секций в файле. Если заголовки идут в одном порядке, а секции загружены в другом, произойдет ахтунг
ужасно. так делать нельзя! выкинь то, что ты написал, изучи формат PE файла в целом и ресурсов в частности, а потом напиши код, с учётом новых знаний!
С с секцией ресурсов так делать в принципе можно, а вообще это плохой стиль. Используйте RVA адреса из заголовка, и сопоставляйте их с секциями. Так элегантней выглядит, и код всегда будет работать правильно. А на счет самого сабжа, можно клонировать секцию, но потом надо будет, обойти все дерево ресурсов, и поправить RVA адрес на ресурса в структуре ResourceDataEntry, это все не сложно и делается минут за 10-15.
RVA ресурсов в секции нада подогнать под размер секций идущих перед секцией ресурсов.Или я ничего непонял?
Ты себе формат ресурсов вообще представляешь? Вообще формат РЕ? Вот в ресурсах есть RVA данных. Чему должно быть равно это RVA? У тебя оно указывает на твои данные? Вообще, сначала возьми и попробуй скопировать любую другую секцию. Если получится и файл окажется рабочим, тогда будешь переходить к правке ресурсов. Сейчас мне кажется, что у тебя каша в голове по поводу всех этих секций.
К старому RVA нужно прибавать дельту между старым и новым RVA секции ресурсов, вроде так. Не забывай что ресурсы вообще могут находится вне секции ресурсов, правда я такого изврата не видел, но теоретически могут.
http://www.sendspace.com/file/6k60nu Ресурс с ID == 768, указывает на RVA точки входа. Ес-но ресхаком не читается, но программа работает. Это еще не все, сейчас кое что пробую сделать.
Позьми notepad.exe запакуй его аспаком, и посмотри где находятся иконки (в секции аспака, которая никак не пренадлежит секции ресурсов), а где секция ресурсов, в ResourceDataEntry поле Offset указывает на следующую за секцией ресурсов секцию, проводник успешно показывает иконку Не согласен?
sysexit, А при чём «секция ресурсов» (я так понимаю, секция с именем ".rsrc") к тому, на что указывает IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]? Хотя это тебе и так понятно, похоже.
sysexit, «Секция ресурсов» — это что? Многим кажется (тебе, вроде, нет), что ресурсы обязательно лежат в секции с именем ".rsrc" (а релоки — в ".reloc"/".rdata" , что по сути есть заблуждение. И первые, и вторые живут там, куда указывает соответствующая ссылка из IMAGE_OPTIONAL_HEADER.DataDirectory[]. Вроде так. Знакомые с fasm товарищи понимают, что всё может быть в одной секции. Правда антивири кирпичами обделываются от этого.
Ооо, я думал ты что-то дельное хотел сказать, по этому поводу я еще в первом своем посте из этого топика отписывался, дураку понятно что не надо опеределять релоки по секции ".reloc".
Также не хотелось бы "ободрять" автора но в этой секции ресурсов наверное могут быть _относительные_ смещения отдельных элементов - их возможно тоже надо тискать (при копировании секции в секцию). ... с другой стороны напейсал такую прогу - щитай PE Viewer/editor is almost ready!