久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用跨進(jìn)程子類化技術(shù)實現(xiàn)對其它進(jìn)程消息的攔載

 獨孤求財 2012-02-01

用跨進(jìn)程子類化技術(shù)實現(xiàn)對其它進(jìn)程消息的攔載

分類: Delphi 189人閱讀 評論(0) 收藏 舉報

  大家都知道每個窗口都有默認(rèn)的窗口函數(shù)來進(jìn)行對窗口消息的處理.
  而子類化技術(shù)就是替換窗口的窗口函數(shù)為自己定義的函數(shù)的技術(shù).例如下面的代碼:
var
  Form1: TForm1;
  OldWndProc: Pointer;
implementation

{$R *.dfm}
function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
begin
  if Msg=WM_CLOSE then
    exit;
  Result := CallWindowProc(OldWndProc, hHwnd, Msg, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  {保存舊的窗口函數(shù)地址}
  OldWndProc := Pointer(GetWindowLong(Self.Handle, GWL_WNDPROC));
  {設(shè)置新的窗口函數(shù)為自定義函數(shù)}
  SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(@NewWndProc));
end;
  這樣在窗口建立時就對窗口實現(xiàn)了子類化,這時按下窗口的關(guān)閉按鈕就會發(fā)現(xiàn)關(guān)不了窗口,因為新的窗口處理函數(shù)把WM_CLOSE消息過濾掉了,要取消子類化,只需要簡單的把以前的窗口函數(shù)恢復(fù)過來就可以了.SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(OldWndProc));

  現(xiàn)在看來似乎很簡單,只要對其它進(jìn)程中的目標(biāo)窗口進(jìn)行子類化就可以實現(xiàn)對其消息的攔載監(jiān)視了.但是在WIN32下,每一個進(jìn)程都有自己獨立的內(nèi)存空間,新的窗口函數(shù)必須和目標(biāo)窗口在同一個進(jìn)程內(nèi),直接使用SetWindowLong(其它進(jìn)程中窗口的句柄, GWL_WNDPROC, 新窗口函數(shù))就會失敗,所以就要想辦法把我們的窗口函數(shù)代碼放到目標(biāo)進(jìn)程內(nèi),這兒有二個辦法,一是使用CreateRemoteThread在目標(biāo)進(jìn)程內(nèi)建立線程,但這函數(shù)只在NT及以上操作系統(tǒng)實現(xiàn),而且還要涉及到API地址重定位等問題,很麻煩(請參考http://www.csdn.net/develop/Read_Article.asp?Id=21079).另一個方法就是使用HOOK技術(shù)(SetWindowsHookEx,如果不知道,請先參考HOOK技術(shù)方面的文章),大家都知道,對其它進(jìn)程進(jìn)行HOOK時,此進(jìn)程會自動加載HOOK過程所在的DLL,如果我們把窗口函數(shù)也放在DLL中,那窗口函數(shù)就相當(dāng)于加載到了目標(biāo)進(jìn)程的地址空間中了,這方法簡單易行.在這里我們就采用HOOK技術(shù)來實現(xiàn)跨進(jìn)程子類化.

  最后一個問題是如何在DLL中實現(xiàn)全局變量,因為DLL中的變量在每個進(jìn)程加載這個DLL時都申請新的空間來存放變量,所以DLL中的變量在各個進(jìn)程內(nèi)不一樣,可以利用內(nèi)存文件映射,WM_COPYDATA等方法來實現(xiàn)全局變量.這兒采用內(nèi)存文件映射.

  現(xiàn)在需要的知識都已了解了,就讓我們來看具體的代碼吧(這兒是把所有函數(shù)放在一個DLL中):

  1. library Hook;     
  2. uses
  3.   SysUtils,windows, Messages;
  4. const
  5.   WM_UNSUBCLASS = WM_USER + 1001;  {卸載子類化消息}
  6.   WM_NEWMESSAGE = WM_USER + 1002;  {通知監(jiān)視窗口攔到了新消息}
  7.   HOOK_EVENT_NAME = 'MyHook';
  8. type
  9.   PMyDLLVar = ^TMyDLLVar;
  10.   TMyDLLVar = record
  11.     SubClass: Boolean;                 {是否已經(jīng)子類化}
  12.     HookWindow, SpyWindow: LongWORD;   {要安裝HOOK的窗口及用于接收消息的窗口}
  13.     hHook: LongWORD;                   {HOOK句柄}
  14.     OldWndProc: pointer;               {舊的窗口過程}
  15.     MsgHwnd: LongWORD;
  16.     Msg: TMessage;
  17.   end;
  18. var
  19.   DLLData: PMyDLLVar;
  20. {---------------------------------------}
  21. {函數(shù)名:NewWndProc
  22. {函數(shù)功能:新的窗口過程
  23. {函數(shù)參數(shù):hHwnd:窗口句柄 Msg:消息ID
  24. {         wParam, lParam:消息參數(shù)
  25. {函數(shù)返回值:下一個窗口過程的返回值
  26. {---------------------------------------}
  27. function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
  28. begin
  29.   if Msg = WM_UNSUBCLASS then   {如果收到卸載子類化消息就恢復(fù)以前的WndProc}
  30.   begin
  31.     SetWindowLong(DLLData^.HookWindow, GWL_WNDPROC, longint(DLLData^.OldWndProc));
  32.     exit;
  33.   end;
  34.   {這兒是把收到的消息放在映射的內(nèi)存中,我們自己的程序可以通過讀這個內(nèi)存來得到監(jiān)視到的消息.}
  35.   DLLData^.Msg.Msg := Msg;            
  36.   DLLData^.Msg.WParam := wParam;
  37.   DLLData^.Msg.LParam := lParam;
  38.   DLLData^.MsgHwnd := hHwnd;
  39.   {給監(jiān)視窗口發(fā)送攔載新消息的消息}
  40.     SendMessage(DLLData^.SpyWindow, WM_NEWMESSAGE, wParam, lParam);
  41.   {這兒可以添加自己對目標(biāo)進(jìn)程消息處理的代碼,因為己經(jīng)是在目標(biāo)進(jìn)程的地址空間內(nèi),現(xiàn)在可以為所
  42.   欲為 ^_^}
  43.   Result := CallWindowProc(DLLData^.OldWndProc, hHwnd, Msg, wParam, lParam);
  44. end;
  45. {------------------------------------}
  46. {過程名:HookProc
  47. {過程功能:HOOK過程
  48. {過程參數(shù):nCode, wParam, lParam消息的相
  49. {         關(guān)參數(shù)
  50. {------------------------------------}
  51. procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
  52. var
  53.   hEvent: THandle;
  54. begin
  55.   if not DllData^.SubClass then  {如果此窗口未子類化}
  56.   begin    {保存窗口過程地址并子類化}
  57.   hEvent := OpenEvent(Synchronize, False, HOOK_EVENT_NAME);
  58.     if hEvent <> 0 then
  59.     begin
  60.       WaitForSingleObject(hEvent, INFINITE);
  61.       CloseHandle(hEvent); 
  62.     end;
  63.     DLLData^.OldWndProc := pointer(GetWindowLong(DLLData^.HookWindow, GWL_WNDPROC));
  64.     SetWindowLong(DLLData^.HookWindow, GWL_WNDPROC, integer(@NewWndProc));
  65.     DLLData^.SubClass := True;
  66.     //hEvent := OpenEvent(Synchronize, False, HOOK_EVENT_NAME);
  67.   end;
  68.   {調(diào)用下一個Hook}
  69.   CallNextHookEx(DLLData^.hHook, nCode, wParam, lParam);
  70. end;
  71. {------------------------------------}
  72. {函數(shù)名:InstallHook
  73. {函數(shù)功能:在指定窗口上安裝HOOK
  74. {函數(shù)參數(shù):HWindow:要安裝HOOK的窗口
  75. {         SWindow:用于接收消息的窗口
  76. {返回值:成功返回TRUE,失敗返回FALSE
  77. {------------------------------------}
  78. function InstallHook(HWindow, SWindow: LongWORD):Boolean;stdcall;
  79. var
  80.   ThreadID: LongWORD;
  81.   hEvent: THandle;
  82. begin
  83.   Result := False;
  84.   DLLData^.hHook := 0;
  85.   DLLData^.HookWindow := HWindow;
  86.   DLLData^.SpyWindow := SWindow;
  87.   {得到指定窗口的線程ID}
  88.   ThreadID := GetWindowThreadProcessId(HWindow, nil);
  89.   {給指定窗口掛上鉤子}
  90.   hEvent := CreateEvent(nil, True, False, HOOK_EVENT_NAME);
  91.   DLLData^.hHook := SetWindowsHookEx(WH_MOUSE, @HookProc, Hinstance, ThreadID);
  92.   SetEvent(hEvent);
  93.   CloseHandle(hEvent);
  94.   if DLLData^.hHook > 0 then Result := True;  {是否成功HOOK}
  95. end;
  96. {------------------------------------}
  97. {過程名:UnHook
  98. {過程功能:卸載HOOK
  99. {過程參數(shù):無
  100. {------------------------------------}
  101. procedure UnHook;stdcall;
  102. begin
  103.   {發(fā)送卸載子類化消息給指定窗口}
  104.   SendMessage(DLLData^.HookWindow, WM_UNSUBCLASS, 00);
  105.   DLLData^.SubClass := False;
  106.   {卸載Hook}
  107.   UnhookWindowsHookEx(DLLData^.hHook);
  108. end;
  109. {------------------------------------}
  110. {過程名:DLL入口函數(shù)
  111. {過程功能:進(jìn)行DLL初始化,釋放等
  112. {過程參數(shù):DLL狀態(tài)
  113. {------------------------------------}
  114. procedure MyDLLHandler(Reason: Integer);
  115. var
  116.   FHandle: LongWORD;
  117. begin
  118.   case Reason of
  119.     DLL_PROCESS_ATTACH:
  120.     begin            {建立文件映射,以實現(xiàn)DLL中的全局變量}
  121.       FHandle := CreateFileMapping($FFFFFFFFnil, PAGE_READWRITE, 0$ff'MYDLLDATA');
  122.       if FHandle = 0 then
  123.       if GetLastError = ERROR_ALREADY_EXISTS then
  124.       begin
  125.         FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MYDLLDATA');
  126.         if FHandle = 0 then Exit;
  127.       end else Exit;
  128.       DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 000);
  129.       if DLLData = nil then
  130.         CloseHandle(FHandle);
  131.     end;
  132.     DLL_PROCESS_DETACH:
  133.       if Assigned(DLLData) then
  134.       begin
  135.         UnmapViewOfFile(DLLData);
  136.         DLLData := nil;
  137.       end;
  138.     DLL_THREAD_ATTACH:;
  139.     DLL_THREAD_DETACH:;
  140.   end;
  141. end;
  142. {$R *.res}
  143. exports
  144.   InstallHook, UnHook, HookProc;
  145. begin
  146.   DLLProc := @MyDLLHandler;
  147.   MyDLLhandler(DLL_PROCESS_ATTACH);
  148. end.

編譯這個DLL,然后在我們的程序中加載這個DLL,并調(diào)用InstallHook(目標(biāo)窗口句柄, 自己窗口句柄)就可  以實現(xiàn)對目標(biāo)窗口消息的監(jiān)視了(在接收到WM_NEWMESSAGE消息時讀映射的內(nèi)存),調(diào)用UnHook則可以卸載掉子類化和HOOK.具休的代碼還請讀者自行編寫.

  1. unit Unit2;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.   Dialogs, StdCtrls;
  6. const WM_NEWMESSAGE = WM_USER + 1002;
  7. type
  8.   TForm2 = class(TForm)
  9.     btn1: TButton;
  10.     btn2: TButton;
  11.     lst1: TListBox;
  12.     procedure btn1Click(Sender: TObject);
  13.     procedure btn2Click(Sender: TObject);
  14.   private
  15.     procedure ShowMsg(var Message:TMessage);message WM_NEWMESSAGE;
  16.   public
  17.     { Public declarations }
  18.   end;
  19.   function InstallHook(HWindow, SWindow: LongWORD):Boolean;stdcall;external 'Hook.dll';
  20.   procedure UnHook;stdcall;external 'Hook.dll';
  21. var
  22.   Form2: TForm2;
  23.   ListCount:Integer;
  24. implementation
  25. {$R *.dfm}
  26. procedure TForm2.ShowMsg(var Message:TMessage);
  27. begin
  28.   if Message.Msg = WM_MOUSEHOVER then
  29.   begin
  30.     ListCount:=ListCount+1;
  31.     Form2.lst1.AddItem(IntToStr(ListCount)+'.'+IntToStr(Message.WParam)+','+IntToStr(Message.lParam),nil);
  32.   end;
  33. end;
  34. function GetWindowHwnd:THandle;
  35. begin
  36.   Result:=FindWindow(nil,'ABCDE.txt - 記事本');
  37. end;
  38. procedure TForm2.btn1Click(Sender: TObject);
  39. var
  40.   TmpWndHandle: THandle;
  41. begin
  42.   TmpWndHandle := 0;
  43.   TmpWndHandle := GetWindowHwnd;
  44.   if not isWindow(TmpWndHandle) then
  45.   begin
  46.     MessageBox(self.Handle, '沒有找到指定窗口''!!!', MB_OK);
  47.     exit;
  48.   end;
  49.   InstallHook(TmpWndHandle,Handle);
  50. end;
  51. procedure TForm2.btn2Click(Sender: TObject);
  52. begin
  53.   UnHook;  //下message鉤子
  54. end
  55. end.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多