I have been trying to make a Global Keyboard hook program in visual C++ that write keystrokes in file "log.txt"..I am new to windows programming and i have gone through the msdn library to get an understanding of hooks....I think i have understood the concept theoretically but when i implement the code it doesn't work..The compiler doesn't show any error in both the DLL file and EXE file....Moreover the "Log.txt" file never gets created...
Here are the code files
First Dll file:
#include<windows.h>
#include<stdio.h>
HHOOK g_hhk;
__declspec(dllexport) LRESULT CALLBACK KeyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode>=0)
{
char ch;
FILE *fp;
fp=fopen("log.txt","a");
if((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100))
{
if(wParam==VK_RETURN)
ch='\n';
fwrite(&ch,1,1,fp);
}
else
{
BYTE ks[256];
GetKeyboardState(ks);
WORD w;
UINT scan;
scan=0;
ToAscii(wParam,scan,ks,&w,0);
ch =char(w);
fwrite(&ch,1,1,fp); // copy character to log file
}
fclose(fp);
}
return CallNextHookEx(g_hhk, nCode, wParam, lParam);
}
Now the EXE file:
#include<windows.h>
HOOKPROC hkprckb;
static HINSTANCE hinstDLL;
static HHOOK hhookkb;
int WINAPI WinMain(HINSTANCE hInstance1,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
hinstDLL=LoadLibrary(TEXT("C:\\Documents and Settings\\Attar Singh\\My Documents\\Visual Studio 2008\\Projects\\key\\Debug\\key.dll"));
hkprckb=(HOOKPROC)GetProcAddress(hinstDLL,"KeyProc");
hhookkb=SetWindowsHookEx(
WH_KEYBOARD_LL,
hkprckb,
hinstDLL,
0);
MessageBox(NULL,NULL,NULL,MB_OK);
return 1;
}
This program is giving me nightmares...Any sort of help will be greatly appreciated...Thanks in Advance...
wParam is supposed to have one of the following values:
WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP.
To get the virtual key code of the key pressed you have to use: ((KBDLLHOOKSTRUCT*)lParam)->vkCode
Related
dll code:
LRESULT CALLBACK CBTNewProc(int nCode, WPARAM wParam, LPARAM lParam)
{
std::ofstream file;
file.open("E:\\enter.txt", std::ios::out);
file << nCode;
file.close();
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) void installHook()
{
if (g_hHook != NULL){
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
HINSTANCE hInstance = GetModuleHandle(NULL);
g_hHook = SetWindowsHookEx(WH_CBT, CBTNewProc, NULL, GetCurrentThreadId());
if (g_hHook == NULL)
{
MessageBox(NULL, L"fail!", L"caption", MB_OK);
}
else
{
MessageBox(NULL, L"install success!", L"caption", MB_OK);
}
}
I wrote another program to load this dll and called installHook. The message box "install success" is showed but the callback function was never called, enter.txt is not found under drive E.
I'm using Win7 + VS2013.
For a hook to be set in other processes, you must pass the hInstance of the DLL which contains the hook proc to SetWindowsHookEx.
You should also pass zero as the thread ID.
I'm trying to make an application that gets informed on creation and destruction of top-level windows, system-wide. I've made a code to exploit a CBT hook. The solution contains two projects, DLL and EXE. EXE project has a reference to the DLL project. The hook is being set from a DLL. There is a message loop in EXE project. The problem is that CBT hook is not working. With the help of VS debugger, I've found out that hook callback is never called, while return code from SetWindowsHookEx is non-zero, implying the hook was set. What's a mistake? How do I fix it?
Here's a minimal example. DLL, main.cpp:
#include <windows.h>
typedef void(*DECODERPROC)(int code, WPARAM wParam, LPARAM lParam);
HINSTANCE hInst = nullptr;
HHOOK hHook = nullptr;
DECODERPROC fpDecoder = nullptr;
LRESULT CALLBACK cbtProc(int code, WPARAM wParam, LPARAM lParam) {
// FIXME: never called
if (code > 0 && fpDecoder) {
fpDecoder(code, wParam, lParam);
}
return CallNextHookEx(hHook, code, wParam, lParam);
}
__declspec(dllexport) bool InstallHook(DECODERPROC decoder) {
if (hHook) return false;
fpDecoder = decoder;
return (hHook = SetWindowsHookEx(WH_CBT, cbtProc, hInst, 0)) != NULL;
}
__declspec(dllexport) bool UninstallHook() {
if (!hHook) return false;
bool res = UnhookWindowsHookEx(hHook) != NULL;
if (res) hHook = NULL;
return res;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
hInst = reinterpret_cast<HINSTANCE>(hModule);
return TRUE;
}
EXE, main.cpp
#include <iostream>
#include <locale>
#include <windows.h>
#include <fcntl.h>
#include <io.h>
using namespace std;
typedef void(*DECODERPROC)(int code, WPARAM wParam, LPARAM lParam);
__declspec(dllimport) bool InstallHook(DECODERPROC);
__declspec(dllimport) bool UninstallHook();
int main() {
_setmode(_fileno(stdout), _O_U8TEXT);
WNDCLASS windowClass = {};
windowClass.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT {
if (message == WM_DESTROY)
UninstallHook();
return DefWindowProc(hWnd, message, wParam, lParam);
};
LPCWSTR windowClassName = L"Foobar";
windowClass.lpszClassName = windowClassName;
if (!RegisterClass(&windowClass)) {
wcerr << L"Failed to register window class" << endl;
return 1;
}
HWND messageWindow = CreateWindow(windowClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
if (!messageWindow) {
wcerr << L"Failed to create message-only window" << endl;
return 1;
}
InstallHook([](int code, WPARAM wParam, LPARAM lParam) {
wcout << L"Never called" << endl;
});
MSG msg;
while (GetMessage(&msg, 0, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
If you are running on Windows 64-bit, you need both 32-bit and 64-bit versions of the DLL in order to hook every running process. A 32-bit DLL cannot hook a 64-bit process, and vice versa. So you need to call SetWindowsHookEx() from a 32-bit process to hook 32-bit processes, and from a 64-bit process to hook 64-bit processes.
More importantly than that, a separate instance of your DLL gets injected into every running process, so your fpDecoder callback pointer is NULL in every instance of the DLL except for the one that your EXE is calling InstallHook() on. So you need to redesign your hook to use inter-process communication (window message, named pipe, mailslot, socket, etc) to communicate with your main EXE, you can't use a function pointer.
Depending on which process you are actually debugging, you might not see cbtProc() getting called. If you are debugging your main EXE process, your code is not doing anything to trigger any CBT activity within your EXE's process once the hook has been installed, and the debugger would not show you any CBT activity occurring in other processes that it is not debugging.
Depending on what you are actually looking for in your hook, you might consider using SetWinEventHook() instead, as it can be used with or without a DLL, and it has more flexible filtering capabilities than SetWindowsHookEx().
I am trying to get global mouse position. I have a hook working that can get the mouse position, however it only has access to it inside the hook code. Trying to access the data inside main doesn't work.
The best way to explain this is with code:
LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
position.x = p->pt.x;
position.y = p->pt.y;
std::cout<<position.x<<std::endl;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);
MessageBox(NULL, "Press OK to close.", "", MB_OK);
return 0;
}
With the above code, moving the mouse will show the new position in the console window. However, if I put the std::cout<<position.x<<std::endl; inside of main, it will just say 0. position is a global variable.
Code when the output is inside of main:
LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
position.x = p->pt.x;
position.y = p->pt.y;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);
for(;;)
{
std::cout<<position.x<<std::endl;
}
MessageBox(NULL, "Press OK to close.", "", MB_OK);
return 0;
}
The first chunk of code works fine, it detects the mouse position, I just don't know how to get the x,y data into my main.
re this posted code:
LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
position.x = p->pt.x;
position.y = p->pt.y;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);
std::cout<<position.x<<std::endl;
MessageBox(NULL, "Press OK to close.", "", MB_OK);
return 0;
}
Here's what the main function specifies should happen:
First, a call to SetWindowsHookEx (this happens once).
Then, outputting position (this happens once).
Then, displaying a MessageBox (this happens once).
That's all.
During the call to MessageBox the hook procedure is called (whenever you move your mouse), but it doesn't do anything visible, just an internal update.
Why did you expect more?
How to fix:
Instead of relying on the internal message loop in MessageBox, which doesn't do any output, code up your own.
Not to do with functionality, but just because the current code is like very dirty clothing that does serve its purpose but feels ungood to wear: replace Microsoft's WinMain monstrosity with a standard C and C++ main.
For global hook the hook procedure mouseHookProc should be in a DLL so that it can be injected into processes.
Check this:
http://www.codeproject.com/Articles/1037/Hooks-and-DLLs
I've created a dialog box inside a Win32 DLL (using resource editor) and now want to show it as application program (using this DLL) calls DisplayDialog, but it is not working.
// AppProgram.cpp
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_COMMAND:
switch (LOWORD (wParam)) {
case IDM_FILE_NEW_DIALOG:
DisplayDialog (hInst, hWnd);
break;
...
}
break;
....
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
My DLL appears like
#include "stdafx.h"
#include "myDLL.h"
EXPORT BOOL CALLBACK DisplayDialog (HINSTANCE hInst, HWND hWnd) {
DialogBox (hInst, MAKEINTRESOURCE (IDD_DIALOG1), hWnd, reinterpret_cast<DLGPROC> (DiagProc));
// MessageBox works here
}
...
I've tested that this DLL displays dialog if the dialog belongs to AppProgram.
Here, I want to display dialog when it is a part of DLL.
Please suggest whether we should create dialog inside DLL or should pass it from program. + how to show dialog in given scenario. Thanks in advance.
The hInst parameter is the handle to the module that contains the dialog resource. If you want to get the dialog from the DL's resourcesL, then pass the handle to the DLL rather than the handle to the main application.
Something like this:
HMODULE module = LoadLibrary("MyDll.dll");
HRSRC res = FindResource(module, "#1234", RT_DIALOG);
DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)LoadResource(module, res);
DialogBoxIndirect(0, pTemplate, hwnd, dlgproc);
I'm writing up a quick tool in C# thats meant to sort of be a virtual keyboard. At the moment I am using SendKeys. I want to know if keyloggers would capture the keys so I found this code but i don't have mfc installed so i cant compile nor run it
How might i key if SendKeys is being logged by keyloggers or how do I get the code (snippet below) running in a single exe to test my code with?
#include <Windows.h>
static UINT uMsg = 0;
static HWND hWndMain = 0;
static HHOOK hKeyHook = NULL ;
#pragma data_seg()
HINSTANCE hInstance = 0;
HOOKPROC lpfnHookProc = 0;
LRESULT __stdcall KeyboardFunc (int nCode, WPARAM wParam, LPARAM lParam)
{
BOOL bPassToChain;
char szDebug [100];
// Check for exception cases...
if (nCode < 0)
return (CallNextHookEx (hKeyHook, nCode, wParam, lParam));
if (nCode == HC_NOREMOVE)
return (CallNextHookEx (hKeyHook, nCode, wParam, lParam));
switch (wParam)
{
case VK_F2:
wsprintf (szDebug, "F2 key message, lparam = 0x%X\n", lParam);
OutputDebugString (szDebug);
// only send on keydown, not keyup (autorepeat)
if (HIWORD (lParam) & 0xC000)
{
OutputDebugString ("F2 Keyup\n");
}
else
{
wsprintf (szDebug, "Sending F2 keydown message %d to hwnd 0x%X\n",
uMsg, hWndMain);
OutputDebugString (szDebug);
PostMessage (hWndMain, uMsg, 0, 0);
}
bPassToChain = FALSE;
break;
default :
bPassToChain = TRUE ;
break ;
}
if (bPassToChain)
return (CallNextHookEx (hKeyHook, nCode, wParam, lParam));
else
return TRUE ; // We have processed this key
}
BOOL __stdcall InstallExampleKeyboardHook (HWND hWnd, UINT uMyMsg)
{
hWndMain = hWnd ;
uMsg = uMyMsg;
lpfnHookProc = (HOOKPROC) KeyboardFunc ;
hKeyHook = SetWindowsHookEx (WH_KEYBOARD, lpfnHookProc, hInstance, NULL);
if (hKeyHook)
return TRUE ;
else
return FALSE ;
}
It's nothing about MFC. Straight native c++ code. If you have Visual Studio, you should be able to make a quick console c++ app, copy and paste that code in, and compile and test. If not, go and get the free but big Windows SDK. Less friendly then VS, but there's a compiler, so should get you in the right direction.
Low level hooks are not quite debugger friendly, so you might need to trace or log out some helpful statements.
Edited: to get the module handle, you will need something like this:
HookModule = LoadLibrary(ModulePath);
HookProc HookFunction = GetProcAddress(HookModule, "GetMessageCallBack");
GetMessageHookHandle = SetWindowsHookEx(HookType.WH_GETMESSAGE, HookFunction, HookModule, 0);