Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
408 views
in Technique[技术] by (71.8m points)

windows - How to Recognize that an Application Intends to Execute Run a File?

I need to recognize and fire an event when a file is going to be executed or run by an application. I know I can do it by hooking windows procedures, but I don't know what procedure or event of windows fires. For example, when an autorun file going to execute, my application should recognize it, Like an antivirus application.

I'm not sure that hooking is useful for my purpose, if solution isn't hooking, please give me a true solution.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

try using the PsSetCreateProcessNotifyRoutine, this function adds a driver-supplied callback routine to, or removes it from, a list of routines to be called whenever a process is created or deleted.

you can find a very nice sample int this link written in c++

Detecting Windows NT/2K process execution

UPDATE

Another option is use the WMI events, check the Win32_Process class, the ExecNotificationQuery method and the SWbemEventSource.NextEvent function.

Check this sample tested in delphi 7 and Windows 7, you must run this application from outside of the Delphi IDE or disable the exception notification for the EOleException exception (check this link), to avoid the EOleException wich is intercepted by the 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
ootcimv2');
  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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...