Tips&Tricks I trucchi del mestiere

 

Applicazioni protette!

In allegato un'applicazione a riga di comando (scritta in Delphi 6) che mostra l'utilizzo dell'API CreateProcessWithLogonW. Permette di lanciare un'applicazione in un contesto di sicurezza specificato (tramite UserName, Dominio e Password). I parametri da passare alla funzione API Win32 CreateProcessWithLogonW (esportata da advapi32.dll, e presente soltanto da Windows 2000 in poi) sono:

lpUserName, lpDominio ed lpPassword : Puntatori a Wide String rispettivamente contenenti il nome utente, il dominio e la password d'accesso

dwLogonFlags : DWORD che specifica le opzioni per il logon (impostato a LOGON_WITH_PROFILE che impone il caricamento del profilo utente)

lpApplicationName ed lpCommandLine: Puntatori a Wide String rispettivamente per il percorso e nome dell'eseguibile e per la riga di comando

dwCreationFlags: DWORD che specifica i flag di creazione del processo; vengono impostati CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE e CREATE_NEW_PROCESS_GROUP che normalmente sono settati per default

lpEnvironment: Puntatore ad un blocco di variabili di ambiente. Settato a NIL consente di utilizzare l'ambiente del processo chiamante

lpCurrentDirectory: Puntatore a Wide String contente la directory in cui verrα eseguita l'applicazione

lpStartupInfo: Puntatore ad una struttura STARTUPINFO che specifica i parametri di visualizzazione della finestra.

lpProcessInfo: Puntatore ad una struttura PROCESSINFO che riceverα gli handle e gli ID di processo e thread.

Nell'esempio viene anche fatto uso dell'API Win32 FormatMessage che restituisce il testo dal codice di un eventuale errore riportato dalla GetLastError nella lingua specificata (dalla GetUserDefaultLangID). Viene inoltre dimostrata anche l'importazione implicita in Delphi di funzioni dalle librerie dinamiche.
Tip fornito dal Sig. Raffaele Cirillo

Program CreateProcess;
{$APPTYPE CONSOLE}
Uses
        SysUtils, Windows;
Const
        LOGON_WITH_PROFILE        = 1;
        LOGON_NETCREDENTIALS_ONLY = 2;
Var
        lpUsername              : LPCWSTR;
        lpDomain                : LPCWSTR;
        lpPassword              : LPCWSTR;
        dwLogonFlags            : LongWord;
        lpApplicationName       : LPCWSTR;
        lpCommandLine           : LPWSTR;
        dwCreationFlags         : LongWord;
        lpEnvironment           : Pointer;
        lpCurrentDirectory      : LPCWSTR;
        StartupInfo             : TSTARTUPINFO;
        lpStartupInfo           : PSTARTUPINFO;
        ProcessInfo             : TProcessInformation;
        lpProcessInfo           : PProcessInformation;
        lpMsgBuf                : Array[0..100] Of Char;

Function CreateProcessWithLogonW
                        (
                        lpUsername         : LPCWSTR;
                        lpDomain           : LPCWSTR;
                        lpPassword         : LPCWSTR;
                        dwLogonFlags       : LongWord;
                        lpApplicationName  : LPCWSTR;
                        lpCommandLine      : LPWSTR;
                        dwCreationFlags    : LongWord;
                        lpEnvironment      : Pointer;
                        lpCurrentDirectory : LPCWSTR;
                        lpStartupInfo      : PSTARTUPINFO;
                        lpProcessInfo      : PProcessInformation
                        )
                        : Boolean; StdCall;
                        External 'advapi32.dll' NAME 'CreateProcessWithLogonW';
Begin
        If ParamCount <> 4 Then
                WriteLn ('Uso: ' + #13#10 +
                         'CreateProcess NOMEAPPLICAZIONE USERNAME' +
                         'DOMINIO PASSWORD')
        Else
        Begin
                lpApplicationName   := PWideChar(WideString(ParamStr(1)));
                lpUserName          := PWideChar(WideString(ParamStr(2)));
                lpDomain            := PWideChar(WideString(ParamStr(3)));
                lpPassword          := PWideChar(WideString(ParamStr(4)));
                lpCommandLine       := NIL;
                lpCurrentDirectory  := PWideChar(WideString(
                                         ExtractFilePath(ParamStr(1))));
                dwLogonFlags        := LOGON_WITH_PROFILE;
                dwCreationFlags     := CREATE_DEFAULT_ERROR_MODE Or
                                       CREATE_NEW_CONSOLE Or
                                       CREATE_NEW_PROCESS_GROUP;
                lpEnvironment       := NIL;
                With StartupInfo Do
                Begin
                        cb          := SizeOf(StartupInfo);
                        lpReserved  := NIL;
                        lpDesktop   := NIL;
                        lpTitle     := NIL;
                        dwFlags     := STARTF_USEPOSITION      Or
                                       STARTF_USEFILLATTRIBUTE Or
                                       STARTF_USECOUNTCHARS    Or
                                       STARTF_USESHOWWINDOW    Or
                                       STARTF_USESIZE;
                        wShowWindow := SW_SHOWDEFAULT;
                        cbReserved2 := 0;
                        lpReserved2 := NIL;
                End;
                lpStartupInfo       := @StartupInfo;
                lpProcessInfo       := @ProcessInfo;
                If CreateProcessWithLogonW(
                                        lpUserName,
                                        lpDomain,
                                        lpPassword,
                                        dwLogonFlags,
                                        lpApplicationName,
                                        lpCommandline,
                                        dwCreationFlags,
                                        lpEnvironment,
                                        lpCurrentDirectory,
                                        lpStartupInfo,
                                        lpProcessInfo)
                Then
                        WriteLn('Handle processo: ', ProcessInfo.hProcess,
                                #13#10,
                                'Handle thread: ',   ProcessInfo.hThread,
                                #13#10,
                                'PID: ',             ProcessInfo.dwProcessId,
                                #13#10,
                                'Thread ID: ',       ProcessInfo.dwThreadId)
                Else
                Begin
                        FormatMessage(
                                FORMAT_MESSAGE_FROM_SYSTEM,
                                NIL,
                                GetLastError,
                                GetUserDefaultLangID,
                                @lpMsgBuf,
                                100,
                                NIL);
                        MessageBox(0,
                                @lpMsgBuf,
                                'CreateProcessWithLogonW',
                                MB_ICONERROR);
                End;
        End;
End.