用HOOK做到监视系统打开的程序或窗口,一但是我指定的程序或窗口(由一个INI文件内读出)就将其关闭!!300分求代码!(100分)

  • 主题发起人 主题发起人 keiven
  • 开始时间 开始时间
K

keiven

Unregistered / Unconfirmed
GUEST, unregistred user!
用HOOK做到监视系统打开的程序或窗口,一但是我指定的程序或窗口(由一个INI文件内读出)<br>就将其关闭!!求代码!<br>我不想用时间控件来做,太没有效率了!<br>我想用钩子截获窗口的创建消息,然后杀掉.可是对这方面不熟悉,不知道该从何入手!<br><br>
 
不熟悉就学啊,用WH_CBT<br>代码嘛,懒得写啊,有空再写
 
老大,你就这样回答我啊!!拜托了.给点例子,我自己也好研究一下嘛.<br>
 
DLL 代码:<br>library Mhook;<br><br>uses<br>&nbsp;Main in 'Main.pas',<br><br>&nbsp;windows,<br>&nbsp;messages,<br>&nbsp;Classes,<br>&nbsp;sysutils;<br><br>procedure DLLEntryPoint(dwReason: DWORD);<br>begin<br>&nbsp;case dwReason of<br>&nbsp; &nbsp;DLL_PROCESS_ATTACH: OpenShareData;<br>&nbsp; &nbsp;DLL_PROCESS_DETACH: CloseShareData;<br>&nbsp;end;<br>end;<br>exports<br>&nbsp;EnableMouseHook,<br>&nbsp;DisableMouseHook;<br>begin<br><br>&nbsp;procExit := ExitProc;<br>&nbsp;ExitProc := @HookExit;<br>&nbsp;DLLProc := @DLLEntryPoint;<br>&nbsp;DLLEntryPoint(DLL_PROCESS_ATTACH);<br>end.<br>=======================================================================<br><br>unit Main;<br><br>interface<br>uses<br>&nbsp;windows,<br>&nbsp;messages,<br>&nbsp;Classes,<br>&nbsp;sysutils;<br><br>type<br><br>&nbsp;PServerData = ^ServerData;<br>&nbsp;ServerData = record<br>&nbsp; &nbsp;Wnd: HWND;<br>&nbsp; &nbsp;UniqueMsgID: Cardinal;<br>&nbsp; &nbsp;hHk: HHOOK;<br>&nbsp;end;<br><br>var<br><br>&nbsp;procExit: pointer;<br>&nbsp;SData: PServerData;<br>&nbsp;MapServerHandle: THandle;<br>const<br><br>&nbsp;cMMServerData: PChar = 'ServerMapData';<br><br><br>function EnableMouseHook(h: HWND): Boolean; stdcall;<br>function DisableMouseHook(): Boolean; stdcall;<br><br>procedure HookExit; far;<br>procedure OpenShareData();<br>procedure CloseShareData();<br><br>function CBTHookProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;<br><br>implementation<br><br>procedure OpenShareData();<br>var<br>&nbsp;Size: integer;<br>begin<br>&nbsp;Size := Sizeof(SData);<br>&nbsp;MapServerHandle := CreateFileMapping(DWORD(-1), nil, PAGE_READWRITE, 0, Size,<br>&nbsp; &nbsp;cMMServerData);<br>&nbsp;SData := MapViewOfFile(MapServerHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);<br>end;<br><br><br>procedure CloseShareData();<br>begin<br>&nbsp;UnmapViewOfFile(SData);<br>&nbsp;CloseHandle(MapServerHandle);<br>end;<br><br>function EnableMouseHook(h: HWND): Boolean; stdcall;<br>begin<br>&nbsp;if SData.hHk &lt;&gt; 0 then<br>&nbsp;begin<br>&nbsp; &nbsp;Result := false;<br>&nbsp; &nbsp;exit;<br>&nbsp;end;<br>&nbsp;SData.Wnd := h;<br>&nbsp;SData.UniqueMsgID := RegisterWindowMessage('RWM1');<br><br>&nbsp;SData.hHk := SetWindowsHookEx(WH_CBT, @CBTHookProc, hInstance, 0);<br><br>&nbsp;Result := SData.hHk &lt;&gt; 0;<br>end;<br><br>function DisableMouseHook(): Boolean; stdcall;<br>begin<br>&nbsp;//注销挂钩<br>&nbsp;Result := false;<br>&nbsp;if UnhookWindowsHookEx(SData.hHk) then<br>&nbsp;begin<br>&nbsp; &nbsp;SData.hHk := 0;<br>&nbsp; &nbsp;Result := true;<br>&nbsp;end;<br>end;<br><br>procedure HookExit;<br>begin<br>&nbsp;if SData.hHk &lt;&gt; 0 then<br>&nbsp; &nbsp;DisableMouseHook;<br>&nbsp;ExitProc := procExit;<br>end;<br><br><br>function CBTHookProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;<br>begin<br>&nbsp;if nCode &lt;0 then<br>&nbsp;begin<br>&nbsp; &nbsp; Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>&nbsp; &nbsp; exit;<br>&nbsp;end;<br>&nbsp;if (nCode = HCBT_CREATEWND) &nbsp;then<br>&nbsp;begin<br>&nbsp; //wParam就是窗口的handle<br>&nbsp; //在这里判断是不是你指定的窗口,是的话关闭 <br>&nbsp; &nbsp;<br>&nbsp;end;<br>&nbsp;Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>end;<br>end.<br>=======================================================================<br>主程序:<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp;Dialogs, StdCtrls, ExtCtrls;<br><br>type<br>&nbsp;TForm1 = class(TForm)<br>&nbsp; &nbsp;Label1: TLabel;<br>&nbsp; &nbsp;Button1: TButton;<br>&nbsp; &nbsp;Edit1: TEdit;<br>&nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp;procedure FormDestroy(Sender: TObject);<br>&nbsp;private<br>&nbsp; &nbsp;{ Private declarations }<br>&nbsp; &nbsp;procedure WndProc(var Msg: TMessage); override;<br>&nbsp;public<br>&nbsp; &nbsp;{ Public declarations }<br>&nbsp;end;<br><br>function EnableMouseHook(h: HWND): Boolean; stdcall;<br>function DisableMouseHook(): Boolean; stdcall;<br><br>var<br>&nbsp;Form1: TForm1;<br>&nbsp;UniqueMsgID: Cardinal;<br><br>implementation<br>function EnableMouseHook; external 'MHook.dll' name 'EnableMouseHook';<br>function DisableMouseHook; external 'MHook.dll' name 'DisableMouseHook';<br><br><br>{$R *.dfm}<br><br>procedure TForm1.WndProc(var Msg: TMessage);<br>var<br>&nbsp;ptMousePos: Tpoint;<br>begin<br>&nbsp;if Msg.msg = UniqueMsgID then<br>&nbsp;begin<br>&nbsp; &nbsp;GetCursorPos(ptMousePos);<br>&nbsp; &nbsp;label1.Caption := 'X:' + inttostr(ptMousePos.X) + ' &nbsp;Y:' + inttostr(ptMousePos.Y);<br>&nbsp;end;<br>&nbsp;inherited WndProc(Msg); ;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>&nbsp;h: HWND;<br>begin<br>&nbsp;UniqueMsgID := RegisterWindowMessage('RWM1');<br>&nbsp;EnableMouseHook(Handle);<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp;DisableMouseHook;<br>end;<br><br>end.<br>
 
