目标
钩取IE进程的API,当它在连接到特定网站的过程中,将其连接到其他网站,类似于拦截恶意网站功能
目标API
API钩取的核心就是选择目标API,我们首先猜测一下,可能会钩取套接字库(ws2_32.dll)、微软提供的网络访问的相关库(wininet.dll、winhttp.dll)就可以了。
查看IE加载了哪些DLL
在Wininet.dll中有个API(InternetConnect())用来连接某个网络
HINTERNET InternetConnectA(
[in] HINTERNET hInternet,
[in] LPCSTR lpszServerName,//要连接的URL
[in] INTERNET_PORT nServerPort,
[in] LPCSTR lpszUserName,
[in] LPCSTR lpszPassword,
[in] DWORD dwService,
[in] DWORD dwFlags,
[in] DWORD_PTR dwContext
);
验证:调试IE进程
我们用OD开启一个IE浏览器,在InternetConnect下断点,然后在浏览器输入www.baidu.com
程序会在InternetConnect断下来,连接地址就是我们输入的网站,现在我们将“www.baidu.com”改成“www.sohu.cocm”试试
这时候我们F9运行还是会在这断下来,因为一个网站是由多个链接地址组成,需要将断点删除后再运行
IE进程结构
我们先打开多个选项卡,用PChunter查看
PID为2628的iexplore.exe进程与其他几个iexplore.exe进程形成了父子关系,每个选项卡是一个单独的进程,所以当其中一个发生错误时,不会影响到其他的选项卡或者父进程。
由于创建新的选项卡就会创建新的进程,我们就需要钩取相关的进程API,达到全局钩取API的目的,否则新创建的选项卡在连接网站时无法钩取。
ntdll!ZwResumeThread()
在创建进程的API中最具有代表性的就是kernel32.CreateProcess()API,现在调试一下利用这个API编写的程序
#include<Windows.h>
#include<stdio.h>
#include<tchar.h>
void main(){
STARTUPINFO si={0,};
PROCESS_INFORMATION pi={0,};
TCAHR szCmd[MAX_PATH]={0,};
si.cb=sizeof(STARTUPINFO);
_tcscpy(szCmd,L"notepad.exe");
if(!CreateProcess(NULL,szCmd,NULL,NULL,FALSE,NORMAK_PRIORITY_CLASS,NULL,NULL,&si,&pi))
return ;
if(pi.hProcess!=NULL)
CloseHandle(pi.hProcess);
}
我们先跟踪到kernel32.CreateProcessW(),然后F7跟进内部
我们看到在内部又调用了kernel32!CreateProcessInternalW(),这里连续的PUSH和CreateProcessW是相同的参数
kernel32!CreateProcessInternalW()比较大,我们往下面拉,就能看到ntdll!ZwCreateUserProcess()
此时的栈空间和原来的区别很大
在执行完这个API后,我们的子进程就会被挂起,然后暂停运行,notepad.exe进程已经生成,但是其EP代码尚未运行。
ntdll!ZwResumeThread()函数就是用来恢复运行线程的。这个线程即是子进程的主线程,所以当执行完后,子进程的EP代码才会执行。
总结
综上所述,CreateProcessW()API的调用流程整理如下:
kernel32!CreateProcessW
kernel32!CreateProcessInternalW()
ntdll!ZwCreateUserProcess()
ntdll!ZwResumeThread()
创建子进程的过程中最后调用的API是ntdll!ZwResumeThread(),所以钩取该API。
注意
ntdll!ZwResumeThread()是尚未公开的API,函数定义如下:
NTSTATUS NtResumeThread{
IN HANDLE ThreadHandle,
OUT PULONG SuspendCount OPTIONAL
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 767778848@qq.com