代码之家  ›  专栏  ›  技术社区  ›  Brandon

C++注入Java应用程序

  •  1
  • Brandon  · 技术社区  · 11 年前

    我真的很难弄明白为什么我不能在java应用程序中使用钩子。。

    我创建了一个C++WINAPI窗口。我加载我的“钩子”dll,每次我向应用程序发送假输入时,它都会很好地引发一个标志。

    然而,如果我对Java应用程序做同样的操作,它根本不起作用!

    我的dll如下所示:

    #include <windows.h>
    
    HINSTANCE hInstance = nullptr;
    HHOOK MouseHook = {0};   /** Structure for hooking the mouse **/
    HHOOK KeyboardHook = {0};  /** Structure for hooking the keyboard **/
    
    LRESULT __stdcall MouseHookProc(int Code, WPARAM wParam, LPARAM lParam)
    {
        if (Code == HC_ACTION)
        {
            MSLLHOOKSTRUCT* Info = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
            if ((Info->flags & LLMHF_INJECTED) == LLMHF_INJECTED)
            {
                MessageBox(NULL, "DETECTED Mouse", "", 0);
            }
        }
        return CallNextHookEx(MouseHook, Code, wParam, lParam);
    }
    
    LRESULT __stdcall KeyboardHookProc(int Code, WPARAM wParam, LPARAM lParam)
    {
        if (Code == HC_ACTION)
        {
            KBDLLHOOKSTRUCT* Info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
            if ((Info->flags & LLKHF_INJECTED) == LLKHF_INJECTED)
            {
                MessageBox(NULL, "DETECTED Keyboard", "", 0);
            }
        }
        return CallNextHookEx(KeyboardHook, Code, wParam, lParam);
    }
    
    extern "C" __declspec(dllexport) bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
            {
                hInstance = hinstDLL;
                SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hInstance, 0);
                SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, 0);
            }
            break;
    
            case DLL_PROCESS_DETACH:
            {
                UnhookWindowsHookEx(KeyboardHook);
                UnhookWindowsHookEx(MouseHook);
            }
            break;
        }
        return true;
    }
    

    然后我创建了一个C++WINAPI应用程序 WM_CREATE 块:

    case WM_CREATE:
        LoadLibrary("JavaHook.dll");
        mouse_event(MOUSEEVENTF_LEFTDOWN, 100, 100, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP,100, 100,0,0);
    break;
    

    弹出MouseHook的MessageBox。这是预期的行为。

    然而,对于Java,我做到了:

    public class HookTest {
    
        public static void main(String[] args) {
            JFrame frame = new JFrame("Test Window");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
    
            System.loadLibrary("JavaHook");
        } 
    }
    

    然后我在应用程序上使用SendInput,如下所示:

    INPUT input;
    input.type = INPUT_MOUSE;
    input.mi.mouseData = 0;
    input.mi.dx =  100 * (65536 / GetSystemMetrics(SM_CXSCREEN)); //x being coord in pixels
    input.mi.dy =  100 * (65536 / GetSystemMetrics(SM_CYSCREEN)); //y being coord in pixels
    input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
    SendInput(1, &input, sizeof(input));
    

    什么都没有弹出。我试过使用 mouse_event keybd_event ,仍然没有。我尝试使用Java鼠标监听器和键盘监听器,并伪造事件。。仍然一无所获。。

    钩子肯定会加载,因为我可以看到我的鼠标在移动之前有很长的3秒钟的延迟。在加载时也会弹出一个窗口来确认。

    然而,我仍然无法理解为什么它在Java应用程序上不起作用。我能让他们工作吗。或者,有没有另一种方法可以更好地从C/C++为Java实现?如果没有,有没有用Java实现的方法?

    1 回复  |  直到 11 年前
        1
  •  2
  •   Zv_oDD    4 年前

    您可能需要阅读备注 SetWindowsHookEx 文档

    具体地说,安装全局钩子的线程应该继续处理Windows消息,以便允许32位和64位应用程序在钩子应用程序的上下文中运行钩子代码。

    因此,我建议您从DllMain创建一个单独的线程。线程将安装一个钩子,然后运行到GetMessage/ProcessMessage循环: http://pastebin.com/JmMvMX78

    #include <windows.h>
    #include <stdio.h>
     
    HHOOK MouseHook = {0};
    HHOOK KeyboardHook = {0};
     
    LRESULT WINAPI MouseHookProc(int Code, WPARAM wParam, LPARAM lParam) {
        if (Code == HC_ACTION) {
            printf("Mouse\n");
        }
        return CallNextHookEx(MouseHook, Code, wParam, lParam);
    }
     
    LRESULT WINAPI KeyboardHookProc(int Code, WPARAM wParam, LPARAM lParam) {
        if (Code == HC_ACTION) {
            printf("Keyboard\n");
        }
        return CallNextHookEx(KeyboardHook, Code, wParam, lParam);
    }
     
    DWORD WINAPI ThreadProc(LPVOID param) {
        HINSTANCE hInstance = (HINSTANCE)param;
        MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, 0);
        KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hInstance, 0);
     
        MSG message;
        while (GetMessage(&message, (HWND)-1, 0, 0) > 0) {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
     
        UnhookWindowsHookEx(KeyboardHook);
        UnhookWindowsHookEx(MouseHook);
     
        return 0;
    }
     
    extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
        if (fdwReason == DLL_PROCESS_ATTACH) {
            CloseHandle(CreateThread(NULL, 0, ThreadProc, hinstDLL, 0, NULL));
        }
        return TRUE;
    }