2010-08-15 140 views
5

当一个文件将被执行或由应用程序运行时,我需要识别并触发一个事件。我知道我可以通过挂钩Windows程序来做到这一点,但我不知道Windows会触发什么程序或事件。 例如,当自动运行文件要执行时,我的应用程序应该识别它,就像防病毒应用程序一样。如何识别应用程序意图执行运行文件?

我不确定挂钩对我的目的有用,如果解决方案没有挂钩,请给我一个真正的解决方案。

回答

12

尝试使用PsSetCreateProcessNotifyRoutine,该功能为驱动程序提供的回调例程添加或从创建或删除进程时要调用的例程列表中删除它。

,你可以找到一个很好的样本INT此链接用C++编写

Detecting Windows NT/2K process execution

UPDATE

另一种选择是使用WMI事件,检查Win32_Process类中,ExecNotificationQuery方法和功能SWbemEventSource.NextEvent

检查在delphi 7和Windows 7中测试过的这个示例,您必须从Delphi IDE外部运行此应用程序或禁用EOleException异常的异常通知(检查link),以避免EOleException被截获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

非常感谢PRUZ 它是非常有用的,但有一个问题! 当一个自动运行文件(Autorun.inf)试图执行一个命令或运行一个文件时,我们可以得到进程执行的地址,但是我怎样才能得到autorun文件的地址? 换句话说,我想获取进程的地址和执行进程的对象... 非常感谢... – 2010-08-16 10:45:09

+0

@Mahmood_N,请检查此链接http://msdn.microsoft.com/en- us/library/aa394372%28VS.85%29.aspx查看您可以使用的所有属性,ParentProcessId返回父进程的PID。当你获得pid时,你可以使用Windows API或WMI本身检索任何信息。 – RRUZ 2010-08-16 15:47:37

+0

非常感谢,这就是我想要的,最好的问候... – 2010-08-17 07:26:13

相关问题