• Welcome to Valhalla Legends Archive.
 

UnhookWindowsHookEx() fails, but GetLastError() returns 0?

Started by Dyndrilliac, January 12, 2008, 05:35 PM

Previous topic - Next topic

Dyndrilliac

I'm working on an injectable DLL hack with a global keyboard hook, and although SetWindowsHookEx() returns as expected, when it comes time to unhook something fails, and GetLastError returns 0. I've attached only the relevant code, but I don't get any errors or warnings. I'm using VC++ 2008 Express Edition. Just say so if you need me to post the rest.

Core.cpp:#include <windows.h>
#include <stdio.h>

// ...

BYTE StatsHackToggle = 0;
BYTE GoldHackToggle  = 0;

HHOOK MyKeyboardHook = 0;
DWORD bRet = 0, ErrCode = 0;

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam);

// ...

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
// Register our keyboard hook.
MyKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)&KeyboardProc, hInstance, NULL);
if (MyKeyboardHook == NULL) { // Checking for errors...
DbgPrint("The call to SetWindowsHookEx() failed, [MyKeyboardHook] is null.", GetLastError());
}
break;
case DLL_PROCESS_DETACH:
// Unregister our keyboard hook.
bRet = UnhookWindowsHookEx(MyKeyboardHook);
if (bRet == NULL) { // Checking for errors...
DbgPrint("The call to UnhookWindowsHookEx() failed, [bRet] is null.", GetLastError());
}
break;
default:
break;
    }

return (TRUE);
}

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
if (code != HC_ACTION) {
return (CallNextHookEx(MyKeyboardHook, code, wParam, lParam));
}

// This is where the conditions for certain keys
// being pressed go. Use the virtual key-codes
// for the keys you wish to hook. For more information,
// do a search on "Virtual key-codes on MSDN.
switch (wParam) {
case VK_PRIOR: // StatsHack
if (StatsHackToggle == 0) { // on toggle
DbgPrint("StatsHack Toggle [ON]!", NULL);
bRet = PlaceDetour(ptrStatsHack,(DWORD)&StatsHack,NULL);
if (bRet == NULL) {
DbgPrint("The call to PlaceDetour() failed during toggling of StatsHack.", NULL);
StatsHackToggle = 0;
}

StatsHackToggle = 1;
} else { // off toggle
DbgPrint("StatsHack Toggle [OFF]!", NULL);
bRet = WriteMemory(ptrStatsHack,StatsHackOldData,6);
if (bRet == NULL) {
DbgPrint("The call to WriteMemory() failed during toggling of StatsHack.", NULL);
StatsHackToggle = 1;
}

StatsHackToggle = 0;
}
break;
case VK_NEXT: // GoldHack
if (GoldHackToggle == 0) { // on toggle
DbgPrint("GoldHack Toggle [ON]!", NULL);
bRet = PlaceDetour(ptrGoldHack,(DWORD)&GoldHack,6);
if (bRet == NULL) {
DbgPrint("The call to PlaceDetour() failed during the [ON] toggle of GoldHack.", NULL);
GoldHackToggle = 0;
}

GoldHackToggle = 1;
} else { // off toggle
DbgPrint("GoldHack Toggle [OFF]!", NULL);
bRet = WriteMemory(ptrGoldHack,GoldHackOldData,6);
if (bRet == NULL) {
DbgPrint("The call to WriteMemory() failed during the [OFF] toggle of GoldHack.", NULL);
GoldHackToggle = 1;
}

GoldHackToggle = 0;
}
break;
default:
break;
}

// Call the next hook in the system's hook chain.
return (CallNextHookEx(MyKeyboardHook, code, wParam, lParam));
}
I would appreciate it if someone could tell me what I've done wrong...
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

brew

It appears that you are doing nothing wrong at all--
However, for some reason when I set a global variable to a value within WinMain or DllMain, it always seems to be cleared, and i have to reset it in my windowproc. Check the value of MyKeyboardHook when calling UnhookWindowsHookEx.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Dyndrilliac

I added if (MyKeyboardHook == 0) {
DbgPrint("wtf", NULL);
}
Right before the call to UnhookWindowsHookEx, but still nothing. Someone else suggested creating the Hook in a new thread and allowing it to idle, and it will automatically be unset when the thread terminates - but that still wouldn't explain why my hotkeys don't currently work, even though the only thing that appears to be wrong is the call to unhook...
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

brew

Quote from: Dyndrilliac on January 12, 2008, 10:09 PM
I added if (MyKeyboardHook == 0) {
DbgPrint("wtf", NULL);
}
Right before the call to UnhookWindowsHookEx, but still nothing. Someone else suggested creating the Hook in a new thread and allowing it to idle, and it will automatically be unset when the thread terminates - but that still wouldn't explain why my hotkeys don't currently work, even though the only thing that appears to be wrong is the call to unhook...
So your hotkeys never worked in the first place? Before trying the make-a-new-thread idea?
UnhookWindowsHookEx fails when you try to call from a different thread then SetWindowsHook was called from. If you never do solve this, try using SetWinEventHook instead. Maybe that'll work...
I haven't taken a good look at this, but maybe it'll help you: http://www.codeproject.com/KB/DLL/hooks.aspx
Other then that, I am clueless.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P