微软IE访问页面主要通过UrlMon库来实现对于页面以及附加资源的请求
UrlMon动态库调用WinInet处理相关HTTP\HTTPS请求
BHO ->Browser Help Object,浏览器辅助对象,BHO拥有较高权限
动态库注入最简单稳定的方法就是通过动态库的导入表来完成注入.
对于外部动态库导出的函数进行调用编译器自动形成导入表:CALL DS:[导入函数地址],所以修改只需要修改动态库在加载时候维护的导入表,即可以改变原是调用的函数,
这样可以把自己写的函数地址更改进去,然后再自己的函数内调用原始的函数,实现对于函数调用的监视,同时也可以对参数进行分析得到自己想要的数据,导入表的具体结构和存储位置可以查看
PE文件结构相关的资料.
WinInet处理HTTP请求主要函数HTTPOpenRequest,这个函数在进行页面请求是必须(InternetOpen函数微软资料显示是必须,但是我在IE9下没有监视到UrlMon对他的调用)
InternetSetStateCallback函数用于对HINTERNET句柄设置状态改变回调,
所以我们可以对HTTPOpenReques,InternetSetStateCallback两个函数进行监视就可以做到对请求的监视,HTTPOpenRequest函数中调用InternetSetStateCallback设置通知回调时自己的,然后同时维护HINTERNET句柄和原始回调的映射关系,我们可以在自己的状态改变回调函数进行处理,监视,修改,取消请求都可以做到。然后注入InternetSetStateCallback函数,防止系统后期调用这个函数改变回调,这个函数内只需要维护系统回调之间的关系,而不去调用真正的InternetOpenRequest函数,让我们的函数作为回调过滤器,在无法维护自己的映射关系时调用系统默认的函数将对应函数维护进去,保证就算你程序的BUG也要让浏览器正常工作。
当然对于其他系统函数进行监视也可以使用导入表注入的方式完成,如果直接注入系统函数内部就比较复杂了,需要计算指令长度,以及被你覆盖的指令并且在你自己的函数返回的时候执行原有的一些代码,所以相对难度大技术要求比较高,而且在不同系统版本中函数肯能有差异,可能需要为每个版本编写不同的代码,否则导致浏览器无法正常工作。
另外浏览器对于权限限制比较严格,特别是IE8和IE9 回调函数的执行线程权限相当低,所以很多时候需要其他的通讯方式调度高权限的代码。例如,消息队列,共享内存,文件映射。
以提高后期处理的时候的权限
关于BHO、URLMon、WinInet、PE文件结构的资料可以参见MSDN。