那么如果我只需要HOOK返回当前打开的窗口名或进程名,由程序本身来杀掉.<br>上面的代码要做那些修改??
 
上面有些代码是不需要的,我也懒得改了<br><br>你的意思是什么啊?是不是要做像win2000里的任务管理器一样的呢?
 
不是,在我自己的程序里已经可以杀掉进程或窗口,我只需要让我的程序得到当前正在创建<br>的窗口名或进程ID! 你的代码该怎么改呢?
 
function CBTHookProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;<br>var<br>&nbsp; pID: DWORD;<br>&nbsp; WinName,ClassName: array[0..254] of char;<br>begin<br>if nCode &lt;0 then<br>begin<br>&nbsp; &nbsp;Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>&nbsp; &nbsp;exit;<br>end;<br>if (nCode = HCBT_CREATEWND) &nbsp;then<br>begin<br>&nbsp;//wParam就是窗口的handle<br>&nbsp;//在这里判断是不是你指定的窗口,是的话关闭 <br>&nbsp;GetWindowText(wParam, WinName, 255); //得到窗口名<br>&nbsp;GetClassName(wParam, ClassName, 255); //得到窗口类名<br>&nbsp;GetWindowThreadProcessId(wParam, @pID); //得到进程ID<br>//关闭的话,判断,如:<br>&nbsp;if WinName='form1' then<br>&nbsp; sendmessage(wParam,WM_CLOSE,0,0);<br><br>//防止创建该窗口,这样好像也可以,没试过<br>//Result:=1; <br>//exit;<br><br>end;<br>Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>end;<br>end.<br>
 
