Código: Seleccionar todo
////////////////////////////////////////////////////////////////
//Obtiene la sección ejecutable de un archivo
////////////////////////////////////////////////////////////////
DWORD GetExecutableSection(LPSTR lpFileMaped)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INTH;
PIMAGE_SECTION_HEADER ISH;
BOOL flag=FALSE;
IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];
//Recorremos todas las secciones
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];
//Comprobamos si se trata de una sección de código
if((ISH->Characteristics&0x20000000)==0x20000000)
{
return i;
}
}
return -1;
}
////////////////////////////////////////////////////////////////
//Añade espacio al final de la sección ejecutable
////////////////////////////////////////////////////////////////
LPSTR AddExecutableSectionSize(LPSTR lpFileMaped,DWORD FileSize,DWORD minSize,DWORD &newFileSize)
{
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];
//Calculo el tamaño a añadir
DWORD SizeToAdd=0;
while(SizeToAdd<minSize)
{
SizeToAdd=SizeToAdd+INTH->OptionalHeader.FileAlignment;
}
DWORD ExecutableSection=GetExecutableSection(lpFileMaped);
ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*ExecutableSection];
//Si intetamos añadir demasiado, retornamos null
if(ISH->Misc.VirtualSize+SizeToAdd>INTH->OptionalHeader.SectionAlignment)
{
return NULL;
}
//Copio la parte del archivo que no cambia su posición
LPSTR Temp=(LPSTR)malloc(FileSize+SizeToAdd);
CopyMemory(&Temp[0],&lpFileMaped[0],ISH->PointerToRawData+ISH->SizeOfRawData);
//Copio 0's para rellenar el tamaño que añado a la sección
memset(&Temp[ISH->PointerToRawData+ISH->SizeOfRawData],0,SizeToAdd);
//Copio el resto de datos que si cambian su posición
CopyMemory(&Temp[ISH->PointerToRawData+ISH->SizeOfRawData+SizeToAdd],&lpFileMaped[ISH->PointerToRawData+ISH->SizeOfRawData],FileSize-(ISH->PointerToRawData+ISH->SizeOfRawData));
IDH=(PIMAGE_DOS_HEADER)&Temp[0];
INTH=(PIMAGE_NT_HEADERS)&Temp[IDH->e_lfanew];
ISH=(PIMAGE_SECTION_HEADER)&Temp[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*ExecutableSection];
//Ajusto el SizeOfRawData de la sección a la que añado espacio
ISH->SizeOfRawData=ISH->SizeOfRawData+SizeToAdd;
//Ajustamos los punteros y tamaños de las secciones que movimos
for(DWORD i=ExecutableSection+1;i<INTH->FileHeader.NumberOfSections;i++)
{
ISH=(PIMAGE_SECTION_HEADER)&Temp[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
ISH->PointerToRawData=ISH->PointerToRawData+SizeToAdd;
}
//Ajustamos el VirtualSize de todas las Secciones y obtenemos el SizeOfImage
DWORD SizeOfImage=0;
for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
{
ISH=(PIMAGE_SECTION_HEADER)&Temp[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
ISH->Misc.VirtualSize=ISH->SizeOfRawData;
if(ISH->VirtualAddress>SizeOfImage)
{
SizeOfImage=ISH->VirtualAddress+ISH->Misc.VirtualSize;
}
}
//Ajustamos el SizeOfImage
INTH->OptionalHeader.SizeOfImage=SizeOfImage;
//Retornamos el puntero al archivo y el nuevo tamaño
newFileSize=FileSize+SizeToAdd;
return Temp;
}
Código: Seleccionar todo
DWORD newFileSize=0;
LPSTR Temp=AddExecutableSectionSize(lpFileMaped,FileSize,0x800,newFileSize);