如何识别应用程序打算执行\运行文件? [英] How to Recognize that an Application Intends to Execute \ Run a File?

查看:111
本文介绍了如何识别应用程序打算执行\运行文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当需要执行文件或由应用程序运行时,我需要识别和触发事件。我知道我可以通过挂起Windows程序来完成,但我不知道Windows的程序或事件的发生。
例如,当一个自动运行文件执行时,我的应用程序应该识别它,就像一个防病毒应用程序。



我不知道钩子是有用的为了我的目的,如果解决方案没有挂钩,请给我一个真正的解决方案。

解决方案

尝试使用 PsSetCreateProcessNotifyRoutine ,这个函数将一个驱动程序提供的回调例程添加到每个进程被创建或删除时被调用的例程列表中,或从其中删除。



您可以在c ++中找到一个非常好的示例int link

检测Windows NT / 2K进程执行



更新



另一个选项是使用WMI事件,请检查 Win32_Process 类, ExecNotificationQuery 方法和 SWbemEventSource.NextEvent 函数。



检查此示例在delphi 7和Windows 7中测试,您必须运行这个应用程序从Delphi IDE外部或禁用异常通知的EOleException异常(检查这个链接),以避免被IDE拦截的 EOleException

 程序GetWMI_InstanceCreationEvent; 

{$ APPTYPE CONSOLE}

使用
SysUtils
,Windows
,ComObj
,ActiveX
,变种


功能KeyPressed:boolean; //检测是否按键
var
NumEvents:DWORD;
ir:_INPUT_RECORD;
bufcount:DWORD;
StdIn:THandle;
begin
结果:= false;
StdIn:= GetStdHandle(STD_INPUT_HANDLE);
NumEvents:= 0;
GetNumberOfConsoleInputEvents(StdIn,NumEvents);
如果NumEvents<> 0然后
begin
PeekConsoleInput(StdIn,ir,1,bufcount);
如果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);
结束
结束
结束


函数VarStrNUll(VarStr:OleVariant):string; //用于处理空变量的虚函数
begin
结果:='';
如果不是VarIsNull(VarStr)then
结果:= VarToStr(VarStr);
结束

函数GetWMIObject(const objectName:String):IDispatch; //创建一个wmi对象实例
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));
结束

过程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'''); //获取事件监听器
而不是KeyPressed做
开始
尝试
objLatestProcess:= colMonitoredProcesses.NextEvent(100); //设置最大时间等待(ms)
除了
在E:EOleException do
如果EOleException(E).ErrorCode = HRESULT($ 80043001)然后//检查超时错误wbemErrTimedOut 0x80043001
objLatestProcess:= Null
else
加注
结束

如果不是VarIsNull(objLatestProcess)然后
begin
Writeln('Process Started'+ VarStrNUll(objLatestProcess.TargetInstance.Name));
Writeln('CommandLine'+ VarStrNUll(objLatestProcess.TargetInstance.CommandLine));
Writeln('PID'+ VarStrNUll(objLatestProcess.TargetInstance.ProcessID));
结束
结束
结束



begin
try
CoInitialize(nil);
try
Writeln('按任意键退出);
GetWin32_InstanceCreationEvent;
finally
CoUninitialize;
结束

除了
在E:Exception do
开始
Writeln(E.Classname,':',E.Message);
Readln;
结束;
结束
结束。


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.

解决方案

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\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.

这篇关于如何识别应用程序打算执行\运行文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