Bueno, una de las funciones que terminamos del VM (siempre haciendo publicidad :xD). Muchas funciones no las publicaremos antes de sacar el VM, pero ésta no lo perjudicará :P.

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;
}
Modo de uso:

Código: Seleccionar todo

	DWORD newFileSize=0;
	LPSTR Temp=AddExecutableSectionSize(lpFileMaped,FileSize,0x800,newFileSize);
Saludos
Responder

Volver a “Fuentes”