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;
}