相同的代码,用来Hook窗口显示。
D7编译出来的,不管怎么测试,都是正常的。Delphi2007编译出来的,挂钩后,运行也都正常,但在卸钩后,会导致资源管理器或者任务管理器错误。
出现错误的测试过程:
先打开任务管理器(别关掉),执行主程序,挂钩,打开一个有窗口的程序(别关掉),退出主程序。
任务栏鼠标右键->任务管理器,出错。 我这里只要这么操作,就一定出错。
代码上传到download频道了,跟我下面贴的代码有一两行不一样。
http://download.csdn.net/source/651499 有兴趣的,下载下来帮忙看看。
不过要注意,很可能会造成任务管理器和资源管理器崩溃。
实际工程内容比较多,想在D7下重新改写已经不太现实了。就想知道Delphi2007下,应该怎么解决。谢谢
不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
Dll部分代码:
library makeErr;uses
Messages,
Classes,
SysUtils,
Windows,
Dialogs,
ComServ,
theMain in 'theMain.pas';exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;{$R *.RES}
const
HookMemFileName = 'DllHookMemFile.DTA';var
PShare: PShareMem;
MapHandle: THandle;function CallWndProc(nCode: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
var winStruct: TCWPStruct;
begin
winStruct := PCWPSTRUCT(LParam)^;
if nCode >= 0 then
begin
if winStruct.message = WM_SHOWWINDOW then
begin
SaveInfo('发现窗口创建:::' + inttostr(winStruct.hwnd));
end;
end; Result:= CallNextHookEx(0, nCode, WParam, LParam);
end;procedure StartHook; stdcall;
begin
if PShare^.HookHandle = 0 then
begin
PShare^.HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, PShare^.HookProc, HInstance, 0);
SaveInfo('钩子启动完毕,钩子句柄:::' + inttostr(PShare^.HookHandle));
end;
end;procedure StopHook; stdcall;
var unhookResult: Boolean;
begin
if PShare^.HookHandle <> 0 then
begin
unhookResult := UnhookWindowsHookEx(PShare^.HookHandle);
if unhookResult then
begin
PShare^.HookHandle := 0;
SaveInfo('钩子卸载完毕'); end
else
SaveInfo('钩子卸载失败');
end
else
SaveInfo('PShare^.HookHandle为空:::' + inttostr(PShare^.HookHandle));
end;procedure DllEntry(dwReason: DWORD);
begin
case dwReason of
DLL_PROCESS_DETACH:
begin
saveinfo('dll 卸载,MapHandle:::' + inttostr(MapHandle));
UnmapViewOfFile(PShare);
closehandle(MapHandle);
SaveInfo('共享内存关闭');
end;
// else;
end;end;
exports StartHook, StopHook;
begin
saveinfo('dll 入口执行,MapHandle:::' + inttostr(MapHandle));
MapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, pchar(HookMemFileName));
saveinfo('得到共享内存句柄:::' + inttostr(MapHandle)); if MapHandle = 0 then
begin
MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(TShareMem), pchar(HookMemFileName));
SaveInfo('共享内存创建:::' + inttostr(MapHandle));
end; PShare := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);// FillChar(PShare^, SizeOf(TShareMem), 0);
PShare^.HookProc := @CallWndProc; DllProc := @DllEntry;
// DllEntry(DLL_PROCESS_ATTACH);
end.
theMain.pasunit theMain;interface
uses
Windows,SysUtils;type
THookProc = function(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
PShareMem = ^TShareMem;
TShareMem = packed record
Data: String[255];
HookHandle:HHook;
HookProc: THookProc;
end; procedure SaveInfo(str: string); stdcall;implementation
procedure SaveInfo(str: string); stdcall;
var
f: textfile;
begin
assignfile(f,'d:\Records.txt'); if FileExists('d:\Records.txt') = false then
rewrite(f)
else
append(f); writeln(f, str);
closefile(f);
end;initializationfinalizationend.调用主程序MainForm.pas:
unit MainForm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton; procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure SaveInfo(str: string);
public
{ Public declarations }
end;//procedure StartHook; stdcall; external 'makeErr.dll' name 'StartHook';
//procedure StopHook; stdcall; external 'makeErr.dll' name 'StopHook';var
Form1: TForm1; StartHook:procedure; stdcall;
StopHook :procedure; stdcall;
moduleHandle : THandle;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
moduleHandle:= loadlibrary(pchar('makeErr.dll'));
StartHook := GetProcAddress(moduleHandle, 'StartHook');
StopHook := GetProcAddress(moduleHandle, 'StopHook'); if (@StartHook<>nil) then StartHook;
end;procedure TForm1.SaveInfo(str: string);
var
f: textfile;
begin
assignfile(f,'d:\Records.txt'); if FileExists('d:\Records.txt') = false then
rewrite(f)
else
append(f); writeln(f, str);
closefile(f);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveInfo('开始卸载钩子');
if @StopHook<>nil then
StopHook
else
SaveInfo('未找到卸载函数'); freelibrary(moduleHandle); SaveInfo('关闭主程序');
end;end.用Delphi2009也试了一下,发现Hook也不正常,从日志文件里能看到莫名其妙的不停在发现窗口创建,就好像被挂钩很多次似的。不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
明天加分到200.
D7编译出来的,不管怎么测试,都是正常的。Delphi2007编译出来的,挂钩后,运行也都正常,但在卸钩后,会导致资源管理器或者任务管理器错误。
出现错误的测试过程:
先打开任务管理器(别关掉),执行主程序,挂钩,打开一个有窗口的程序(别关掉),退出主程序。
任务栏鼠标右键->任务管理器,出错。 我这里只要这么操作,就一定出错。
代码上传到download频道了,跟我下面贴的代码有一两行不一样。
http://download.csdn.net/source/651499 有兴趣的,下载下来帮忙看看。
不过要注意,很可能会造成任务管理器和资源管理器崩溃。
实际工程内容比较多,想在D7下重新改写已经不太现实了。就想知道Delphi2007下,应该怎么解决。谢谢
不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
Dll部分代码:
library makeErr;uses
Messages,
Classes,
SysUtils,
Windows,
Dialogs,
ComServ,
theMain in 'theMain.pas';exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;{$R *.RES}
const
HookMemFileName = 'DllHookMemFile.DTA';var
PShare: PShareMem;
MapHandle: THandle;function CallWndProc(nCode: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
var winStruct: TCWPStruct;
begin
winStruct := PCWPSTRUCT(LParam)^;
if nCode >= 0 then
begin
if winStruct.message = WM_SHOWWINDOW then
begin
SaveInfo('发现窗口创建:::' + inttostr(winStruct.hwnd));
end;
end; Result:= CallNextHookEx(0, nCode, WParam, LParam);
end;procedure StartHook; stdcall;
begin
if PShare^.HookHandle = 0 then
begin
PShare^.HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, PShare^.HookProc, HInstance, 0);
SaveInfo('钩子启动完毕,钩子句柄:::' + inttostr(PShare^.HookHandle));
end;
end;procedure StopHook; stdcall;
var unhookResult: Boolean;
begin
if PShare^.HookHandle <> 0 then
begin
unhookResult := UnhookWindowsHookEx(PShare^.HookHandle);
if unhookResult then
begin
PShare^.HookHandle := 0;
SaveInfo('钩子卸载完毕'); end
else
SaveInfo('钩子卸载失败');
end
else
SaveInfo('PShare^.HookHandle为空:::' + inttostr(PShare^.HookHandle));
end;procedure DllEntry(dwReason: DWORD);
begin
case dwReason of
DLL_PROCESS_DETACH:
begin
saveinfo('dll 卸载,MapHandle:::' + inttostr(MapHandle));
UnmapViewOfFile(PShare);
closehandle(MapHandle);
SaveInfo('共享内存关闭');
end;
// else;
end;end;
exports StartHook, StopHook;
begin
saveinfo('dll 入口执行,MapHandle:::' + inttostr(MapHandle));
MapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, pchar(HookMemFileName));
saveinfo('得到共享内存句柄:::' + inttostr(MapHandle)); if MapHandle = 0 then
begin
MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(TShareMem), pchar(HookMemFileName));
SaveInfo('共享内存创建:::' + inttostr(MapHandle));
end; PShare := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);// FillChar(PShare^, SizeOf(TShareMem), 0);
PShare^.HookProc := @CallWndProc; DllProc := @DllEntry;
// DllEntry(DLL_PROCESS_ATTACH);
end.
theMain.pasunit theMain;interface
uses
Windows,SysUtils;type
THookProc = function(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
PShareMem = ^TShareMem;
TShareMem = packed record
Data: String[255];
HookHandle:HHook;
HookProc: THookProc;
end; procedure SaveInfo(str: string); stdcall;implementation
procedure SaveInfo(str: string); stdcall;
var
f: textfile;
begin
assignfile(f,'d:\Records.txt'); if FileExists('d:\Records.txt') = false then
rewrite(f)
else
append(f); writeln(f, str);
closefile(f);
end;initializationfinalizationend.调用主程序MainForm.pas:
unit MainForm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton; procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure SaveInfo(str: string);
public
{ Public declarations }
end;//procedure StartHook; stdcall; external 'makeErr.dll' name 'StartHook';
//procedure StopHook; stdcall; external 'makeErr.dll' name 'StopHook';var
Form1: TForm1; StartHook:procedure; stdcall;
StopHook :procedure; stdcall;
moduleHandle : THandle;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
moduleHandle:= loadlibrary(pchar('makeErr.dll'));
StartHook := GetProcAddress(moduleHandle, 'StartHook');
StopHook := GetProcAddress(moduleHandle, 'StopHook'); if (@StartHook<>nil) then StartHook;
end;procedure TForm1.SaveInfo(str: string);
var
f: textfile;
begin
assignfile(f,'d:\Records.txt'); if FileExists('d:\Records.txt') = false then
rewrite(f)
else
append(f); writeln(f, str);
closefile(f);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveInfo('开始卸载钩子');
if @StopHook<>nil then
StopHook
else
SaveInfo('未找到卸载函数'); freelibrary(moduleHandle); SaveInfo('关闭主程序');
end;end.用Delphi2009也试了一下,发现Hook也不正常,从日志文件里能看到莫名其妙的不停在发现窗口创建,就好像被挂钩很多次似的。不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
明天加分到200.
先打开任务管理器(别关掉),执行主程序,挂钩,打开一个有窗口的程序(别关掉),退出主程序。
任务栏鼠标右键->任务管理器,出错。
也用Delphi2007编译过吗?我的Delphi2007就是你给我的那个啊,一模一样啊,我RP有问题?
主机Win2003+sp2测试都有问题
1.文件访问失败,报异常,从而Hook释放失败,解决办法是在写文件的时候使用互斥,或者加try ... except
2.由于使用到String对象,多线程导致内存访问违例,Hook释放失败.设置IsMultiThread 为True,强制内存管理器启用线程安全管理.
但我试过,加了ShareMem,干脆加载不了Dll了
IsMultiThread 我也试了,问题依旧
看有人讨论FastMM,不知道这个跟我的问题是否有关系。
Delphi2009我也试了,也是出现错误。