java通过jni调用hook无效

发布于 2022-09-07 00:10:01 字数 2989 浏览 18 评论 0

我需要实现一个钩子程序来禁用鼠标键盘的输入,然后将其生成为dll,然后在java中调用,调用时候程序没有报错,但是调用无效.下面是部分代码

c++部分:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "stdio.h"

HHOOK g_HookHwnd = NULL;
HHOOK g_hMouse = NULL;

// 钩子子程
extern "C" _declspec(dllexport) LRESULT CALLBACK MyHookFun(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("in hook key function\n");
    // 这个Structure包含了键盘的信息
    /*typedef struct {
    DWORD vkCode;
    DWORD scanCode;
    DWORD flags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
    } KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;*/
    // 我们只需要那个vkCode
    PKBDLLHOOKSTRUCT pVirKey = (PKBDLLHOOKSTRUCT)lParam;

    // MSDN说了,nCode < 0的时候别处理
    if (nCode >= 0)
    {
        // 按键消息
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            switch (pVirKey->vkCode)
            {
            case VK_LWIN:
            case VK_RWIN:
                return 1;  // 吃掉消息
                break;
            }
            return 1;
            break;
        }
    }

    return CallNextHookEx(g_HookHwnd, nCode, wParam, lParam);
}

extern "C" _declspec(dllexport) LRESULT CALLBACK  MyHookMouse(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("in hook mouse function\n");
    return 1;
}


HMODULE g_Module;
extern "C" _declspec(dllexport)  BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    {

        break;
    }
    }
    return TRUE;
}


extern "C" _declspec(dllexport) void FuncHookDevice()
{
    if (!g_HookHwnd)
    {
        printf("start hook\n");
        g_HookHwnd = SetWindowsHookEx(WH_KEYBOARD_LL, MyHookFun, g_Module, 0);
        //g_hMouse = SetWindowsHookEx(WH_MOUSE_LL, MyHookMouse, g_Module, 0);  //暂时禁用鼠标钩子
    }
}

extern "C" _declspec(dllexport) void FuncEndHook()
{
    printf("end hook\n");
    UnhookWindowsHookEx(g_HookHwnd);
    //UnhookWindowsHookEx(g_hMouse);   //暂时禁用鼠标钩子
    g_HookHwnd = NULL;
}

java程序:

public class HookTest {
    public interface  Hook extends Library{
        Hook INSTANCE = (Hook) Native.loadLibrary("lib/Hook",Hook.class);
        public void FuncEndHook();
        public void FuncHookDevice();
    }

    public static void main(String[] args) {
        Hook.INSTANCE.FuncHookDevice();
    }
}

运行结果:
clipboard.png

程序运行完后发现只输出了"start hook" 然后程序就停止了运行.并没有打印出"in hook key function".说明程序是没有进入到钩子函数内部的. 这个c++程序的钩子我是经过测试的,使用c++调用dll可以成功的禁用掉键盘或者鼠标.

所以为什么用java调用的时候就无效呢.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫轩蝶泪 2022-09-14 00:10:01

终于解决了这个问题,在stackoverflow上面提问找到了解答:问答详情

做法是添加消息队列.为什么添加在这个问答:为什么添加消息队列,大致意思是因为低级鼠标键盘钩子默认会马上返回返回值,通过添加消息队列就能解决.

添加了一个线程来控制钩子,如果不添加好像程序不能按要求退出.

最后c++部分代码:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "stdio.h"

HHOOK g_HookHwnd = NULL;
HHOOK g_hMouse = NULL;
HANDLE hThread = NULL;

// 钩子子程
extern "C" _declspec(dllexport) LRESULT CALLBACK MyHookFun(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("in hook key function\n");
    // 这个Structure包含了键盘的信息
    /*typedef struct {
    DWORD vkCode;
    DWORD scanCode;
    DWORD flags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
    } KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;*/
    // 我们只需要那个vkCode
    PKBDLLHOOKSTRUCT pVirKey = (PKBDLLHOOKSTRUCT)lParam;

    // MSDN说了,nCode < 0的时候别处理
    if (nCode >= 0)
    {
        // 按键消息
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            switch (pVirKey->vkCode)
            {
            case VK_LWIN:
            case VK_RWIN:
                return 1;  // 吃掉消息
                break;
            }
            return 1;
            break;
        }
    }

    return CallNextHookEx(g_HookHwnd, nCode, wParam, lParam);
}

extern "C" _declspec(dllexport) LRESULT CALLBACK  MyHookMouse(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("in hook mouse function\n");
    return 1;
}


HMODULE g_Module;
extern "C" _declspec(dllexport)  BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    {

        break;
    }
    }
    return TRUE;
}


extern "C" _declspec(dllexport) DWORD WINAPI controllHook(LPVOID lpParamter)
{
    g_HookHwnd = SetWindowsHookEx(WH_KEYBOARD_LL, MyHookFun, g_Module, 0);
    g_hMouse = SetWindowsHookEx(WH_MOUSE_LL, MyHookMouse, g_Module, 0);
    while (true) {
        MSG msg;
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}


extern "C" _declspec(dllexport) void FuncHookDevice()
{
    if (!g_HookHwnd)
    {
        hThread = CreateThread(NULL, 0, controllHook, NULL, 0, NULL);
        
        printf("start hook\n");
        g_HookHwnd = SetWindowsHookEx(WH_KEYBOARD_LL, MyHookFun, g_Module, 0);

    }
}

extern "C" _declspec(dllexport) void FuncEndHook()
{
    printf("end hook\n");
    UnhookWindowsHookEx(g_HookHwnd);
    UnhookWindowsHookEx(g_hMouse);
    CloseHandle(hThread);
    g_HookHwnd = NULL;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文