Click to See Complete Forum and Search --> : hooking into external program
flynny1st
April 25th, 2007, 04:25 AM
Hi,
I've got a question about the best way to hook into a program. I want to create a generic program that will hook into a number of different programs in the same way.
The program will then sit there until a certain action is performed and then trigger an action, like create a new button on that particaular window.
At the moment my program will replace each programs executable. This program will take a path to the second program on the command line.
My program will then run and launch the second program before hooking into it (to ensure an instance of the program is present).
The problem i have is that a couple of these programs have seperate log in screens, so that when the program is launched using the createProcess method it is the login screen that is run first and hooked into, only once the user has logged in does the main program run.
My question is what is the best method for hooking into the second screen? I could just cause the program to sleep() for a set number of time and assume that the user will then have logged in, i can then try and hook into the window using findWindow().
However this doesn't seem a nice way of doing things. does anyone else have any other ideas?
Many Thanks,
Matt.
Krishnaa
April 25th, 2007, 05:52 AM
Look into these articles,
API Hooking revealed (http://www.codeguru.com/Cpp/W-P/system/misc/article.php/c5667)
API Spying Techniques for Windows 9x, NT and 2000 (http://www.internals.com/articles/apispy/apispy.htm)
madShi's Commercial Library for hooking (http://help.madshi.net/ApiHookingMethods.htm)
flynny1st
April 25th, 2007, 06:31 AM
Hi,
Thanks for the reply. Ok, i'm going to add a system wide hook and then listen out for the program being created and then hook into.
However how do i add a system wide hook from this documentation it does seem possible but everytime i try i get 0 returning from setwindowshookex(). Is there another method to do this?
Matt.
Krishnaa
April 25th, 2007, 06:41 AM
What method are you trying, can you post that code here?
There aren't multiple methods to set Windows Hooks, properly using Win32 API SetWindowsHook is the only one.
flynny1st
April 25th, 2007, 06:50 AM
Ok the code im using is
in my main console application
AppHInstance = 0;
AppProcessID = 0;
EventsHook = InstallEventsLauncher(AppHInstance, AppProcessID, NULL, NULL);
char buf[128];
sprintf(buf, "Hooking into all events %d", EventsHook);
MessageBox(NULL, buf, NULL, 0);
the InstallEventsLauncher refers to the methos in my dll.
DllExport HHOOK__* WINAPI InstallEventsLauncher(HINSTANCE__* wHnd, DWORD processID, HWND__* eventWND, HWND__* appWND)
{
EventWindowHandle = eventWND;
AppWindowHandle = appWND;
Hook = (HHOOK)SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)LauncherEventsHook, wHnd, processID);
return Hook;
}
by setting the wHnd and processID to zero here will it not hook system wide?
Thanks again for the reply,
Matt.
Krishnaa
April 25th, 2007, 06:58 AM
The last parameter of SetWindowsHookEx is a threadID, which is described as,
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.
You need to pass zero (0) in order to hook all processes/threads. If you still get 0 in return then try using GetLastError () to determine the cause.
Also is see if you are passing correct DLL handle (hMod).
Refer to following on MSDN for sample code and description on hooking,
Using Hooks (http://msdn2.microsoft.com/en-us/library/ms644960.aspx)
flynny1st
April 25th, 2007, 08:33 AM
Hi, again thanks for the reply and the links they were useful.
ok i've followed the example in your last link but it still doesnt seem to give me a hook and GetLastError() is returning a blank too.
hkprcSysMsg returns 0 (i've tested this) "LauncherEventsHook" is the callback method name i wish to be fired when an event is recieved, this is held in my dll.
am i doing something wrong?
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary((LPCTSTR) ".\\LaunchDLL.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "LauncherEventsHook");
hhookSysMsg = SetWindowsHookEx(WH_CALLWNDPROC,hkprcSysMsg,hinstDLL,0);
char buf[128];
sprintf(buf, "hhookSysMsg %d", hkprcSysMsg);
MessageBox(NULL, buf, NULL, 0);
DWORD result = GetLastError();
sprintf(buf, "last error %c", result);
MessageBox(NULL, buf, NULL, 0);
Thanks Matt.
Krishnaa
April 25th, 2007, 08:41 AM
By hkprcSysMsg you mean the return value of GetProcAddress is NULL ?? Do LoadLibrary succeed ? Is "LauncherEventsHook" the exact export name ??
Have you not exported this function as extern "C" ??? GetProcAddress needs the export name (it can be different than function if C++ compiler mangles (http://en.wikipedia.org/wiki/Name_mangling) it) to be exactly same as in export table.
flynny1st
April 25th, 2007, 08:53 AM
yes getProcAddress is not returning anything.
the loadlibrary is working ok as i am getting a handle returned.
the LauncherEventsHook is declared in my DLL and i include the library file to the LaunchDLL.lib in my VC++ project link settins and include the header file too
#include "..\LaunchDLL\LaunchDLL.h"
I'm sorry what do you mean when you say extern "C"?
Many Thanks Matt.
Krishnaa
April 25th, 2007, 09:01 AM
Have you visited the link on C++ Name mangling (also known as name decoration (http://msdn2.microsoft.com/en-us/library/56h2zst2(VS.80).aspx)) ? it explains how C++ compiler creates export names, in your case if you are exporting a function in C++ style (which mangles the name) then the actuall export name looks like LauncherEventsHook@?$ctype@_W@.
extern "C" (http://msdn2.microsoft.com/en-us/library/0603949d(VS.80).aspx) directs linker to use C specs for creating name, which uses same export name as given in code.
And as GetProcAddress needs actual export name, it will fail for name LauncherEventsHook, got it ??
You can use Dependancy Walker (http://www.dependencywalker.com/) to confirm if exported name is mangled or not.
flynny1st
April 25th, 2007, 10:45 AM
Hi,
Thanks for the help once used the "mangled" name it detected the callback method with no probs.
If i could ask you one final question.
Now i have hooked into the system wide hooks, i will want to detect the WM_CREATE (to test a program is being created) and then test to see if the window i want has been created using FindWindow(NULL, "window name");
this is the code i'm using it however causes the program to crash every time.
LRESULT CALLBACK LauncherEventsHook (int nCode, int wParam, long lParam)
{
LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam);
if(nCode == HC_ACTION)
{
tagCWPSTRUCT* eStruct = (tagCWPSTRUCT*) lParam;
//check if window is being activated and check if can hook into relevent window
if(eStruct->message == WM_CREATE)
{
foundHWnd = FindWindow(NULL, "Calculator");
if(foundHWnd > 0)
{
char buf[128];
sprintf(buf, "IN HERE SO CREATE NEW HOOK");
MessageBox(NULL, buf, NULL, 0);
//remove system wide hook and add application hook
}
}
}
return Result;
}
codeguru.com
Copyright 2007 Jupitermedia Corporation All Rights Reserved.