用户按下该键时无法看到该消息

下面的java程序在C中调用一个本机方法,它应该打印you pressed a key !的消息you pressed a key ! 如果用户按下一个键。 但我无法看到消息,因为我按下了键。我还检查函数SetWindowsHookEx返回null但不是,它不返回null。

Java代码:

 package keylogger; public class TestKeys { private native void setWinHook(); public static void main(String args[]) { TestKeys o = new TestKeys(); try { o.setWinHook(); Thread.sleep(10000); } catch(Exception exc) { exc.printStackTrace(); } } static { System.loadLibrary("MyHook"); } 

C代码:

 #include  #include  #include  #include "keylogger_TestKeys.h" static HHOOK handleKeyboardHook = NULL; HINSTANCE hInst = NULL; static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { printf("You pressed a key !\n"); return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam); } void Java_keylogger_TestKeys_setWinHook (JNIEnv *env, jobject obj) { hInst = GetModuleHandle(NULL); // include or exclude,i don't see the result handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,NULL, 0); if(handleKeyboardHook==NULL) { printf("Is Null"); } else { printf("Is not Null"); } printf("Inside fucntion setWinHook !"); } /*int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { printf("Hello World !"); handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0); if(handleKeyboardHook==NULL) { printf("Is Null"); } else { printf("Is not Null"); } MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }*/ 

我看到的唯一输出是Is NullInside fucntion setWinHook!

问题出在哪儿 ?

我应该怎么做才能让我按下按键时该程序返回信息。 我看到的唯一输出是: Inside function setWinHook !

注意 :

如果上述程序在某人的机器上运行,请提及。

输出图片:

在此处输入图像描述

我没有在按键上看到任何消息。程序只在10秒后退出而不显示消息。

您不能简单地声明本地HINSTANCE变量并将其传递给函数。 HINSTANCE是应用程序实例的句柄,换句话说是指向必须指向有效位置的指针。 您需要使用您自己的应用程序HINSTANCE。

我的Windows API有点生疏,但我相信你可以通过GetModuleHandle()来做到这一点。 所以:

 void Java_keylogger_TestKeys_setWinHook (JNIEnv *env, jobject obj) { HINSTANCE hInst; hInst = GetModuleHandle(null); handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0); printf("Inside function setWinHook !"); } 

你的Java goo很可能在某个对象中隐藏了一个HINSTANCE。

查看Java Global(低级)键盘/鼠标挂钩

我试着自己写一个,但似乎有太多未知的细节(JNI,HOOKS,穿线问题等)

HHOOK变量需要在共享数据段内声明。 检查它是如何完成的 – http://www.codeproject.com/Articles/5002/Mousey-Roll-Over-and-Park

您需要GetMessage/PeekMessage循环才能使键盘钩子接收任何事件。 对于Windows上的键盘钩子的Java实现,请参阅Windows中的JNA Keyboard Hook ,或者在JNA项目中执行相同function的贡献包( https://github.com/twall/jna/tree/master/contrib/ w32keyhook )。

肯定有更好的方法来实现这一点。 一旦创建了一个线程,就会多次DllMain ,这对我来说似乎不对。我不确定这是否合法! C代码启动一个新线程来实现keycatcher。

C代码:

 #include  #include  #include  #include "keylogger_TestKeys.h" static HHOOK handleKeyboardHook = NULL; HINSTANCE hInst = NULL; static DWORD hookThreadId = 0; static HANDLE hookThreadHandle = NULL; BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved); static int i = 0; static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { printf("You pressed the key !"); return CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam); } BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(hookThreadHandle==NULL) { printf("hookThreadHandle is NULL\n"); LPTHREAD_START_ROUTINE lpStartAddress = &installHook; hookThreadHandle = CreateThread(NULL, 0, lpStartAddress, NULL, 0, &hookThreadId); } } BOOL WINAPI installHook(HINSTANCE hinstDLL, DWORD fwdReason, LPVOID lpvReserved) { // printf("From installHook : %u",fwdReason); printf("count : %d\n",i++); handleKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinstDLL, 0); MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void Java_keylogger_TestKeys_unregisterWinHook (JNIEnv *env, jobject obj) { // should have stopped the thread before unhooking if(handleKeyboardHook != NULL) { UnhookWindowsHookEx(handleKeyboardHook); } } void Java_keylogger_TestKeys_stopNativeThread // stop the native thread (JNIEnv *env, jobject obj) { PostThreadMessage(hookThreadId, WM_QUIT, (WPARAM) NULL, (LPARAM) NULL); WaitForSingleObject(hookThreadHandle, 5000); } 

Java代码:

 package keylogger; public class TestKeys { private static int i = 0; private native void setWinHook(); private native void unregisterWinHook(); private native void createWinThread(); private native void stopNativeThread(); public static void main(String args[]) { TestKeys o = new TestKeys(); try { Thread.sleep(5000); }catch(Exception exc) { exc.printStackTrace(); } o.stopNativeThread(); o.unregisterWinHook(); System.out.println("Native thread stopped and Hook unregistered !"); try { Thread.sleep(3000); // Now you won't see the message : you pressed the key }catch(Exception exc) { exc.printStackTrace(); } } static { System.loadLibrary("MyHook"); } } 

我启动java程序并调用DLLMain