初学 Hook ,简单的键盘 Hook,用了内存映象为什么不能 Hook 了呢 --- 200 分求教(200分)

  • 主题发起人 qi_jianzhou
  • 开始时间
Q

qi_jianzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
程序很简单
就是其它的程序中输入什么,我这里的 Memo 中就显示他的输入(当然不是汉字了 ^_^)
我用自定义消息的方式给主程序发消息,让其显示,击键保存在内存映象文件呢,主程序读内存映象来显示数据

==================== dll =========================
library KDll;

uses
SysUtils,
windows,
dialogs,
messages,
Classes;

const wm_k = wm_user+10;
type
PKeyInfo = ^TKeyInfo;
TKeyInfo = record
k:word;
end;

var
HH:HHOOK;
KeyInfo:pKeyInfo;
mh:THandle;

function KeyHookProc(nCode:integer;wparam,lparam:integer):integer;stdcall;
var
h:THandle;
begin
result := 0;
if nCode<0 then
windows.CallNextHookEx(hh,nCode,wparam,lparam)
else
begin
if ncode = windows.HC_Action then
begin
h := FindWindow(nil,pchar('KeyHook'));
// 内存映象
mh := windows.OpenFileMapping(windows.PAGE_READWRITE,false,pchar('KeyTest1'));
keyInfo := windows.MapViewOfFile(mh,windows.FILE_MAP_ALL_ACCESS,0,0,0);
keyInfo^.k := wparam; // 赋值 --> 这里没有赋值成功, 不知为什么
windows.UnmapViewOfFile(keyInfo);
closeHandle(mh);

sendmessage(h,wm_k,wparam,lparam); // 发送消息
end;
end;
end;

procedure HookOn;stdcall;
begin
hh := windows.SetWindowsHookEx(windows.WH_KEYBOARD,@keyHookProc,Hinstance,0);
end;

procedure HookOff;stdcall;
begin
windows.UnhookWindowsHookEx(hh);
end;


exports
HookOn,HookOff;

begin
end.
=================== 主程序 ====================
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

// 自定认一个消息
const wm_k = wm_user+10;

type
// 自定义结构
PKeyInfo = ^TKeyInfo;
TKeyInfo = record
k:word;
end;

TFormKeyHook = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure WMK(var msg:Tmessage);message wm_K;
public

end;

procedure HookOn;stdcall;external 'KDll.dll';
procedure HookOff;stdcall;external 'KDll.dll';

var
FormKeyHook: TFormKeyHook;
Mh:THandle;
KeyInfo:pKeyinfo;
implementation

{$R *.dfm}

procedure TFormKeyHook.Button1Click(Sender: TObject);
begin
HookOn;
mh := windows.CreateFileMapping($ffffffff,nil,
windows.PAGE_READWRITE,0,sizeof(TKeyInfo),pchar('KeyTest1'));
KeyInfo:= windows.MapViewOfFile(mh,windows.FILE_MAP_ALL_ACCESS,0,0,0);
//keyInfo^.k := mh;

end;

procedure TFormKeyHook.Button2Click(Sender: TObject);
begin
HookOff;
windows.UnmapViewOfFile(keyInfo);
closeHandle(mh);
end;

procedure TFormKeyHook.WMK(var msg:Tmessage);
begin
if msg.Msg = wm_k then
memo1.Lines.Add(char(Keyinfo^.k)); // 显示按键
end;

end.

==================================================


当我用 内存映象时,就不能 hook 了,但一去掉内存映象
直接

procedure TFormKeyHook.WMK(var msg:Tmessage);
begin
if msg.Msg = wm_k then
memo1.Lines.Add('aaa') ; // 这样显示,就没有问题
end;

不明白为什么用了内存映象就会不能 Hook ,请高手指点

万分感激
 
S

smokingroom

Unregistered / Unconfirmed
GUEST, unregistred user!
Dll中的OpenFileMapping函数改用CreateFileMapping,写法与主程序中的一样.
另:如果传递的数据很简单的话,可以直接将数据(比较你这里的key值)作为SendMessage
参数传递即可,无需要建立共享内存.
 
Q

qi_jianzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢 smokingroom ,我用 CreateFileMapping 成功,但为什么我用 openFileMapping 不行呢?还行指教

我用共享内存的方式,只是为了练习一下共享内存,我用 sendmessage 的方式试验成功了,所以想用共享内存的方式再试试

谢谢,就是搞不明白为什么要重新建立共享内存
 
A

andd_chen

Unregistered / Unconfirmed
GUEST, unregistred user!
问题很简单,因为你的内存映象是在主程序中建立的。根据某本书所说的(我有点健忘,记不清什么书了,好象是核心编程样),操作系统会自动为运行的程序分配内存空间,当然包括你建立的内存映象了(是在你主程序的内存堆栈里的!)。而hook,我们知道的是他用的是公共内存块(0x80000)以上的,所以,你在hook代码中去调用别人内存块的东西(0x8000以下)当然就不行了。
我也是好久没搞这个东西了,有点忘了,也不知说的对不对,还请指正
 
Q

qi_jianzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
andd_chen:

内存映象就是了为多个程序共享某一块内存空间,所以上面你说的有问题,而 smokingroom 的方法是正确的,可以就是 openFileMapping 本身有问题吧 用CreateFileMapping 就可以了,

谢谢你的回答
 
Q

qi_jianzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
结束了 ^_^
 
顶部