注入到Java应用程序中

C++ Inject into Java application

本文关键字:应用程序 Java 注入      更新时间:2023-10-16

我真的很难弄清楚为什么我不能让我的钩子在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;
}

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

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

弹出鼠标钩子的消息框。这是预期的行为。

但是对于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_eventkeybd_event,仍然没有。我尝试使用Java鼠标监听器和键盘监听器并伪造事件。仍然没有. .

钩子肯定会加载,因为我可以看到我的鼠标在移动它之前延迟了3秒。还做了一个弹出确认加载

然而,我仍然不明白为什么它不能在Java应用程序上工作。知道怎么让他们工作吗。或者是否有另一种方法可以更好地从C/c++为Java做到这一点?如果没有,有没有办法在Java中做到这一点?

您可能需要阅读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("Mousen");
    }
    return CallNextHookEx(MouseHook, Code, wParam, lParam);
}
 
LRESULT WINAPI KeyboardHookProc(int Code, WPARAM wParam, LPARAM lParam) {
    if (Code == HC_ACTION) {
        printf("Keyboardn");
    }
    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;
}