HOOK能不能只向主程序发送一个消息什么的,告诉主程序,系统当前有窗口在创建呢?<br><br>
 
function CBTHookProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;<br>var<br>&nbsp;pID: DWORD;<br>&nbsp;WinName,ClassName: array[0..254] of char;<br>begin<br>if nCode &lt;0 then<br>begin<br>&nbsp; Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>&nbsp; exit;<br>end;<br>if (nCode = HCBT_CREATEWND) &nbsp;then<br>begin<br>//wParam就是窗口的handle<br>//在这里判断是不是你指定的窗口,是的话关闭 <br>//GetWindowText(wParam, WinName, 255); //得到窗口名<br>//GetClassName(wParam, ClassName, 255); //得到窗口类名<br>//GetWindowThreadProcessId(wParam, @pID); //得到进程ID<br>//关闭的话,判断,如:<br>//if WinName='form1' then<br>// sendmessage(wParam,WM_CLOSE,0,0);<br><br>//防止创建该窗口,这样好像也可以,没试过<br>//Result:=1; <br>//exit;<br><br>//发消息:<br>SendMessage(SData.Wnd, SData.UniqueMsgID, 0, 0); <br><br>end;<br>Result := CallNextHookEx(SData.hHk, nCode, wParam, lParam)<br>end;<br>end.<br><br>接收消息:我上面写的:procedure TForm1.WndProc(var Msg: TMessage);
 
GetWindowText(wParam, WinName, 255); //得到窗口名<br>GetClassName(wParam, ClassName, 255); //得到窗口类名<br>GetWindowThreadProcessId(wParam, @pID); //得到进程ID<br>//关闭的话,判断,如:<br>if WinName='系统 属性' then<br>&nbsp; &nbsp;^^^^^^^<br>&nbsp;sendmessage(wParam,WM_CLOSE,0,0);<br><br>"winname "没有得到窗口名?!!
 
GetWindowText(wParam, WinName, 255); //得到窗口名<br>GetClassName(wParam, ClassName, 255); //得到窗口类名<br>GetWindowThreadProcessId(wParam, @pID); //得到进程ID<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;^^^^^<br>那么要如何得到进程的程序名呢?<br>如 p.ExeFile:=FProcessEntry32.sZExeFile; 如p.exefile = c:/windows/Notepad.exe<br>
 
