Hola, Aquí les dejo esta función que añade una nueva sección a la cabecera PE de un ejecutable. La función no soporta la tabla BOUND_IMPORT que suelen tener todos los ejecutables programados en VB, en cuanto me ponga soluciono este problema moviendo la tabla o eliminandola.
Agradecimientos a The Swash y Thor por esos magníficos manuales de las secciones PE y a Pink por la ayudita prestada.
Sin mas aquí el code, esta bastante comentado:
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.1
 Author: Naker90

 Script Function:
	Añade una seccion a un ejecutable

 Agradecimientos a Pink, The Swash y Thor

 Esta funcion no soporta la tabla BOUND IMPORT.

#ce ----------------------------------------------------------------------------

Func AddSection($sFile, $sSectionName)

	;Abrimos el archivo, obtenemos su peso, lo leemos y lo cerramos.
	Local $sOpen = FileOpen($sFile, 16)
	Local $sSize = FileGetSize($sFile)
	Local $sRead = FileRead($sOpen)
	FileClose($sOpen)

	;Creamos una structura de bytes y creamos el puntero para pasarselos a las estructuras posteriores.
	Local $sFileStruct = DllStructCreate('Byte[' & $sSize & ']')
	DllStructSetData($sFileStruct, 1, $sRead)

	Local $sPointer = DllStructGetPtr($sFileStruct)

	;Creamos la primera structura IMAGE_DOS_HEADER donde se encuentra e_magic que contiene los datos "MZ" si el archivo es un ejecutable.
	Local $sIMAGE_DOS_HEADER = 'WORD e_magic;WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;' & _
			'WORD e_cs;WORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];WORD e_lfanew'
	Local $sDosStruct = DllStructCreate($sIMAGE_DOS_HEADER, $sPointer)

	Local $sMZ = DllStructGetData($sDosStruct, 'e_magic')

	;Si el archivo no es un ejecutable (Por que no contiene "MZ"), mostramos un error y salimos de lo contrario seguimos el codigo.
	If Not $sMZ = 23117 Then

		MsgBox(64, 'ERROR', 'El archivo elegido no es un archivo ejecutable')
		Exit

	Else

		;Le sumamos al puntero el valor de PE\0x\0x que se encuentra en IMAGE_DOS_HEAEDER en el parametro e_lfanew.
		$sPointer += DllStructGetData($sDosStruct, 'e_lfanew')

		;Caragamos 3 nuevas estructuras .
		Local $sIMAGE_NT_HEADER = 'DWORD signature;CHAR IMAGE_FILE_HEADER[20];CHAR IMAGE_OPTIONAL_HEADER[224]'
		Local $sNTStruct = DllStructCreate($sIMAGE_NT_HEADER, $sPointer)

		;Le pasamos de puntero el ultimo parametro de la structura de IMAGE_NT_HEADER y obtenemos el sectionalignment y el filealignment que despues nos van a hacer
		;falta para calcular la nueva seccion.
		Local $sIMAGE_OPTIONAL_HEADER = 'WORD magic;BYTE majorlinkerversion;BYTE minorlinkerversion;DWORD sizeofcode;DWORD sizeofinitializeddata;' & _
				'DWORD sizeofuninitializeddata;DWORD addressofentrypoint;DWORD baseofcode;DWORD baseofdata;DWORD imagebase;' & _
				'DWORD sectionalignment;DWORD filealignment;WORD majoroperatingsystemversion;WORD minoroperatingsystemversion;' & _
				'WORD majorimageversion;WORD minorimageversion;WORD majoresubsystemversion;WORD minorsubsystemversion;' & _
				'DWORD win32versionvalue;DWORD sizeofimage;DWORD sizeofheaders;DWORD checksum;WORD subsystem;WORD dllcharacteristics;' & _
				'DWORD sizeofstackreserve;DWORD sizeofstackcommit;DWORD sizeofheapcommit;DWORD loaderflags;DWORD numberofrvaandsizes;' & _
				'DOUBLE datadirectory[16]'
		Local $sOptionalStruct = DllStructCreate($sIMAGE_OPTIONAL_HEADER, DllStructGetPtr($sNTStruct, 'IMAGE_OPTIONAL_HEADER'))

		Local $sSectionAligment = DllStructGetData($sOptionalStruct, 'sectionalignment')
		Local $sFileAligment = DllStructGetData($sOptionalStruct, 'filealignment')

		;Le pasamos como puntero en 2º parametro de la estructura de IMAGE_NT_HEADER.
		Local $sIMAGE_FILE_HEADER = 'WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;' & _
				'WORD Characteristics;'
		Local $sFileHeaderStruct = DllStructCreate($sIMAGE_FILE_HEADER, DllStructGetPtr($sNTStruct, 'IMAGE_FILE_HEADER'))

		;Obtenemos la direccion del la ultima seccion.
		Local $sLastSection = DllStructGetData($sFileHeaderStruct, 'numberofsections') - 1

		;Le sumamos al puntero el tamaño de SizeOfOptionalHeader + 24 y las secciones multiplicadas por 0x28 (0x28 por que es lo que ocupa cada seccion).
		$sPointer += (24 + DllStructGetData($sFileHeaderStruct, 'SizeOfOptionalHeader'))

		$sPointer += ($sLastSection * 0x28)

		;Creamos una nueva estructura (IMAGE_FILE_HEADER) para sacar unos valores de la ultima seccion que nos haran falta para calcular la nueva seccion.
		Local $sIMAGE_SECTION_HEADER = 'CHAR name[8];DWORD virtualsize;DWORD virtualaddress;DWORD sizeofrawdata;DWORD pointertorawdata;DWORD pointertorelocations;' & _
				'DWORD pointertolinenumbers;WORD numberofrelocations;WORD numberoflinenumbers;DWORD characteristics'
		Local $sLastSectionStruct = DllStructCreate($sIMAGE_SECTION_HEADER, $sPointer)

		Local $sLastVirtualAddress = DllStructGetData($sLastSectionStruct, 'virtualaddress')
		Local $sLastVirtualSize = DllStructGetData($sLastSectionStruct, 'virtualsize')
		Local $sLastPointerToRawData = DllStructGetData($sLastSectionStruct, 'pointertorawdata')
		Local $sLastSizeOfRawData = DllStructGetData($sLastSectionStruct, 'sizeofrawdata')

		;Sumamos 1 al numero total de secciones para añadir nuestra seccion
		Local $sNewNumberOfSection = DllStructGetData($sFileHeaderStruct, 'numberofsections') + 1
		DllStructSetData($sFileHeaderStruct, 'NumberOfSections', $sNewNumberOfSection)

		;Sumamos 0x28 al puntero para ubicarnos al final de la ultima seccion, donde vamos a añadir la nuestra.
		$sPointer += 0x28

		;Creamos la estructura para nuestra nueva seccion
		Local $sNewSectionStruct = DllStructCreate($sIMAGE_SECTION_HEADER, $sPointer)

		;Si el nombre de la nueva seccion supera los 8 caracteres (que serian 8 bytes) solo nos quedamos con los 8 primeros caracteres.
		if StringLen($sSectionName) > 8 then
			$sSectionName = StringLeft($sSectionName, 8)
		EndIf

		;Añadimos a nuestra nueva seccion su nombre.
		DllStructSetData($sNewSectionStruct, 1, $sSectionName)

		;Añadimos el valor "VirtualSize" de nuestra nueva seccion, le voy a dar 0x100 por defecto
		DllStructSetData($sNewSectionStruct, 2, 0x10)

		;Añadimos el VirtualAddress de nuestra secccion, esta se calcula de la siguiente manera: Sumamos el VirtualSize + VirtualAddress de la seccion anterior a la nuestra
		;y lo alineamos con SectionAligment
		Local $sNewVirtualAddress = $sLastVirtualAddress + $sLastVirtualSize
		$sNewVirtualAddress = ($sNewVirtualAddress + $sSectionAligment) - Mod($sNewVirtualAddress, $sSectionAligment)

		DllStructSetData($sNewSectionStruct, 3, $sNewVirtualAddress)

		;Alineamos los datos al valor de FileAligment.
		Local $sNewSizeOfRawData = (0x10 + $sFileAligment) - Mod(0x10, $sFileAligment)
		DllStructSetData($sNewSectionStruct, 4, $sNewSizeOfRawData)

		;El PointerToRawData lo obtenemos sumando el PonterToRawData + SizeOfRawData de la seccion anterior
		Local $sNewPointerToRawData = $sLastPointerToRawData + $sLastSizeOfRawData
		DllStructSetData($sNewSectionStruct, 5, $sNewPointerToRawData)

		;Los proximos 4 parametros de nuestra estructura no nos interesan asi que los dejamos a 0
		DllStructSetData($sNewSectionStruct, 6, 0)
		DllStructSetData($sNewSectionStruct, 7, 0)
		DllStructSetData($sNewSectionStruct, 8, 0)
		DllStructSetData($sNewSectionStruct, 9, 0)

		;Por ultimo el atributo de nuestra seccion, le asignaremos los valores de lectura y escritura (C0000000)
		DllStructSetData($sNewSectionStruct, 10, 0xC0000000)

		;Modificamos el SizeOfImage, El resultado lo obtenermos sumando el sizeofimage + sizeofrawdata de nuestra seccion y por ultimo lo alineamos con FileAligment
		Local $sNewSizeOfImage = DllStructGetData($sOptionalStruct, 'sizeofimage') + DllStructGetData($sNewSectionStruct, 'sizeofrawdata')
		$sNewSizeOfImage = ($sNewSizeOfImage + $sFileAligment) - Mod($sNewSizeOfImage, $sFileAligment)

		DllStructSetData($sOptionalStruct, 'sizeofimage', $sNewSizeOfImage)

		;Cremaos un nuevo archivo donde escribir los nuevos datos y le añadimos bytes al final del archivo.
		Local $sNewFile = FileOpen('new.exe', 17)
		FileWrite($sNewFile, DllStructGetData($sFileStruct, 1))
		For $i = 0 to 210
			FileWrite($sNewFile, 0)
		Next
		FileClose($sNewFile)

		MsgBox(64, 'Listo', 'Nuevo archivo creado con las secciones modificadas!')

	EndIf

EndFunc
Saludos
Skype: naker.noventa
Es muy bueno.

Cambia esto

Código: Seleccionar todo

 Local $sNewSizeOfImage = DllStructGetData($sOptionalStruct, 'sizeofimage') + DllStructGetData($sNewSectionStruct, 'sizeofrawdata')
        $sNewSizeOfImage = ($sNewSizeOfImage + $sFileAligment) - Mod($sNewSizeOfImage, $sFileAligment)
 
Por esto:

Código: Seleccionar todo

 Local $sNewSizeOfImage = DllStructGetData($sOptionalStruct, 'sizeofimage') + $sSectionAligment

Saludos
Imagen
Responder

Volver a “Fuentes”