2010-08-15 147 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

相關問題