当一个文件将被执行或由应用程序运行时,我需要识别并触发一个事件。我知道我可以通过挂钩Windows程序来做到这一点,但我不知道Windows会触发什么程序或事件。 例如,当自动运行文件要执行时,我的应用程序应该识别它,就像防病毒应用程序一样。如何识别应用程序意图执行运行文件?
我不确定挂钩对我的目的有用,如果解决方案没有挂钩,请给我一个真正的解决方案。
当一个文件将被执行或由应用程序运行时,我需要识别并触发一个事件。我知道我可以通过挂钩Windows程序来做到这一点,但我不知道Windows会触发什么程序或事件。 例如,当自动运行文件要执行时,我的应用程序应该识别它,就像防病毒应用程序一样。如何识别应用程序意图执行运行文件?
我不确定挂钩对我的目的有用,如果解决方案没有挂钩,请给我一个真正的解决方案。
尝试使用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.
非常感谢PRUZ 它是非常有用的,但有一个问题! 当一个自动运行文件(Autorun.inf)试图执行一个命令或运行一个文件时,我们可以得到进程执行的地址,但是我怎样才能得到autorun文件的地址? 换句话说,我想获取进程的地址和执行进程的对象... 非常感谢... – 2010-08-16 10:45:09
@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
非常感谢,这就是我想要的,最好的问候... – 2010-08-17 07:26:13