當一個文件將被執行或由應用程序運行時,我需要識別並觸發一個事件。我知道我可以通過掛鉤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