主程序注入dll到另一个程序中,然后HOOK监测到WM_WINDOWPOSCHANGED事件后就把WM_WINDOWPOSCHANGED中的WINDOWPOS结构体数据通过sendmessage发回到主程序中。
unit u_dllHook;interfaceuses
Windows, SysUtils, Messages, Dialogs;const
WM_USERCREATE = WM_USER + 122;
WM_USERWINDOWPOSCHANGED = WM_USER + 123; // 定义一个消息来通知主程序
WM_USERDESTROY = WM_USER + 124;function installDLL(ss: THandle): Boolean; stdcall; // 导出的2个函数 挂钩和解钩
function uninstallDLL: Boolean; stdcall;var
ahook: HHOOK; // 钩子
// F:TextFile; //本来用来生成log文件调试钩子的.后来没有用了
hmapFile: THandle; // 映像文件句柄
pH: PHandle; // 保存主程序的句柄
aName: array [0 .. 255] of Char; // 用来保存挂钩程序的exe名字的
bBool: Boolean; // 是不是勾上了进程implementation// cbt钩子回调函数function CBTProc(icode: Integer; awParam: WPARAM; alParam: LPARAM): LongInt;
stdcall;
var
Data: TCWPStruct;
WindowText, WindowClass: Array [0 .. 254] of Char;
begin
Result := 0;
// 根据msdn上面说的 如果icode小于0,就不进行处理,下一步
if icode < 0 then
begin
Result := CallNextHookEx(ahook, icode, awParam, alParam);
Exit;
end;
Data := (PCWPStruct(alParam))^;
case Data.message of
WM_WINDOWPOSCHANGED:
begin
if not bBool then
begin
//SendMessage(ph^,WM_USERWINDOWPOSCHANGED,data.hwnd,data.lParam); 此处发送消息回主程序lParam是一个WINDOWPOS指针,内容传不回去
end;
end;
WM_DESTROY:
begin
end;
end;
end;// 装钩子,传入主程序句柄
function installDLL(ss: THandle): Boolean; stdcall;
begin
ahook := SetWindowsHookEx(WH_CALLWNDPROC, @CBTProc, HInstance, 0);
// 全局cbt 钩子.
Result := ahook <> 0;
pH^ := ss
end;// 卸载钩子function uninstallDLL: Boolean; stdcall;
begin
if ahook <> 0 then
begin
UnhookWindowsHookEx(ahook);
Result := ahook = 0;
end;
end;initialization// 先判断被钩进程的名字 是桌面进程就不钩了,因为容易被钩死掉
GetModuleFileName(0, aName, 256);
bBool := SameText(ExtractFileName(aName), 'Explorer.exe');
if not bBool then // 不是就生成映像文件
begin
hmapFile := OpenFileMapping(FILE_MAP_WRITE, False, 'FollowMap');
//
if hmapFile = 0 then
hmapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf
(THandle), 'FollowMap');
if hmapFile = 0 then
Exception.Create('不能创建内存映像');
//
pH := MapViewOfFile(hmapFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
if pH = nil then
begin
CloseHandle(hmapFile);
Exception.Create('不能共享内存');
end;
end;finalization// 钩子在退出的时候关闭映像文件
if not bBool then
begin
UnmapViewOfFile(pH);
CloseHandle(hmapFile);
end;end.
unit u_dllHook;interfaceuses
Windows, SysUtils, Messages, Dialogs;const
WM_USERCREATE = WM_USER + 122;
WM_USERWINDOWPOSCHANGED = WM_USER + 123; // 定义一个消息来通知主程序
WM_USERDESTROY = WM_USER + 124;function installDLL(ss: THandle): Boolean; stdcall; // 导出的2个函数 挂钩和解钩
function uninstallDLL: Boolean; stdcall;var
ahook: HHOOK; // 钩子
// F:TextFile; //本来用来生成log文件调试钩子的.后来没有用了
hmapFile: THandle; // 映像文件句柄
pH: PHandle; // 保存主程序的句柄
aName: array [0 .. 255] of Char; // 用来保存挂钩程序的exe名字的
bBool: Boolean; // 是不是勾上了进程implementation// cbt钩子回调函数function CBTProc(icode: Integer; awParam: WPARAM; alParam: LPARAM): LongInt;
stdcall;
var
Data: TCWPStruct;
WindowText, WindowClass: Array [0 .. 254] of Char;
begin
Result := 0;
// 根据msdn上面说的 如果icode小于0,就不进行处理,下一步
if icode < 0 then
begin
Result := CallNextHookEx(ahook, icode, awParam, alParam);
Exit;
end;
Data := (PCWPStruct(alParam))^;
case Data.message of
WM_WINDOWPOSCHANGED:
begin
if not bBool then
begin
//SendMessage(ph^,WM_USERWINDOWPOSCHANGED,data.hwnd,data.lParam); 此处发送消息回主程序lParam是一个WINDOWPOS指针,内容传不回去
end;
end;
WM_DESTROY:
begin
end;
end;
end;// 装钩子,传入主程序句柄
function installDLL(ss: THandle): Boolean; stdcall;
begin
ahook := SetWindowsHookEx(WH_CALLWNDPROC, @CBTProc, HInstance, 0);
// 全局cbt 钩子.
Result := ahook <> 0;
pH^ := ss
end;// 卸载钩子function uninstallDLL: Boolean; stdcall;
begin
if ahook <> 0 then
begin
UnhookWindowsHookEx(ahook);
Result := ahook = 0;
end;
end;initialization// 先判断被钩进程的名字 是桌面进程就不钩了,因为容易被钩死掉
GetModuleFileName(0, aName, 256);
bBool := SameText(ExtractFileName(aName), 'Explorer.exe');
if not bBool then // 不是就生成映像文件
begin
hmapFile := OpenFileMapping(FILE_MAP_WRITE, False, 'FollowMap');
//
if hmapFile = 0 then
hmapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf
(THandle), 'FollowMap');
if hmapFile = 0 then
Exception.Create('不能创建内存映像');
//
pH := MapViewOfFile(hmapFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
if pH = nil then
begin
CloseHandle(hmapFile);
Exception.Create('不能共享内存');
end;
end;finalization// 钩子在退出的时候关闭映像文件
if not bBool then
begin
UnmapViewOfFile(pH);
CloseHandle(hmapFile);
end;end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, RzPanel, jpeg, RzShellDialogs;const
WM_CopyDateDestory = wm_user + 100; //self define messagetype
TPerson = packed record
Name :string[10];
Age :Integer;
end;type
Tserver = class(TForm)
RzPanel1: TRzPanel;
RzPanel2: TRzPanel;
RzPanel3: TRzPanel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Edit3: TEdit;
Image_D: TImage;
RzPanel4: TRzPanel;
RzPanel5: TRzPanel;
Image_s: TImage;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations } public
{ Public declarations }
procedure _WM_COPYDATA(var _Msg :TMessage);message WM_COPYDATA;
end;var
server: Tserver;
_PictureMemoryStream :TMemoryStream;implementation{$R *.dfm}procedure Tserver._WM_COPYDATA(var _Msg :TMessage);
var
_CopyData :TCopyDataStruct;
_Person :TPerson;
_MemStream :TMemoryStream;
_MemSize :Cardinal;
_Buf :array of Char;
begin
if _Msg.Msg = WM_COPYDATA then
begin
if _Msg.WParam = $02 then
begin
_CopyData := PCopyDataStruct(_Msg.LParam)^;
_Person := TPerson(_CopyData.lpData^);
Edit3.Text := _Person.Name + IntToStr(_Person.Age);
end
else if _Msg.WParam = $03 then
begin
_MemStream := TMemoryStream.Create;
_CopyData := PCopyDataStruct(_Msg.LParam)^;
_MemSize := _CopyData.cbData; //mothod 1 ---------------------------------------------------------------
SetLength(_Buf, _MemSize);
Move(_CopyData.lpData^, _Buf[0], _MemSize);
_MemStream.WriteBuffer(_Buf[0], _MemSize);
//------------------------------------------------------------------------ //mothod 1 ---------------------------------------------------------------
//_MemStream.WriteBuffer(_CopyData.lpData^, _MemSize);
//------------------------------------------------------------------------
_MemStream.SaveToFile('d:\1.jpg');
_MemStream.Free;
Image_D.Picture.LoadFromFile('d:\1.jpg');
end
else if _Msg.Msg = WM_CopyDateDestory then
begin
if _PictureMemoryStream <> nil then
begin
_PictureMemoryStream.Free;
_PictureMemoryStream := nil;
end;
end;
end;
end;
procedure Tserver.Button1Click(Sender: TObject);
var
_CopyData :TCopyDataStruct;
_Person :TPerson;
begin
_Person.Name := Edit1.Text;
_Person.Age := StrToInt(Edit2.Text); _CopyData.dwData := 0;
_CopyData.cbData := SizeOf(_Person);
_CopyData.lpData := @_Person; SendMessage(Handle, WM_COPYDATA, $02, LongWord(@_CopyData));
end;procedure Tserver.Button2Click(Sender: TObject);
var
_PictureCopyDat :TCopyDataStruct;
_FileSize :Int64;
_hwnd :HWND;
begin
if _PictureMemoryStream = nil then
_PictureMemoryStream := TMemoryStream.Create;
Image_s.Picture.Graphic.SaveToStream(_PictureMemoryStream);
_PictureCopyDat.dwData := 0;
_FileSize := _PictureMemoryStream.Size;
_PictureCopyDat.cbData := _FileSize;
_PictureCopyDat.lpData := _PictureMemoryStream.Memory;
_hwnd := FindWindow(nil,'client');
if _hwnd <> 0 then
SendMessage(_hwnd, WM_COPYDATA, $03, Cardinal(@_PictureCopyDat));//send other program SendMessage(Handle, WM_COPYDATA, $03, Cardinal(@_PictureCopyDat)); //send this program
end;procedure Tserver.FormCreate(Sender: TObject);
begin
_PictureMemoryStream := TMemoryStream.Create;
end;procedure Tserver.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if _PictureMemoryStream <> nil then
begin
_PictureMemoryStream.Free;
_PictureMemoryStream := nil;
end;
end;end.