c++ - 如何从 DLL 与 C++ 中的调用应用程序通信

标签 c++ windows dll hook

<分区>

我创建了一个系统范围的 Hook DLL,在我的 DLL 中,我试图在每次创建或销毁新进程时得到通知。每当检测到新进程时,我都希望能够向调用程序发送消息,无论是 bool 值还是自定义对象。

我该怎么做?目前我正在使用一个文件来记录所有名称,这太可怕了。这是到目前为止的代码:

定义文件

;LIBRARY
; Def file
EXPORTS
    InstallHook
    UninstallHook

dllapi.h

void InstallHook(void);
void UninstallHook(void);

dllmain.cpp

#include "stdafx.h" 

using namespace std;
HINSTANCE currentProcessHandle;
HHOOK hookID;
string str = "1";
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
        currentProcessHandle = hModule;
    return TRUE;
}

LRESULT CALLBACK HookProcedure(int nCode, WPARAM wparam, LPARAM lparam)
{

    if (nCode < 0) return CallNextHookEx(hookID, nCode, wparam, lparam);

    std::ofstream outfile;
    CBT_CREATEWND   *CBTHOOKCREATE;
    RECT            *CBTRECTPTR;
    RECT            CBTRECT;
    wstring         Message;

    CBTHOOKCREATE = (CBT_CREATEWND*) lparam;
    LPWSTR str = L"                     ";
    outfile.open(("d:\\test.txt"), std::ios_base::app);

    if (nCode >= 0) {
        switch (nCode)
        {
        case HCBT_CREATEWND:
            outfile << *(CBTHOOKCREATE->lpcs->lpszName) << " " << CBTHOOKCREATE->lpcs->lpszName << " Created!~ " << endl;
            //cout << "Created!~" << endl;
            break;
        case HCBT_DESTROYWND:
            outfile << "Destroyed!~" << endl;
            //cout << "Destroyed!~" << endl;
            break;
        default:
            //cout << "something else" << endl;
            break;
        }
    }
    outfile.close();
    return 0;
}

void InstallHook(void)
{
    hookID = SetWindowsHookEx(WH_CBT, HookProcedure, currentProcessHandle, 0);
}

void UninstallHook(void)
{ 
    UnhookWindowsHookEx(hookID);
}

Hook 消费者控制台应用程序

// Hook Executer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "..\Dll\dllapi.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int num = -1;
    cout << "1.Install Hook"<<endl
        << "2.Unistall Hook"<<endl
        << "0.Exit";
    do{
        cin >> num;
        if (num ==1)
        {
            InstallHook();

        }
        else
        {
            UninstallHook();
        }
        getchar();
        system("cls");
        cout << "1.Install Hook" << endl
            << "2.Unistall Hook" << endl
            << "0.Exit";
    } while (num != 0 && num < 3);
    

    return 0;
}

最佳答案

Hook DLL 由 Windows 加载到 Hook 进程的地址空间中。您将不得不使用 IPC。参见 Interprocess Communications首先。

在这种情况下可用的一个简单 IPC 可能是 Data Copy .

请注意,数据复制需要接收线程中的事件(泵送)消息队列。

一种可能的实现方式(许多其他可能的方式):

您将辅助线程添加到您的 EXE,并带有一个消息队列。在新线程中,您将创建一个具有特定类名的虚拟不可见窗口。

其代码是一个非常经典的序列:RegisterClassCreateWindowwhile GetMessage DispatchMessage

在 Hook DLL 中,您将拥有一个全局 HWND 变量。当要使用WM_COPYDATA时,如果全局变量为null,使用FindWindow获取HWND,并保存起来以备下次使用。该代码将在每个 Hook 进程中至少执行一次。

您可能想要使用 SendMessageTimeout用于发送 WM_COPYDATA 消息的 API。

请注意,如果您快速停止/重新启动您的 exe,某些进程可能会在全局变量中存储无效的 HWND。检查 Send API 的返回值,如果是“invalid hwnd”,则重做 FindWindow。 (不确定这种行为是否真的可能,但无论如何......)

另请注意,在安装 Hook 之前,您的主线程应等待辅助线程中虚拟窗口的正确创建。

如果您的 Hook EXE 是窗口化的,则不需要辅助线程,但您必须构建一个 GUI。你也可以,也许,留在“只有一个线程”并设法玩弄一些API,同时拥有一个事件的消息队列和你的 getchar 代码,但我不建议这样做.

关于c++ - 如何从 DLL 与 C++ 中的调用应用程序通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20583408/

相关文章:

c++ - LTO、去虚拟化和虚拟表

C++ 无输出,boost.asio

c# - 将 C 结构编码到 C#

c++ - 单例 : C++ shared dll

c - MASM:从程序集访问全局 C 变量

c++ - 未处理的异常堆栈溢出 win32 控制台应用程序

c++ - 如何在 C++ 中对数组中的字母进行排序?

.net - 为什么 System.Windows.MessageBoxImage 有相同值的枚举子项?

java - Windows 上的 Jenkins Master - Java 设置

windows - python easysnmp packge install error windows..失败,退出状态为2