Как распознать, что приложение намерено выполнить \ запустить файл? - PullRequest
5 голосов
/ 16 августа 2010

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

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

1 Ответ

12 голосов
/ 16 августа 2010

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

Вы можете найти очень хороший пример по этой ссылке, написанной на c ++

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

ОБНОВЛЕНИЕ

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

Проверьте этот пример, протестированный в Delphi 7 и Windows 7, вы должны запустить это приложение из-за пределов Delphi IDE или отключить уведомление об исключении для исключения 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...