

La parte de reordenar las secciones se puede hacer de una forma más rápida y con menos código (Cambiando sólo el PointerToRawData), pero como eso se me ocurrió despues de terminar..
Código
LPSTR RebuildPE(LPSTR FileName,LPSTR lpFileMaped,DWORD FileSize) { PIMAGE_DOS_HEADER IDH; PIMAGE_NT_HEADERS INTH; PIMAGE_SECTION_HEADER ISH; IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0]; INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew]; //Creamos un buffer y guardamos una copia del archivo mapeado LPSTR Temp=(LPSTR)GlobalAlloc(GPTR,FileSize); CopyMemory(&Temp[0],&lpFileMaped[0],FileSize); //Cambiamos las secciones en el archivo de orden (no en la cabecera) for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { PIMAGE_DOS_HEADER tIDH; PIMAGE_NT_HEADERS tINTH; PIMAGE_SECTION_HEADER tISH; PIMAGE_SECTION_HEADER tISH2; PIMAGE_SECTION_HEADER ISH2; tIDH=(PIMAGE_DOS_HEADER)&Temp[0]; tINTH=(PIMAGE_NT_HEADERS)&Temp[tIDH->e_lfanew]; tISH=(PIMAGE_SECTION_HEADER)&Temp[tIDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*(i+1)]; ISH2=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*(i+1)]; tISH2=(PIMAGE_SECTION_HEADER)&Temp[tIDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; if(i!=INTH->FileHeader.NumberOfSections-1) { CopyMemory(&lpFileMaped[ISH->PointerToRawData],&Temp[tISH->PointerToRawData],tISH->SizeOfRawData); ISH->SizeOfRawData=tISH->SizeOfRawData; ISH->Characteristics=tISH->Characteristics; ISH->VirtualAddress=tISH->VirtualAddress; CopyMemory(&ISH->Name,&tISH->Name,8); ISH2->PointerToRawData=ISH->PointerToRawData+tISH->SizeOfRawData; } else { tISH=(PIMAGE_SECTION_HEADER)&Temp[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)]; ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; CopyMemory(&lpFileMaped[ISH->PointerToRawData],&Temp[tISH->PointerToRawData],tISH->SizeOfRawData); ISH->SizeOfRawData=tISH->SizeOfRawData; ISH->Characteristics=tISH->Characteristics; ISH->VirtualAddress=tISH->VirtualAddress; CopyMemory(&ISH->Name,&tISH->Name,8); } } LPSTR SecTmp=(LPSTR)GlobalAlloc(GPTR,0x28*INTH->FileHeader.NumberOfSections); CopyMemory(&SecTmp[0],&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)],0x28*INTH->FileHeader.NumberOfSections); //Reordenamos las secciones en la cabecera for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { if(i==0) { CopyMemory(&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)],&SecTmp[0x28*(INTH->FileHeader.NumberOfSections-1)],0x28); } else { CopyMemory(&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i],&SecTmp[0x28*(i-1)],0x28); } } GlobalFree(Temp); //Obtenemos el PointerToRawData más alto y el tamaño total de todas las secciones DWORD MaxPointerToRawData=0; DWORD TotalSectionsSize=0; for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; if(MaxPointerToRawData<ISH->PointerToRawData) { MaxPointerToRawData=ISH->PointerToRawData; } TotalSectionsSize=TotalSectionsSize+(DWORD)(ISH->SizeOfRawData); } //Obtenemos la sección con el PointerToRawData más alto for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; //Si es la sección que contiene el PointerToRawData más alto salimos del bucle if(ISH->PointerToRawData==MaxPointerToRawData) { i=INTH->FileHeader.NumberOfSections; } } //Si hay EOF Data if(ISH->PointerToRawData+ISH->SizeOfRawData<FileSize) { //Metemos el EOF Data dentro de la última sección ISH->SizeOfRawData=ISH->SizeOfRawData+(FileSize-(ISH->PointerToRawData+ISH->SizeOfRawData)); } //Obtenemos el SizeOfImage y ajustamos el VirtualSize de las secciones DWORD SizeOfImage=0; for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++) { ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i]; ISH->Misc.VirtualSize=ISH->SizeOfRawData; if(SizeOfImage<ISH->VirtualAddress) { SizeOfImage=ISH->VirtualAddress+ISH->Misc.VirtualSize; } } //Ajustamos el SizeOfImage INTH->OptionalHeader.SizeOfImage=SizeOfImage; //Recalculamos el CheckSum _MapFileAndCheckSum miMapFileAndCheckSum=NULL; HMODULE hLib=LoadLibraryA("IMAGEHLP.DLL"); miMapFileAndCheckSum=(_MapFileAndCheckSum)GetProcAddress(hLib,"MapFileAndCheckSumA"); DWORD OrignalCheckSum=0; DWORD newCheckSum=0; miMapFileAndCheckSum((PTSTR)FileName,&OrignalCheckSum,&newCheckSum); INTH->OptionalHeader.CheckSum=newCheckSum; return lpFileMaped; }
Como las secciones no están ordenadas por el PointerToRawData en la cabecera, algunos visores del PE (Pe explorer por ejemplo) dice que tiene EOF data, pero no la tiene

Saludos
PD: Gracias a Karcrack y Arkangel por escuchar mis lamentos
