Hook全版本IE并修改网址的示例分析
更新:HHH   时间:2023-1-7


这篇文章将为大家详细讲解有关Hook全版本IE并修改网址的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

正文

先导入一波引用

#include <windows.h>
#include <WinInet.h>
#include <string>
#include <iostream>
using std::string;
using namespace std;
#pragma comment(lib,"wininet.lib")

首先我们知道http应用层的函数基本都在wininet.dll中故我们导出wininet.dll的函数列表(这里我使用的是ProcessHacker)

我们要对Url进行拦截修改所以先要查找和Url有关的函数,这边的Delay验证了我之前说的wininet.dll是延迟导入IAT HOOK是无效的。

这里我们找到了InternetCrackUrl这个函数同时上面一个InternetConnect看上去非常有用,调试IE在该函数加断点 这里我使用的是开源的x64_dbg 输入指令bp InternetConnectW

这样我们可以确定IE在访问网址是必然会执行这个函数我们需要对其进行inline hook,避免大家采坑说明一下IAT Hook是行不通的,IE浏览器进行了DelayLoad,一开始并没有加载wininet.dll,通过查找wininet.h我们可以得到该函数的参数以及类型

typedef HINTERNET(WINAPI *tInternetConnectWFunc)
(
 HINTERNET     hInternet,
 LPCWSTR       lpszServerName,
 INTERNET_PORT nServerPort,
 LPCWSTR       lpszUserName,
 LPCWSTR       lpszPassword,
 DWORD         dwService,
 DWORD         dwFlags,
 DWORD_PTR     dwContext
);

注意一定要引入wininet.h不然会有类型找不到

接下来我们需要准备一个变量来存储该函数的原调用

tInternetConnectWFunc oInternetConnectWFunc ;

然后需要编写该函数的新回调,注意这边用到了Hook和UnHook需要现在头部声明,另外WCharToMByte这个转换函数在文章最后我会给出。

HINTERNET WINAPI hkInternetConnectW(
 HINTERNET hInternet,//internet句柄(我是这么理解的)
 LPCWSTR lpszServerName,//服务器名
 INTERNET_PORT nServerPort,//端口
 LPCWSTR lpszUserName,
 LPCWSTR lpszPassword,
 DWORD dwService,
 DWORD dwFlags,
 DWORD_PTR dwContext
)
{
 UnHook();//先解除hook取得返回值后在重新Hook
 oInternetConnectWFunc = (tInternetConnectWFunc)GetProcAddress(GetModuleHandle(L"wininet.dll"), "InternetConnectW");//通过wininet.dll获取原函数并转换成我们声明好的类型
 LPCWSTR url = lpszServerName;
 if (WCharToMByte(url).find("*****.com") == string::npos)//此处判断是否是某地址不是强制修改为某地址
 {
  url = L"*****.com";
 }
 HINTERNET rest = oInternetConnectWFunc(hInternet, url, nServerPort, lpszUserName, lpszPassword, dwService, dwFlags, dwContext);//再次强调现货区返回值在恢复hook
 InHook();
 return rest;
}

接下来是InLineHook非常简单

BYTE oldAddress[5];
BYTE newAddress[5] = { 0xE9 };
void InHook()
{
 memcpy(oldAddress, InternetConnectW, 2); //保存原字节
 BYTE pByte[2] = { 0xEB,0xF9 }; //优化以防重复Hook
 if (*(BYTE*)InternetConnectW == 0xEB)
  return;

 // 计算偏移
 DWORD Offset = (DWORD)hkInternetConnectW - (DWORD)InternetConnectW;
 *(DWORD*)(newAddress + 1) = Offset;
 
 DWORD Protect;
 VirtualProtect((LPVOID)((DWORD)InternetConnectW - 5), 7, PAGE_EXECUTE_READWRITE, &Protect);//修改内存属性

 // 修改函数地址数据
 memcpy((LPVOID)((DWORD)InternetConnectW - 5), newAddress, 5);
 memcpy(InternetConnectW, pByte, 2);
 
 VirtualProtect((LPVOID)((DWORD)InternetConnectW - 5), 7, Protect, &Protect);// 还原内存属性
}
void UnHook()
{
 DWORD Protect;
 VirtualProtect(InternetConnectW, 2, PAGE_EXECUTE_READWRITE, &Protect);
 memcpy(InternetConnectW, oldAddress, 2);
 VirtualProtect(InternetConnectW, 2, Protect, &Protect);
}

最后就是dll的入口

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
  InHook();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

最后是讲LPCESTR 转换成string的函数,该函数需要放在最上面,或者先声明在调用

string WCharToMByte(LPCWSTR lpcwszStr)
{
 string str;
 DWORD dwMinSize = 0;
 LPSTR lpszStr = NULL;
 dwMinSize = WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, NULL, 0, NULL, FALSE);
 if (0 == dwMinSize)
 {
  return FALSE;
 }
 lpszStr = new char[dwMinSize];
 WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, lpszStr, dwMinSize, NULL, FALSE);
 str = lpszStr;
 delete[] lpszStr;
 return str;
}

到这里基本就完成了,这边值得注意的是ie11有多个进程主进程是64位每个标签的子进程是32位故此我们需要编译成Release x86 和x64两个版本,注入我这边测试是使用ProcessHacker进行注入的

需要对ie的所有进程进行注入,如果自己编写注入器的话需要注意x86和x64的区分注入方法非常多这里我就不多做累述了,值得注意的是虽然Proccess Hacker是驱动级任务管理器,但是部分进程他还是无法直接注入的,需要大家自己编写注入代码。

最后附上效果图

无法上传视频对效果图简单说明一下tab栏显示的是tb实际上却是bd,对于其他浏览器不一定直接使用InternetConnectW,但是大家也可以通过此方法调试浏览器后写出方法。

关于“Hook全版本IE并修改网址的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

返回数据安全教程...