DLL进程挂钩不起作用

时间:2017-11-18 23:14:02

标签: c++ winapi dll

我想使用dll注入将我的KeyboardProc从dll挂钩到我创建的窗口。我想在按下聚焦注入窗口的按键时看到消息框,但我的代码无法正常工作。

注入的窗口代码:

#include <windows.h>
#include <iostream>

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (lParam)
    {
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgs, int nCmdShow)
{
    HWND hwnd;
    LPCTSTR className = L"WNDCLASS";
    LPCTSTR windowName = L"Window";

    WNDCLASSEX wcex;
    memset(&wcex, 0, sizeof(wcex));

    wcex.cbSize = sizeof(wcex);
    wcex.hInstance = hInstance;
    wcex.lpszClassName = className;
    wcex.style = CS_DBLCLKS;
    wcex.lpfnWndProc = WndProc;
    wcex.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));

    if (!RegisterClassEx(&wcex))
    {
        return -1;
    }

    hwnd = CreateWindowEx(NULL, className, windowName, WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);

    if (!hwnd)
    {
        return -2;
    }

    MSG msg;

    ShowWindow(hwnd, SW_NORMAL);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, hwnd, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 
        msg.lParam;
}

dll代码:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>

HHOOK hhkKb;

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (wParam == WM_KEYDOWN)
    {
        MessageBox(0, L"DOWN", L"keyboard key down in dll", MB_ICONINFORMATION);
    }
    else if (wParam == WM_KEYUP)
    {
        MessageBox(0, L"UP", L"keyboard key up in dll", MB_ICONINFORMATION);
    }

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

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        {
            HWND windowHandle = FindWindow(NULL, L"Window");

            if (windowHandle == NULL)
            {
                MessageBox(NULL, L"Error", L"Handle is null", MB_ICONERROR);
                return TRUE;
            }

            DWORD threadId = GetWindowThreadProcessId(windowHandle, NULL);
            hhkKb = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, threadId);
            MessageBox(NULL, L"Success", L"Sucessfully injected dll", MB_ICONINFORMATION); //shows that message

            break;
        }
        case DLL_PROCESS_DETACH:
        {
            UnhookWindowsHookEx(hhkKb);
            break;
        }
    }
    return TRUE;
}

我看到&#34;成功注入了dll&#34;消息,但是当我按下按键进入注入的窗口时,没有调用KeyboardProc,我做错了什么?

1 个答案:

答案 0 :(得分:1)

  

使用dll注入

不清楚你是如何进行这种dll注入的,但根据你以前的question可以假设你手动将你的dll CreateRemoteThread注入LoadLibraryA。在任何情况下,从dll入口点调用SetWindowsHookEx都是错误的。

正式地,如果调用SetWindowsHookEx退出的线程 - 钩子将被自动删除。所以可以说退出线程间接调用UnhookWindowsHookEx。不确定这是清楚的记录,但可以在下一个简单的测试中查看

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    DbgPrint("%x>KeyboardProc(%x)\n", GetCurrentThreadId(), wParam);

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

ULONG HookThread(PVOID threadId)
{
    DbgPrint("%x>HookThread(%x)\n", GetCurrentThreadId(), (ULONG)(ULONG_PTR)threadId);
    if (HHOOK hhk = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, (HINSTANCE)&__ImageBase, (ULONG)(ULONG_PTR)threadId))
    {
        Sleep(10000);//10 sec
        //MessageBoxW(0,0,L"Close Me", MB_ICONWARNING);
    }
    return 0;
}

void test()
{
    if (HANDLE hThread = CreateThread(0, 0, HookThread, (PVOID)(ULONG_PTR)GetCurrentThreadId(), 0,0))
    {
        CloseHandle(hThread);
        MessageBoxW(0,0,L"Press Buttons here", MB_ICONINFORMATION);
    }
}

前几秒钟(或直到你关闭MessageBoxW L&#34;关闭我&#34;如果选择此变体),当您按下时,您可以从KeyboardProc查看dbgprint第一个消息框上的按钮。 HookThread退出后 - 将不再调用KeyboardProc

所以如果你通过CreateRemoteThread注入dll - 这个线程调用LoadLibrary,那么SetWindowsHookEx将在这个线程中被调用,最后线程只是退出 - 这就删除了call {的效果{1}} - 将删除钩子。

但是如果我们使用SetWindowsHookEx,我们不需要手动注入dll来处理。反之亦然 - 这种api特殊设计可自动将dll注入远程进程。当然你不能从dll入口点调用SetWindowsHookEx - 这是无稽之谈。你需要从远程进程调用SetWindowsHookEx - 结果你的dll将被注入目标进程。重读Installing and Releasing Hook Procedures