2010-08-15 4 views
5

Devo riconoscere e attivare un evento quando un file verrà eseguito o eseguito da un'applicazione. So che posso farlo agganciando le procedure di Windows, ma non so quale procedura o evento di Windows si spara. Ad esempio, quando un file autorun sta per essere eseguito, la mia applicazione dovrebbe riconoscerlo, come un'applicazione antivirus.Come riconoscere che un'applicazione intende eseguire Esegui un file?

Non sono sicuro che l'aggancio sia utile per il mio scopo, se la soluzione non si aggancia, per favore dammi una soluzione vera.

risposta

12

provare a utilizzare il PsSetCreateProcessNotifyRoutine, questa funzione aggiunge una routine di callback fornita dal driver o rimuoverla da un elenco di routine da chiamare ogni volta che un processo viene creato o eliminato.

potete trovare un bel int campione questo link scritto in C++

Detecting Windows NT/2K process execution

UPDATE

Un'altra opzione è utilizzare gli eventi WMI, verificare la classe Win32_Process, il metodo ExecNotificationQuery e la funzione SWbemEventSource.NextEvent.

controllare questo campione testato in Delphi 7 e Windows 7, è necessario eseguire questa applicazione al di fuori della Delphi IDE o disattivare la notifica di eccezione per l'eccezione EOleException (controllare questo link), al fine di evitare il wich EOleException è stato intercettato dalla IDE.

program GetWMI_InstanceCreationEvent; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils 
    ,Windows 
    ,ComObj 
    ,ActiveX 
    ,Variants; 


Function KeyPressed:boolean; //detect if an key is pressed 
var 
NumEvents : DWORD; 
ir   : _INPUT_RECORD; 
bufcount : DWORD; 
StdIn  : THandle; 
begin 
Result:=false; 
StdIn := GetStdHandle(STD_INPUT_HANDLE); 
NumEvents:=0; 
GetNumberOfConsoleInputEvents(StdIn,NumEvents); 
    if NumEvents<> 0 then 
    begin 
     PeekConsoleInput(StdIn,ir,1,bufcount); 
     if bufcount <> 0 then 
     begin 
      if ir.EventType = KEY_EVENT then 
      begin 
       if ir.Event.KeyEvent.bKeyDown then 
       result:=true 
       else 
       FlushConsoleInputBuffer(StdIn); 
      end 
      else 
      FlushConsoleInputBuffer(StdIn); 
     end; 
    end; 
end; 


function VarStrNUll(VarStr:OleVariant):string;//dummy function to handle null variants 
begin 
    Result:=''; 
    if not VarIsNull(VarStr) then 
    Result:=VarToStr(VarStr); 
end; 

function GetWMIObject(const objectName: String): IDispatch; //create a wmi object instance 
var 
    chEaten: Integer; 
    BindCtx: IBindCtx; 
    Moniker: IMoniker; 
begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker)); 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result)); 
end; 

Procedure GetWin32_InstanceCreationEvent; 
var 
    objWMIService    : OLEVariant; 
    colMonitoredProcesses  : OLEVariant; 
    objLatestProcess   : OLEVariant; 
begin 
    objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2'); 
    colMonitoredProcesses  := objWMIService.ExecNotificationQuery('Select * From __InstanceCreationEvent Within 1 Where TargetInstance ISA ''Win32_Process'''); //Get the event listener 
    while not KeyPressed do 
    begin 
    try 
    objLatestProcess := colMonitoredProcesses.NextEvent(100);//set the max time to wait (ms) 
    except 
    on E:EOleException do 
    if EOleException(E).ErrorCode=HRESULT($80043001) then //Check for the timeout error wbemErrTimedOut 0x80043001 
    objLatestProcess:=Null 
    else 
    raise; 
    end; 

    if not VarIsNull(objLatestProcess) then 
    begin 
     Writeln('Process Started '+VarStrNUll(objLatestProcess.TargetInstance.Name)); 
     Writeln('CommandLine  '+VarStrNUll(objLatestProcess.TargetInstance.CommandLine)); 
     Writeln('PID    '+VarStrNUll(objLatestProcess.TargetInstance.ProcessID)); 
    end; 
    end; 
end; 



begin 
try  
    CoInitialize(nil); 
    try 
     Writeln('Press Any key to exit'); 
     GetWin32_InstanceCreationEvent; 
    finally 
    CoUninitialize; 
    end; 

except 
    on E:Exception do 
    Begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    End; 
    end; 
end. 
+0

grazie molto PRUZ è molto utile, ma c'è una domanda! quando un file autorun (Autorun.inf) tenta di eseguire un comando o esegue un file, possiamo ottenere il processo eseguito indirizzo ma come posso ottenere l'indirizzo del file autorun? In altre parole, voglio ottenere l'indirizzo del processo e l'oggetto che ha eseguito il processo ... grazie mille ... –

+0

@Mahmood_N, controlla questo link http://msdn.microsoft.com/it us/library/aa394372% 28VS.85% 29.aspx per vedere tutte le proprietà che è possibile utilizzare, 'ParentProcessId' restituisce il PID del processo padre. quando ottieni il pid puoi recuperare qualsiasi informazione usando l'API di Windows o il WMI stesso. – RRUZ

+0

Grazie mille, è quello che volevo, i migliori saluti ... –