uses tlhelp32;<br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; pe:PROCESSENTRY32;<br>&nbsp; me:MODULEENTRY32;<br>&nbsp; hp,hm:Thandle;<br>&nbsp; b,b1:boolean;<br>begin<br>&nbsp; hp:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0);<br>&nbsp; pe.dwSize:=SizeOf(pe);<br>&nbsp; b:=Process32First(hp,pe);<br>&nbsp; while &nbsp;b do<br>&nbsp; begin<br>&nbsp; &nbsp; hm:=CreateToolHelp32SnapShot(TH32CS_SNAPModule,pe.th32ProcessID);<br>&nbsp; &nbsp; me.dwSize:=sizeof(ModuleEntry32);<br>&nbsp; &nbsp; if Module32First(hm,me) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; b1:=Module32First(hm,me);<br>&nbsp; &nbsp; while &nbsp;b1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if me.th32ModuleID=pe.th32ModuleID then<br>&nbsp; &nbsp; &nbsp; &nbsp; listbox1.Items.Add(me.szExePath);<br>&nbsp; &nbsp; &nbsp; b1:=Module32Next(hm,me);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; &nbsp; b:=Process32Next(hp,pe);<br>&nbsp; end;<br><br>end;<br><br><br>&nbsp;<br>&nbsp;<br><br>--------------------------------------------------------------------------------<br>toolhelp api 在 nt 上不支持<br>下面的可以在 nt 上运行<br>如果要copy到其他机上运行,要顺便拷贝 psapi.dll(这个dll安装delphi或者c++ builder后就有了)<br><br>#include "psapi.hpp"<br><br>假使process id是 pid 的话:<br><br>HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,pid);<br>if( NULL != hProcess )<br>&nbsp; {<br>&nbsp; HMODULE hMod;<br>&nbsp; DWORD cbNeeded;<br>&nbsp; if( EnumProcessModules( hProcess, &amp;hMod, sizeof( hMod ), &amp;cbNeeded ) )<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; char buf[MAX_PATH+1]="";<br>&nbsp; &nbsp; if(GetModuleBaseName( hProcess, hMod,buf,sizeof buf)&gt;0)<br>&nbsp; &nbsp; &nbsp; // <br>&nbsp; &nbsp; &nbsp; // buf放的就是名字<br>&nbsp; &nbsp; &nbsp; //<br>&nbsp; &nbsp; }<br>&nbsp; CloseHandle(hProcess);<br>&nbsp; }<br>&nbsp;<br>&nbsp;<br><br>--------------------------------------------------------------------------------<br>找出所有进程的 process id:<br><br>下面的程序也是可以在 nt 上运行:<br><br>下面的程序也是需要 psapi.dll<br><br>#include "psapi.hpp"<br><br>DWORD pid[1000];<br>DWORD ret_id=0;<br>if(!EnumProcesses(pid,sizeof pid,&amp;ret_id))<br>&nbsp; //返回0,就是失败了<br><br>成功的话返回 非 0 值<br><br>ret_id是返回的字节数,注意不是id的个数,<br>比如返回 1 个id,实际上ret_id等于4,(表示4个字节)<br>ret_id/4 才是 返回 的id 的个数<br><br>返回的id放在 数组 pid<br>大小要大于 id 可能的最大数才找的全,上面的例子是可以找1000个,足够了,<br>如果嫌大,200个就可以了<br><br>
 
这样吧,我把我写的杀进程和窗口的程序帖给你看一下.<br>function killwin (winname:string):boolean;<br>var<br>hwnd_a:HWND;<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp;hwnd_a := FindWindow(nil,pchar(winname));<br>&nbsp; &nbsp; &nbsp; &nbsp;if hwnd_a &lt;&gt; 0 then PostMessage(hwnd_a,WM_CLOSE,0,0);<br>&nbsp; &nbsp; &nbsp; &nbsp;Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp;end;<br>&nbsp;<br>"winname "从INI文件中取得.<br>=====================================================================<br><br>uses TLHelp32<br>type<br>&nbsp; &nbsp; TProcessInfo=Record<br>&nbsp; &nbsp; ExeFile:String;<br>&nbsp; &nbsp; ProcessID:Dword;<br>end;<br>&nbsp;pProcessInfo=^TProcessInfo;<br><br>function killexe(winpath:string):boolean;<br>var<br>p:pProcessInfo;<br>ContinueLoop:Bool;<br>FSnapshotHandle,hProcess:THandle;<br>FProcessEntry32:TProcessEntry32;<br>n:integer;<br>&nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp;New(p);<br>&nbsp; &nbsp; &nbsp; &nbsp;FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);<br>&nbsp; &nbsp; &nbsp; &nbsp;FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);<br>&nbsp; &nbsp; &nbsp; &nbsp;ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);<br>&nbsp; &nbsp; &nbsp; &nbsp;while integer(ContinueLoop)&lt;&gt;0 do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p.ProcessID := FProcessEntry32.th32ProcessID;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p.ExeFile:=FProcessEntry32.sZExeFile;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if SameText(p.ExeFile,winpath) then TerminateProcess(OpenProcess(PROCESS_TERMINATE,BOOL(0),p.ProcessID),0);<br>&nbsp; &nbsp; &nbsp; &nbsp; Continueloop:=process32next(fsnapshothandle,fprocessentry32);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp;end;<br>"winpath "从INI文件中取得.<br>=====================================================================<br><br>以上两段程序,如何嵌入到你的DLL的代码中呢?我试了一下,要报错.不知道该怎么改.<br><br>
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部