Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Creare un processo come figlio di un altro processo


Ecco un altro esempio di utilizzo della tecnica di Code Injection esposta nell'articolo Code Injection.

1. Implementazione

function RemoteCreateProcess( PID: Cardinal; //PID del processo remoto //dichiarazione di tutti i parametri che vogliamo NomeProg: PAnsiChar; NomeDesktop: PAnsiChar; var outValue: Cardinal; //valore importante ottenuto dalla funzione remota var codError: Cardinal; //errore riscontrato dalla funzione remota synch: Boolean): Boolean; //esecuzione sincrona del thread remoto type TRemoteCreateProcessData = record errorcod: Cardinal; //codice di errore rilevato nella funzione remota output: Cardinal; //risultato significativo nella funzione remota //Indirizzi delle API usate: elenco puntatori a funzioni; N.B. rigorosamente stdcall //Es. pLoadLibraryA: function(pLibFileName: PAnsiChar): Cardinal; stdcall; pExitThread: procedure (dwExitCode: Cardinal); stdcall; //API obbligatoria pGetLastError: function(): Cardinal; stdcall; pCreateProcessA: function (lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: Boolean; dwCreationFlags: Cardinal; lpEnvironment: Pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): Boolean; stdcall; pCloseHandle: function (hObject: Cardinal): Boolean; stdcall; //Puntatori a dati; Es. tutte le stringhe vanno messe qui dentro //Es. pNomeDll: Pointer; pProgName: Pointer; pDesktopName: Pointer; end; var hProcess: Cardinal; //handle al processo remoto RemoteCreateProcessData: TRemoteCreateProcessData; //indirizzo del record nello spazio di memoria del processo remoto pRemoteCreateProcessData: Pointer; //indirizzo della funzione del thread nello spazio di memoria del processo remoto pRemoteCreateProcessThread: Pointer; output_value: Cardinal; error_code: Cardinal; functionSize, parameterSize: Cardinal; procedure RemoteCreateProcessThread(lpParameter: pointer); stdcall; var //qui posso definire delle variabili locali StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; begin with TRemoteCreateProcessData(lpParameter^) do begin //implementazione: tutte le API vengono chiamate tramite i puntatori nel record StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.lpReserved := nil; StartupInfo.lpDesktop := pDesktopName; StartupInfo.lpTitle := nil; StartupInfo.dwX := 0; StartupInfo.dwY := 0; StartupInfo.dwXSize := 0; StartupInfo.dwYSize := 0; StartupInfo.dwXCountChars := 0; StartupInfo.dwYCountChars := 0; StartupInfo.dwFillAttribute := 0; StartupInfo.dwFlags := 1; StartupInfo.wShowWindow := 5; StartupInfo.cbReserved2 := 0; StartupInfo.lpReserved2 := nil; StartupInfo.hStdInput := 0; StartupInfo.hStdOutput := 0; StartupInfo.hStdError := 0; if not pCreateProcessA(nil, pProgName, nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin errorcod := pGetLastError; pExitThread(0); end else begin //come output metto il PID del processo creato output := ProcessInfo.dwProcessId; pCloseHandle(ProcessInfo.hProcess); pExitThread(1); end; end; end; //dealloco la memoria in remoto function RemoteCreateProcessUnloadData(): Boolean; begin Result := False; with RemoteCreateProcessData do begin //chiamo UnloadData su tutti i puntatori a dati inclusi nel record UnloadData(hProcess, pDesktopName); UnloadData(hProcess, pProgName); end; //deallocazione spazio per il parametro UnloadData(hProcess, pRemoteCreateProcessData); //deallocazione spazio per la funzione UnloadData(hProcess, pRemoteCreateProcessThread); Result := True; end; //definisco i valori dei campi del record e copio i dati in remoto function RemoteCreateProcessInjectData(): Boolean; begin Result := False; try //inizializzazione valori campi del record: with RemoteCreateProcessData do begin errorcod := 0; output := 0; //assegno i valori ai puntatori a funzione (tramite GetModuleHandle e GetProcAddress) //Es. pLoadLibraryA := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA'); pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread'); //API Obbligatoria pGetLastError := GetProcAddress(GetModuleHandle('kernel32'), 'GetLastError'); pCreateProcessA := GetProcAddress(GetModuleHandle('kernel32'), 'CreateProcessA'); pCloseHandle := GetProcAddress(GetModuleHandle('kernel32'), 'CloseHandle'); //assegno i valori ai puntatori ai dati (tramite InjectData); //N.B. se una InjectData ritorna False allora bisogna chiamare Exit if not InjectData(hProcess, NomeProg, Length(NomeProg), False, pProgName) then begin Exit; end; if not InjectData(hProcess, NomeDesktop, Length(NomeDesktop), False, pDesktopName) then begin Exit; end; end; //copio il parametro parameterSize := SizeOf(RemoteCreateProcessData); if not InjectData(hProcess, @RemoteCreateProcessData, parameterSize, False, pRemoteCreateProcessData) then begin Exit; end; //copio la funzione functionSize := SizeOfProc(@RemoteCreateProcessThread); if not InjectData(hProcess, @RemoteCreateProcessThread, functionSize, True, pRemoteCreateProcessThread) then begin Exit; end; Result := True; finally if not Result then begin RemoteCreateProcessUnloadData; end; end; end; begin //inizializzo a zero le variabili locali hProcess := 0; pRemoteCreateProcessData := nil; pRemoteCreateProcessThread := nil; output_value := 0; error_code := 0; try hProcess := OpenProcessEx(PROCESS_CREATE_THREAD + PROCESS_QUERY_INFORMATION + PROCESS_VM_OPERATION + PROCESS_VM_WRITE + PROCESS_VM_READ, False, PID ); if hProcess = 0 then begin ErrStr('OpenProcessEx'); Exit; end; if not RemoteCreateProcessInjectData() then Exit; if not InjectThread(hProcess, pRemoteCreateProcessThread, pRemoteCreateProcessData, output_value, error_code, synch) then Exit; //output_value e error_code sono stati inizializzati a 0. //sono stati modificati dalla InjectThread solo se synch = true; //se synch=false sono rimasti uguali a zero outvalue := output_value; codError := error_code; Result := True; finally if synch or (not Result) then begin RemoteCreateProcessUnloadData; end; if hProcess <> 0 then begin if not CloseHandle(hProcess) then begin ErrStr('CloseHandle'); end; end; end; end;

e di seguito un semplice esempio di utilizzo

procedure TfrmMain.btnCreateClick(Sender: TObject); var success: Boolean; output: Cardinal; err: Cardinal; begin if not RemoteCreateProcess(PidProcesso(edtNomeEXE.Text), PAnsiChar(edtProcessoFiglioEXE.Text), 'winsta0\default', output, err, True) then begin mmoLog.Lines.Add('errore nella procedura'); end else begin if err <> 0 then mmoLog.Lines.Add('Errore nella creazione del processo figlio; Cod errore: ' + IntToStr(err)) else mmoLog.Lines.Add('Creato proceso figlio con il seguente PID: ' + IntToStr(output)); end; end;

RemoteCreateProcess

 

 

 

 

 

 

 

 
 
Your Ad Here