0

I tried to hook keyboard of one process, but code of hook don't get executed and process freezes when I press any key. I based my code on following post: How to hook external process with SetWindowsHookEx and WH_KEYBOARD

Here is my code of dll:

#include <windows.h>
#include <iostream>
#include <stdio.h>

HINSTANCE hinst = NULL;
#pragma data_seg(".shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")

LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
    return CallNextHookEx(hhk, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install(unsigned long threadID) {
    hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
}

BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
    hinst = hinstDLL;
    return TRUE;
}

EDIT: After loading of dll I execute function install(), which secefully create hook, but for some reason function wireKeyboardProc don't get executed when key is pressed and process freezes. Any idea why this happen?

EDIT 2: Here is also code of my exe:

unsigned long threadID = GetWindowThreadProcessId(hWnd, &ProcessId);

    HINSTANCE hinst;
    hinst = LoadLibrary(_T("hookKbd32.dll"));

    if (hinst) {
        typedef void(*Install)(unsigned long);
        Install install = (Install)GetProcAddress(hinst, "install");
        install(threadID);
    }
Community
  • 1
  • 1
  • 1
    If it "freezes" then you have pretty good evidence that the hook in fact works. That this code cannot repro the problem for anybody tends to be explained by it not being the real code, since it doesn't do anything, or that your anti-malware product doesn't think highly of key loggers. – Hans Passant Jun 03 '16 at 15:44
  • @HansPassant I don't think that problem is there, because I don't use any anti-malware product and also I tried to put there cout and it didn't make any output. I think that function wireKeyboardProc isn't for any reason executed. – Growtopia Noobs Jun 03 '16 at 17:09
  • You don't show any code that's using these functions. Given the code you posted, _none_ of your functions get called. See Also: [mcve] – theB Jun 03 '16 at 18:13
  • @theB I tried to edit my post to make it more clear. Thanks for help. :) – Growtopia Noobs Jun 03 '16 at 21:15
  • The phrase "after injection of DLL" worries me. If I understand rightly, SetWindowsHookEx loads the DLL into the target process for you - you aren't supposed to be injecting it. But are you *sure* that it crashes when using the code as posted? If your real code has, say, a call to `cout`, that might explain the crash. At any rate, there doesn't seem to be anything wrong with the code as posted, so perhaps the problem is with the code that calls install(), please post the *entire* program. – Harry Johnston Jun 04 '16 at 01:33
  • @HarryJohnston Sorry I mean loading dll. And cout don't cause crash, because I tried code without it too. – Growtopia Noobs Jun 04 '16 at 09:33
  • Best guess: you're running into one of the cases where the hook procedure is called in the context of the hooking application, and your hooking application doesn't have a message pump. We'd need to see the rest of the hooking application to be sure whether this was the problem or not. – Harry Johnston Jun 04 '16 at 22:27
  • @HarryJohnston I didn't know that I need to put message pump there, because this is first time when I am trying hooking. Now my app work fine. Thank you for help! – Growtopia Noobs Jun 05 '16 at 07:33

1 Answers1

0

I have had the same problem trying to add a hook to nox player (android emulator). I have tried the same code with another emulator and it works perfectly.

After this, i'm sure that nox includes a anti hook system ... probably same for your program. Nox looks freeze or exits after SetWindowsHookExA and not events captured at all.

EDITED. I know why after some hours checking.... 64 bits app needs 64 bits dlls, and 32 bits apps need 32 bits dlls.

from: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa

SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.

Because hooks run in the context of an application, they must match the "bitness" of the application. If a 32-bit application installs a global hook on 64-bit Windows, the 32-bit hook is injected into each 32-bit process (the usual security boundaries apply). In a 64-bit process, the threads are still marked as "hooked." However, because a 32-bit application must run the hook code, the system executes the hook in the hooking app's context; specifically, on the thread that called SetWindowsHookEx. This means that the hooking application must continue to pump messages or it might block the normal functioning of the 64-bit processes. If a 64-bit application installs a global hook on 64-bit Windows, the 64-bit hook is injected into each 64-bit process, while all 32-bit processes use a callback to the hooking application.

To hook all applications on the desktop of a 64-bit Windows installation, install a 32-bit global hook and a 64-bit global hook, each from appropriate processes, and be sure to keep pumping messages in the hooking application to avoid blocking normal functioning. If you already have a 32-bit global hooking application and it doesn't need to run in each application's context, you may not need to create a 64-bit version.

https://learn.microsoft.com/en-us/windows/win32/winprog64/process-interoperability

You can run Win32-based applications on 64-bit Windows using an emulation layer. Windows 10 on ARM includes an x86-on-ARM64 emulation layer. For more information, see Running 32-bit Applications.

On 64-bit Windows, a 64-bit process cannot load a 32-bit dynamic-link library (DLL). Additionally, a 32-bit process cannot load a 64-bit DLL. However, 64-bit Windows supports remote procedure calls (RPC) between 64-bit and 32-bit processes (both on the same computer and across computers). On 64-bit Windows, an out-of-process 32-bit COM server can communicate with a 64-bit client, and an out-of-process 64-bit COM server can communicate with a 32-bit client. Therefore, if you have a 32-bit DLL that is not COM-aware, you can wrap it in an out-of-process COM server and use COM to marshal calls to and from a 64-bit process.

Hamboy75
  • 938
  • 1
  • 11
  • 22