compatibiliser ce programme en 32 et 64 bits

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
davinciomar
Niveau 2
Niveau 2
Messages : 17
Enregistré le : dim. 26 mars 2017 19:52
Status : Hors ligne

compatibiliser ce programme en 32 et 64 bits

#1

Message par davinciomar »

Bonjour je veux compatibiliser ce programme pour étudier sur 32 et 64 bits. fonctionne bien en 32 bits je peux utiliser autre version pour 64 bits mais je ne peux pas utiliser sur les deux. 32 et 64. Le programme est le suivante:

Code : Tout sélectionner

Func _Programme($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.
		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'))
		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 0x10007
		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
		Local $pVirtualAlloc = DllCall('Kernel32.dll', 'Ptr', 'VirtualAllocEx', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Dword', $dSizeOfImage, 'Dword', 0x3000, 'Dword', 0x40)

		;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.
		Local $dModEntryPoint = $dwImageBase + $dEntryPoint
		DllStructSetData($sContext_Struct, 'Eax', $dModEntryPoint)

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

		;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
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: compatibiliser ce programme en 32 et 64 bits

#2

Message par Tlem »

Pouvez vous aussi nous communiquer le code qui fonctionne sur 64Bits ?

Envoyé de mon SM-N9005 en utilisant Tapatalk

Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
davinciomar
Niveau 2
Niveau 2
Messages : 17
Enregistré le : dim. 26 mars 2017 19:52
Status : Hors ligne

Re: compatibiliser ce programme en 32 et 64 bits

#3

Message par davinciomar »

Programme 64 bits.

Code : Tout sélectionner

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 (Version x64) de la cual sacaremos los datos de: ImageBase, SizeOfImage, EntryPoint y el SizeOfHeaders.
			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'))
			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 (Version x64) y establecemos la bandera con el valor 0x100007
			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)

			;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"
			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"
			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)

			;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   ;==>_RunPE_Version_x64
mais je peux utiliser @OSArchitecture mais je trouve une manière pour faire directement donc je peux utiliser les deux ou sinon avec un if je peux mais.. j'attends votre reponse.
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: compatibiliser ce programme en 32 et 64 bits

#4

Message par Tlem »

2 Fonctions distinctes est une assez bonne solution. Cela permet lors des test de savoir ou ce situe un éventuel problème.

Sinon une seule et unique fonction en adaptant à l'architecture.
J'ai repris et fusionné vos deux codes :

Code : Tout sélectionner

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
On peux simplifier encore un tout petit peu, mais bon, si ça fonctionne ... ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Répondre