В PE формате столько всего.Аж крыша едет.Спасибо за полезную инфу теперь я знаю как получать указатель на нужные секции.Только это настолько запутанный формат что он сбил меня с ума разума.Вообщем нахожу секцию ресурсов,выделяю под неё память копирую туда а VS матерится что указатель на блок памяти не валиден Я уж совсем в потеряшках,секция то находится ипамять под неё выделяется,и копирую её туда.Но что то не то Код (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(srcimage->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress==sections[i].VirtualAddress) { 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(targetimage->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress==sections[i].VirtualAddress) { resesDelta=srcressz-sections[i].SizeOfRawData; } } char *newexe=new char[SZ.QuadPart+resesDelta]; for(int i=0;i<targetimage->FileHeader.NumberOfSections;i++) { if(targetimage->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress==sections[i].VirtualAddress) { DWORD irdsz=sizeof(_IMAGE_RESOURCE_DIRECTORY),irdEsz=sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY),resdatsz=sizeof(_IMAGE_RESOURCE_DATA_ENTRY); DWORD acum=irdsz; _IMAGE_RESOURCE_DATA_ENTRY dataE; //printf("%d",srcressz); srcreses+=irdsz; for(;;) { ZeroMemory(&dataE,resdatsz); srcreses+=irdEsz; memcpy(&dataE,srcreses,resdatsz);//тут еррор acum=acum+irdEsz+resdatsz; dataE.OffsetToData=/*dataE.Size+*/acum+sections[i].PointerToRawData;//calculate new RVA memcpy(srcreses,&dataE,resdatsz); srcreses+=(resdatsz+dataE.Size); acum=acum+resdatsz+dataE.Size; if(acum==srcressz){break;} } srcreses-=srcressz; printf("!"); //////////////////////////////////////////////////////////// memcpy(newexe,buf,sections[i].PointerToRawData); newexe+=sections[i].PointerToRawData; memcpy(newexe,srcreses,srcressz); newexe+=srcressz; 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; i++; 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; fixedsections[j].VirtualAddress=sections[j].VirtualAddress+resesDelta; newexe+=sections[j].SizeOfRawData; totalseek=totalseek+sections[j].SizeOfRawData; } newexe-=totalseek; newexe-=sections[i-1].PointerToRawData; newexe-=srcressz; _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); } Надеюсь найдется добрый человек который покажет мне мою ошибку работы с памятью.
ну ты хотя бы строку указывай, на которую у тебя студия ругается. Мой тебе совет: а) пиши все на апишках, а не этих вот макросах; б) хотя бы ентерами разделяй части кода (например, один блок - чтение, второй - подготовка, третий - запись, четвертый - корректировка). Иначе ты не только себе мозг сломаешь таким кодом
Строка в каментах указанна.Немогу понять почему студия ругается на блок памяти с скопированной секцией как на несуществующий указатель О_о,я наверно что топропустил очевидное Но немогу понять что
_nic Вроде бы можно найти исходники ResHacker'а (или другого редактора - уже не помню), они на Делфи и там многое сделано через виндовые АПИ... лучше не знаю, sorry.
Я немогу понять что находится за _IMAGE_RESOURCE_DIRECTORY_ENTRY когда я делаю сдвиг на sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY) то не попадаю на _IMAGE_RESOURCE_DATA_ENTRY.
так не бывает. Они идут подряд. Покажи код. У меня ощущение, что ты в студии к указателю прибавляешь размер струткуры, а не 1
Вот для теста написал Код (Text): DWORD irdsz=sizeof(_IMAGE_RESOURCE_DIRECTORY),irdEsz=sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY),resdatsz=sizeof(_IMAGE_RESOURCE_DATA_ENTRY); DWORD acum=irdsz; _IMAGE_RESOURCE_DATA_ENTRY *dataE=new _IMAGE_RESOURCE_DATA_ENTRY; _IMAGE_RESOURCE_DIRECTORY ird; _IMAGE_RESOURCE_DIRECTORY_ENTRY erde; ZeroMemory(&ird,irdsz); memcpy(&ird,srcreses,irdsz); printf("%d:%d\n",ird.NumberOfIdEntries,ird.NumberOfNamedEntries); srcreses+=irdsz; ZeroMemory(&erde,irdsz); memcpy(&erde,srcreses,irdEsz); printf("%d:%d\n",erde.Id,erde.OffsetToDirectory); srcreses+=irdEsz; ZeroMemory(dataE,resdatsz); memcpy(dataE,srcreses,resdatsz); printf("%d\n",dataE->Size); getch(); А вот что оно выводит:
Код (Text): printf("%d:%d\n",erde.Id,erde.OffsetToDirectory); замени на printf("%d:%d, is a _directory_ = %u\n",erde.Id,erde.OffsetToDirectory, erde.DataIsDirectory)); и подумай, что не так
За ней следующая IMAGE_RESOURCE_DIRECTORY_ENTRY, что же ещё там может находиться, раз их у тебя 5+1 штук. Личку глянь, ну и попытайся всё же прочитать два абзаца комментариев в winnt.h, которые всё объясняют.
ВОбщем перпелил ф-цию для обхода дерева,с целью посмотреть что то за фигня творится Код (Text): DWORD fixResRVA(char *res,//буфер с секцией DWORD stoff//текущей смещение буфера ) { DWORD irdsz=sizeof(_IMAGE_RESOURCE_DIRECTORY),irdEsz=sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY),resdatsz=sizeof(_IMAGE_RESOURCE_DATA_ENTRY); _IMAGE_RESOURCE_DIRECTORY ird; _IMAGE_RESOURCE_DATA_ENTRY dataE; ZeroMemory(&dataE,resdatsz); res+=stoff; ZeroMemory(&ird,irdsz); memcpy(&ird,res,irdsz); printf("dirs num: %d\n",ird.NumberOfNamedEntries+ird.NumberOfIdEntries); res+=irdsz; stoff=stoff+irdsz; _IMAGE_RESOURCE_DIRECTORY_ENTRY *erde=new _IMAGE_RESOURCE_DIRECTORY_ENTRY[ird.NumberOfNamedEntries+ird.NumberOfIdEntries]; memset(erde,NULL,sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY)*ird.NumberOfNamedEntries+ird.NumberOfIdEntries); memcpy(erde,res,sizeof(_IMAGE_RESOURCE_DIRECTORY_ENTRY)*ird.NumberOfNamedEntries+ird.NumberOfIdEntries); for(int i=0;i<ird.NumberOfNamedEntries+ird.NumberOfIdEntries;i++) { printf("erde[i].DataIsDirectory - %d\n",erde[i].DataIsDirectory); if(erde[i].DataIsDirectory==1) { printf("diroffset: %d\n",erde[i].OffsetToDirectory); res-=stoff; stoff=fixResRVA(res,erde[i].OffsetToDirectory); } if(erde[i].DataIsDirectory==0) { res-=stoff; res+=erde[i].OffsetToData; ZeroMemory(&dataE,resdatsz); memcpy(&dataE,res,resdatsz); printf("%d\n",dataE.OffsetToData); } } return(stoff); } Получаю вылет с таким интересным выводом: Обьясните плз откуда дакой бредовый офсет у 1й ветки дерева??? ЗЫ:ресурсы из стандартного виндового блокнота ,из 32х битной 7ки