There is good news, however, if you want to hook explorer.exe and/or iexplore.exe, it's easy to do with a BHO.
First you need to make a GUID -- it's not hard. Next, you need to make some registry entries:
First, the BHO entry
Code: Select all
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{00000000-0000-0000-0000-000000000000}
Code: Select all
[HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-000000000000}]
[HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-000000000000}\InprocServer32]
@="C:\\Program Files\\MyHooksDir\\LoadMyHook.dll"
"ThreadingModel"="Apartment"
Next we need to code the "LoadMyHook.dll"
Code: Select all
#include <windows.h>
static HMODULE ModuleFromAddress(PVOID pv)
{
MEMORY_BASIC_INFORMATION mbi;
return ((::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
? (HMODULE) mbi.AllocationBase : NULL);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
//returning false causes us to be unloaded
BOOL bRet = FALSE;
BOOL bHookOnlyIE = TRUE; // set to false if you want to hook Explorer too
if(dwReason == DLL_PROCESS_ATTACH)
{
if(bHookOnlyIE)
{
TCHAR exeFileName[MAX_PATH];
if(GetModuleFileName(NULL, exeFileName, MAX_PATH) == 0)
return bRet;
//backup until we find the name of the exe
TCHAR* pChar = NULL;
for(int i=wcslen(exeFileName); (i>=0) &&
(exeFileName[i]!='\\'); i--)
{
//convert the exe filename to uppercase while we're at it.
if((exeFileName[i] >= 'a') && (exeFileName[i] <= 'z'))
{
exeFileName[i] -= 'a' - 'A';
}
//get the address of this char
pChar = &exeFileName[i];
}
if(wcscmp(pChar, L"IEXPLORE.EXE") != 0)
{
//this isn't IE (could be explorer.exe or anything else)
return bRet;
}
}
//This is the IE process
//see if MyHook is loaded already
if(GetModuleHandle(L"MyHook.DLL") != NULL)
{
//it's already loaded and doing it's job
return bRet;
}
//we need to launch MyHook.dll with LoadLibrary() before IE shuts us down for not being a
// true BHO
//Before we can launch MyHook.dll, it would be nice to know the full path to it :D
//get the filename of this DLL
TCHAR fileName[MAX_PATH];
if(GetModuleFileName(ModuleFromAddress(DllMain), fileName, MAX_PATH) == 0)
return bRet;
//strip off the dll filename leaving us with a path
for(i=wcslen(fileName); (i>=0) &&
(fileName[i]!='\\'); i--)
{
fileName[i] = 0;
}
//we make the assumption that MyHook.dll and this DLL are in the same dir
wcscat(fileName, L"MyHook.dll");
//Locked a Loaded. Let 'er Rip. :D
if(LoadLibrary(fileName) == NULL)
{
MessageBox(NULL, L"Unable to Load Hook!", L"MyHook - LoadMyHook.dll", MB_OK);
}
}
return bRet;
}
The real action takes place in MyHook.dll. The fear I had when I first coded this is that IE would eject the DLL when it turned out not to be a BHO. This is why the loader dll only launches the dll that does the hooking. Because IE and explorer both keep the fake BHO dll loaded, it's "possible" to do all all your hooking with one dll. I personally think it's safer using two dlls. There isn't any chance of being ejected by the host process.
Also, you'll see that I'm checking to see if I'm running in IE. For my project, I didn't want to hook explorer and doing so caused me problems when I wanted to update or uninstall my dlls. If you only want to hook explorer, you can do the same thing and look for "EXPLORER.EXE".
Also note that I'm using wide (unicode) versions of the APIs. Converting the code back to ansi will take a little effort, but it shouldn't be hard. I personally feel a little more comfortable knowing if someone sticks my app in a folder that has Chinese or Japanese characters in it, it'll still work.
Anyway, I though I'd share my method for hooking IE (and explorer if you want). It suites my needs well.
EDIT = spelling.