此文章的代码可以从此处下载:http://www.codeproject.com/KB/shell/RetrieveHttponlyCookies.aspx
开发中经常使用到WebBrowser。WebBrowser控件编程控制起来很方面,好处不用说了。
但日前遇到一个问题,如何获取HTTP服务器页面返回的HTTP HEADER(不是DOM的head)?
比如说ASP.Net页面返回的SessionID,尝试通过DOM的 IHTMLDocument2::get_cookie 获取不到
浏览器控件并没有提供此类接口。那就HOOK吧。
HOOK winsock? HTTP协议不想去分析啊
通过Depends.exe查看mshtml.dll, 发现HTTP的时候使用了 WinInet.dll,WinInet.dll的升级版WinHttp.dll早出来了,不知M$怎么还在用WinInet.dll. 不过没关系,只要能够HOOK到 mshtml.dll 对 WinInet.dll 的调用,什么问题都解决了。HOOK WinInet.dll 还不需要去处理HTTP协议底层,多简单啊。
进程内HOOK是很简单的,不用考虑内存空间问题。HOOK一般分2种:inline hook和dispatch hook.
inline hook具有普适性,但dispatch hook具有robust性, (呃,这个词常被翻译成鲁棒性,健壮性就健壮性吧)
可爱的 SSDT GDT IDT HOOK都属于此类。那还是用后者吧。
扯远了,扯远了。在这里是HOOK IAT,IAT是导入函数表(Import Address Table)的缩写,对它的HOOK例子网上一抄一大把,原理就不细说了,废话都被说完了,看代码吧。
首先导入一些头文件和库文件,后面的代码要用
如果你有DDK/WDK最好了,没有的话需要加入一点点定义,后面需要用到
呃,为什么我要使用到一些内核中的结构?
一般的HOOK方式是HOOK Kernel32.dll 中的 LoadLibrar(Ex) 和 GetProcAddress 来检测动态加载的DLL以及通过函数指针方式的调用。
不过这里是HOOK NTDLL.DLL中的 LdrLoadDll 和 LdrGetProcedureAddress 。这2个API更彻底,LoadLibrar(Ex) 和 GetProcAddress 最终都是通过它们实现。NTDLL.DLL是Win32 SubSystem调用 Ring3 通往 Ring0 的最后一道门户,HOOK它更加彻底和保险。
所以这里要用到一点点内核中的结构。
现在最主要的问题是HOOK WinInet的调用,函数定义直接查MSDN就可以了。这里只HOOK的一部分的函数,根据需要你可以增加更多的函数。
首先定义函数指针
变量定义起来:
初始化以及转接函数如下:
终于到了最核心的部分了。
唯一需要注意的事:挂接IAT需要到 IMAGE_IMPORT_DESCRIPTOR 和 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 两个地方查找。
此代码可以扩展用来在浏览器底层去做到网络方面很细节的控制。