通过钩子监听和获取windows登录密码(part 1)
终于静下心来写这篇博文。在遥远的过去(两个星期前),我曾经用了一周的时间去尝试弄一个小程序,在windows登录的时候企图获取密码。当然,这是在高举“以学习为目的”这旗帜下进行的。上星期前半段时间在补作业,然后就开始python之路,所以一直没有心思总结一下那个获取密码的小程序。为了不让这边博文夭折,所以现在就狠下心来写了。
这个程序的主线是:windows的钩子和windows服务编程。本文中提到的所有函数,可以用msdn查查。
关于这个程序的编写,主要经历了以下几个阶段:
1.有关钩子的函数的用法
2.Dll的编写
3.windows启动过程
4.windows服务编写
本部分将要用到的函数有
SetWindowsHookEx
HOOKPROC
CallNextHookEx
UnhookWindowsHookEx
在讲有关钩子的函数之前,有必要搞清楚什么是钩子:下面的介绍是根据msdn中有关钩子的介绍翻译出来的(献丑了~)
系统支持多种不同的钩子,每种钩子对应windows消息处理机制的不同方面。例如,一个应用程序可以用WH_HOUSE钩子来监控鼠标信息的传输。
系统为每种类型的钩子维护一个独立的钩子链,每个钩子链其实就是一个由特殊的,应用程序定义的,叫作钩子处理函数(hook procedure)的可回调函数的指针组成的列表。当和某个钩子相关的消息产生时,系统传递消息给相应的钩子链,并从链表都开始,该消息将传递给里面的所有钩子处理函数,每个钩子都能决定是否往下一个钩子传递消息。此外,值得注意的是某些钩子的处理程序只能监控消息,并且往下传递消息(而不管该钩子处理函数是否要往下传递消息),其他的钩子的处理函数能修改消息或者停止消息在链里面的传递,阻止消息到达下一个钩子处理函数或者目标窗口。
顺便讲讲钩子作用域的分类:全局和局部。全局钩子就监控钩子所在桌面的所有线程。局部钩子就监控一个进程的独立的线程。
上面的解释中出场律最高的是钩子处理函数,那就让我从钩子处理函数说起吧。注:函数名可以自定义,但是参数列表和返回值必须和下面的原型一致
LRESULT CALLBACK HookProc( int nCode, //nCode 是钩子代码,用于说明钩子的行为。这个值和钩子类型相关,每类钩子有自己的钩子代码集 WPARAM wParam, //wParam和lParam依赖于钩子代码,一般来说它们包含将要传送的消息的信息 LPARAM lParam );
现在已经知道了钩子处理函数的原型,它要做的事情是用户自定义的,没什么好说的。但是有一个东西,虽然是按照用户的喜好来定义,但是却能影响消息的传递,那就是在钩子处理函数中用于决定消息是否往下一个钩子传递的传递函数CallNextHookEx。
LRESULT CallNextHookEx(
HHOOK hhk, //在windows 95/98/ME中,这是一个指向当前hook的句柄;在windwos XP/NT/2003时代,这个参数是被无视的
int nCode, //下面的参数都是传递到钩子处理函数中的参数
WPARAM wParam,
LPARAM lParam
);
由上面的解释可以看到钩子的伟大之处,而把那个伟大的钩子挂到钩子链头(注意,是钩子链头哦~)的函数。
HHOOK SetWindowsHookEx( int idHook, //idHook 说明将要挂载的钩子的类型 HOOKPROC lpfn, //lpfn 指向钩子处理函数的指针,如果dwThreadId = 0 或者所指向的线程是有其他进程产生的,lpfn参数必须指向一个在Dll中的钩子处理函数。否则,lpfn可以指向一个和当前进程代码结合的钩子处理函数(看起来很拗口,其实就是说:如果你要把钩子挂到别人的进程上,那么钩子处理函数必须放在Dll中……) HINSTANCE hMod, //包含lpfn指向的钩子处理函数的Dll的句柄。当dwThreadId表示一个由当前进程创建的线程或者是钩子函数在当前进程的代码中时,hMod必须为NULL(还是一句话:不用Dll就把它设置为NULL- -|||) DWORD dwThreadId //说明钩子处理函数将要关联的线程id。如果dwThreadId=0,则钩子处理函数将关联所有在相同桌面中的线程作为监听线程(注意,相同桌面这点很重要,我就是因为没有理解到这句话的深层含义而浪费了几小时的生命T_T) );
本想说到这里就可以把钩子装好了,但是这样貌似很办负责任,因为装进去的钩子没有在没用的时候卸载掉,所以,最后要讲述一下钩子的卸载。
BOOL UnhookWindowsHookEx(//注:这个函数专门用来卸载由SetWindowsHookEx加载的钩子
HHOOK hhk //将要移除的钩子的句柄,一般由之前调用SetWindowsHookEx时获得
);
注:由于这个程序要调试起来比较困难,尤其是无法运行的时候,根本不知道哪里有问题。这时可以用GetLastError(),这个函数将会返回该程序最后的一个错误的代码,然后根据错误代码可以查出是什么错误。因此在起初的时候,我在程序的关键处(主要是要用到动态的地方,都放了这个函数,并且都打印了错误代码,这样才能勉强进行调试= =
2010年4月23日 05:26
part two呢?
2019年8月06日 17:38
Thanks for sharing such a good info. <a href="http://www.ottawalife.com/">http://www.ottawalife.com/</a>
2019年8月06日 17:41
IAML’s blogs are really great and often to the next level as in this they would make you learn how to get window login passwords. Now you can [url=https://icasinoreviews.info/lucky-nugget-nz/]check here at iCasinoReviews[/url] more games to pass their time. Is it not great to have this access through blog? Of course yes, then don’t wait any more go and get it now.