Как распознать, что приложение намерено выполнить\запустить файл?

Мне нужно распознать и запустить событие, когда файл будет выполняться или запускаться приложением. Я знаю, что могу сделать это, подключив процедуры Windows, но я не знаю, какая процедура или событие Windows срабатывает. Например, когда файл автозапуска будет выполняться, мое приложение должно распознать его, как антивирусное приложение.

Я не уверен, что перехват полезен для моей цели, если решение не перехватывает, пожалуйста, дайте мне верное решение.


person Mahmood_N    schedule 15.08.2010    source источник


Ответы (1)


попробуйте использовать PsSetCreateProcessNotifyRoutine, эта функция добавляет предоставляемая драйвером подпрограмма обратного вызова или удаляет ее из списка подпрограмм, которые будут вызываться всякий раз, когда процесс создается или удаляется.

вы можете найти очень хороший образец по этой ссылке, написанной на С++

Обнаружение выполнения процесса Windows NT/2K

ОБНОВЛЕНИЕ

Другой вариант — использовать события WMI, проверьте Win32_Process метод ExecNotificationQuery и функцию SWbemEventSource.NextEvent.

Проверьте этот образец, протестированный в delphi 7 и Windows 7, вы должны запустить это приложение из-за пределов среды разработки Delphi или отключить уведомление об исключении для исключения EOleException (проверьте эту ссылка), чтобы избежать перехвата 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.
person RRUZ    schedule 15.08.2010
comment
большое спасибо PRUZ очень полезно , но есть вопрос ! когда файл автозапуска (Autorun.inf) пытается выполнить команду или запустить файл, мы можем получить адрес выполнения процесса, но как я могу получить адрес файла автозапуска? Другими словами, я хочу получить адрес Процесса и объекта, выполнившего процесс... большое спасибо... - person Mahmood_N; 16.08.2010
comment
@Mahmood_N, проверьте эту ссылку msdn.microsoft.com/ en-us/library/aa394372%28VS.85%29.aspx, чтобы увидеть все свойства, которые вы можете использовать, ParentProcessId возвращает PID родительского процесса. когда вы получаете pid, вы можете получить любую информацию, используя Windows API или сам WMI. - person RRUZ; 16.08.2010