|
最近写一个需要嵌入 WebBrowser 的东西,可是 WebBrowser 控件会直接继承 IE 的 Cookies,我想摆脱这一点。网上查了下 WebBrowser 是通过一个注册表设置读取 Cookies 存储路径的,经测试确实如此,使用了 RegQueryValue 来读取 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Cookies 里的路径。 于是我想 Hook RegQueryValue,做法如下—— InprocAPIHook 实现: - class InprocAPIHook : public xl::NonCopyable
- {
- public:
- InprocAPIHook() : m_hProcess(nullptr), m_lpProc(nullptr), m_bHooked(false)
- {
- }
- ~InprocAPIHook()
- {
- StopHook();
- }
- public:
- bool SetHook(FARPROC lpProc, FARPROC lpNewAddr)
- {
- StopHook();
-
- if (lpProc == nullptr)
- {
- return false;
- }
- m_lpProc = lpProc;
-
- TCHAR szAddr[MAX_PATH] = {};
- _stprintf_s(szAddr, _T("RegQueryValueW Addr: %08x"), lpProc);
- OutputDebugString(szAddr);
- CopyMemory(&m_thunkOrig, m_lpProc, sizeof(APIThunk));
- m_thunkNew.m_addr = (DWORD)lpNewAddr - (DWORD)m_lpProc - sizeof(APIThunk);
- m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
- if (m_hProcess == nullptr)
- {
- return false;
- }
- return true;
- }
- bool StartHook()
- {
- if (m_bHooked)
- {
- return true;
- }
- DWORD dwOldProtect = 0;
-
- if (!VirtualProtectEx(m_hProcess, m_lpProc, sizeof(APIThunk), PAGE_READWRITE, &dwOldProtect))
- {
- return false;
- }
-
- SIZE_T cbWritten = 0;
- if (!WriteProcessMemory(m_hProcess, m_lpProc, &m_thunkNew, sizeof(APIThunk), &cbWritten) || cbWritten != sizeof(APIThunk))
- {
- return false;
- }
- if (!VirtualProtectEx(m_hProcess, m_lpProc, sizeof(APIThunk), dwOldProtect, &dwOldProtect))
- {
- return false;
- }
- m_bHooked = true;
- return true;
- }
- bool StopHook()
- {
- if (!m_bHooked)
- {
- return true;
- }
- DWORD dwOldProtect = 0;
- if (!VirtualProtectEx(m_hProcess, m_lpProc, sizeof(APIThunk), PAGE_READWRITE, &dwOldProtect))
- {
- return false;
- }
- if (!WriteProcessMemory(m_hProcess, m_lpProc, &m_thunkOrig, sizeof(APIThunk), nullptr))
- {
- return false;
- }
- if (!VirtualProtectEx(m_hProcess, m_lpProc, sizeof(APIThunk), dwOldProtect, &dwOldProtect))
- {
- return false;
- }
- m_bHooked = false;
- return true;
- }
- private:
- #ifdef _WIN64
- #pragma pack(push, 1)
- typedef struct _APIThunk
- {
- USHORT m_mov_rax; // mov rax, addr
- ULONG64 m_addr;
- USHORT m_jmp; // jmp addr
- _APIThunk() : m_mov_rax(0xb848), m_addr(0), m_jmp(0xe0ff)
- {
- }
- } APIThunk;
- #pragma pack(pop)
- #else
- #pragma pack(push, 1)
- typedef struct _APIThunk
- {
- BYTE m_jmp; // jmp addr
- DWORD m_addr;
- _APIThunk() : m_jmp(0xe9), m_addr(0)
- {
- }
- } APIThunk;
- #pragma pack(pop)
- #endif
- private:
- APIThunk m_thunkOrig;
- APIThunk m_thunkNew;
- HANDLE m_hProcess;
- FARPROC m_lpProc;
- bool m_bHooked;
- };
使用处:- InprocAPIHook apiHook;
- InprocAPIHook *g_pApiHook = &apiHook;
- LONG WINAPI MyRegQueryValue(
- __in HKEY hKey,
- __in_opt LPCTSTR lpSubKey,
- __out_opt LPTSTR lpValue,
- __inout_opt PLONG lpcbValue
- )
- {
- OutputDebugString(lpSubKey);
- return ERROR_SUCCESS;
- if (lpSubKey != nullptr &&_tcsicmp(lpSubKey, _T("Cookies")) != 0)
- {
- g_pApiHook->StopHook();
- LONG lRes = RegQueryValue(hKey, lpSubKey, lpValue, lpcbValue);
- g_pApiHook->StartHook();
- return lRes;
- }
-
- g_pApiHook->StopHook();
- LONG lRes = RegQueryValue(hKey, lpSubKey, nullptr, nullptr);
- g_pApiHook->StartHook();
- if (lRes != ERROR_SUCCESS && lRes != ERROR_MORE_DATA)
- {
- return lRes;
- }
- if (lpcbValue == nullptr && lpValue != nullptr)
- {
- return ERROR_INVALID_PARAMETER;
- }
- xl::String strPath = _T("%APPDATA%");
- strPath += _T("\\");
- strPath += FOLDER_COMPANY;
- strPath += _T("\\");
- strPath += FOLDER_APPLICATION;
- strPath += _T("\\");
- strPath += FOLDER_COOKIES;
- if (lpcbValue != nullptr)
- {
- LONG dwGivenSize = *lpcbValue;
- *lpcbValue = (strPath.Length() + 1) * sizeof(xl::Char);
- if (dwGivenSize < *lpcbValue)
- {
- return ERROR_MORE_DATA;
- }
- }
- if (lpValue != nullptr)
- {
- CopyMemory(lpValue, strPath.GetAddress(), *lpcbValue);
- }
- return ERROR_SUCCESS;
- }
上面这个函数时我准备用来替换的函数上面这个函数时我准备用来替换的函数 - apiHook.SetHook((FARPROC)RegQueryValue, (FARPROC)MyRegQueryValue);
- apiHook.StartHook(); // 这里开始使用 Hook
- RegQueryValue(0,0,0,0); // 这一行测试正常进入 MyRegQueryValue
- HRESULT hr = StgCreateDocfile(nullptr,
- STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE,
- 0,
- &m_pStorage);
- if (FAILED(hr))
- {
- return false;
- }
- hr = OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, 0, this, m_pStorage, (LPVOID *)&m_pOleObj);
- if (FAILED(hr))
- {
- return false;
- }
- hr = m_pOleObj->QueryInterface(IID_IOleInPlaceObject, (LPVOID *)&m_pInPlaceObj);
- if (FAILED(hr))
- {
- return false;
- }
- RECT rect = {};
- GetClientRect(&rect);
- hr = m_pOleObj->DoVerb(OLEIVERB_INPLACEACTIVATE, nullptr, this, 0, m_hWnd, &rect);
- if (FAILED(hr))
- {
- return false;
- }
- // 。。。
但是,现在的情况是,只有我自己写的那行测试代码 RegQueryValue 能进入 MyRegQueryValue,WebBrowser 加载过程中没有一次进入 MyRegQueryValue。不知道为什么,各位高手帮忙分析下? 顺求其他将 WebBrowser 的Cookies 和 IE 隔离开来的方案。 先谢过了
|