2010-08-15 17 views
5

Je dois reconnaître et déclencher un événement lorsqu'un fichier va être exécuté ou exécuté par une application. Je sais que je peux le faire en accrochant des procédures de fenêtres, mais je ne sais pas quelle procédure ou événement de Windows déclenche. Par exemple, quand un fichier autorun va s'exécuter, mon application devrait le reconnaître, comme une application antivirus.Comment reconnaître qu'une application a l'intention d'exécuter Exécuter un fichier?

Je ne suis pas sûr que l'accrochage est utile pour mon but, si la solution ne s'accroche pas, s'il vous plaît donnez-moi une vraie solution.

Répondre

12

essayez d'utiliser le PsSetCreateProcessNotifyRoutine, cette fonction ajoute une routine de rappel fournie par le pilote à ou la supprime d'une liste de routines à appeler chaque fois qu'un processus est créé ou supprimé.

vous pouvez trouver un échantillon très agréable int ce lien écrit en C++

Detecting Windows NT/2K process execution

MISE À JOUR

Une autre option est d'utiliser les événements WMI, vérifiez la classe Win32_Process, la méthode ExecNotificationQuery et la fonction SWbemEventSource.NextEvent.

Vérifiez cet échantillon testé dans delphi 7 et Windows 7, vous devez exécuter cette application à partir de l'extérieur de l'IDE Delphi ou désactiver la notification d'exception à l'exception de EOleException (vérifier link), pour éviter la EOleException Wich est interceptée par la 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

merci beaucoup PRUZ c'est très utile, mais il y a une question! Lorsqu'un fichier autorun (Autorun.inf) tente d'exécuter une commande ou d'exécuter un fichier, nous pouvons obtenir l'adresse du processus mais comment puis-je obtenir l'adresse du fichier autorun? En d'autres termes, je veux obtenir l'adresse du processus et l'objet qui a exécuté le processus ... merci beaucoup ... –

+0

@ Mahmood_N, vérifiez ce lien http://msdn.microsoft.com/fr us/library/aa394372% 28VS.85% 29.aspx Pour voir toutes les propriétés que vous pouvez utiliser, 'ParentProcessId' renvoie le PID du processus parent. Lorsque vous obtenez le pid, vous pouvez récupérer toutes les informations en utilisant l'API Windows ou le WMI lui-même. – RRUZ

+0

Merci beaucoup, c'est ce que je voulais, Cordialement ... –