问题
The following java
program calls a native method in C
that should print a message you pressed a key !
if the user presses a key. But i can't see the message as the i press the key.I also check if the function SetWindowsHookEx
returns null but no,it doesn't return null.
Java Code :
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 Code :
#include <stdio.h>
#include <windows.h>
#include <w32api.h>
#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;
}*/
The only output that I see is Is not NullInside fucntion setWinHook !
Where is the problem ?
What should i do so that this program returns me the message when i press the key.
The only output that I see is : Inside function setWinHook !
Note :
If the above program runs on someone's machine,please mention that.
Output Pic :
I don't see any message on key tapping.Program just exits after 10 seconds without displaying a message.
回答1:
You cannot simply declare a local HINSTANCE variable out of the blue and pass that to the function. A HINSTANCE is a handle to your application instance, in other words a pointer that must point at a valid location. You need to use the HINSTANCE that is your own application.
My Windows API is a bit rusty, but I believe you can do this through GetModuleHandle(). So:
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 !");
}
It is also quite possible that your Java goo has a HINSTANCE hidden in an object somewhere.
回答2:
Check out Java Global(low level) Keyboard/Mouse Hook
I tried to write one myself, but there seems to be too many unknown details for me (JNI, HOOKS, threading problems, etc.)
回答3:
The HHOOK variable needs to be declared inside a shared data segment. Check how it is done here - http://www.codeproject.com/Articles/5002/Mousey-Roll-Over-and-Park
回答4:
You need a GetMessage/PeekMessage
loop in order for your keyboard hook to receive any events. For a Java implementation of a keyboard hook on windows, see JNA Keyboard Hook in Windows, or the contributed package that performs the same function in the JNA project (https://github.com/twall/jna/tree/master/contrib/w32keyhook).
回答5:
There is for sure a better way to implement this. Here DllMain
is called multiple times once a thread has been created,that doesn't seem right to me.I am not sure if this is legal ! The C Code starts a new thread to implement the keycatcher.
C Code :
#include <stdio.h>
#include <windows.h>
#include <w32api.h>
#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 Code :
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");
}
}
I start the java program and DLLMain
is called.
来源:https://stackoverflow.com/questions/10731172/cannot-see-the-message-when-user-presses-the-key