【问题标题】:Why doesn't this system wide CBT hook work properly?为什么这个系统范围的 CBT 挂钩不能正常工作?
【发布时间】:2013-12-13 15:38:54
【问题描述】:

我正在尝试创建一个系统范围的挂钩来监视进程并终止不需要的进程。我搜索并发现我需要使用 CBT 钩子,我的第一次尝试失败,这是第二次,前一个问题可以是 found here

以下代码构建得很好,但似乎甚至没有调用挂钩,因为我尝试在DllMain() 中设置断点,但我从未到达那里。不过其他功能似乎可以访问!

这里是sn-ps的代码:

dllmain.cpp

// dllmain.cpp : Defines the entry point for the DLL application.
#pragma once
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;

 HINSTANCE currentProcessHandle;
 HOOKPROC hkprcSysMsg;
 HHOOK hookID;

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    std::ofstream outfile("test.txt");


    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        currentProcessHandle = hModule;
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

LRESULT CALLBACK HookProcedure(int nCode, WPARAM wparam, LPARAM lparam)
{
    std::ofstream outfile("test.txt");
    if (nCode >= 0)
    {
        switch (nCode)
        {
        case HCBT_CREATEWND:
            outfile << L"Created!~";
            cout << "Created!~" << endl;
            break;
        case HCBT_DESTROYWND:
            outfile << L"Destroied!~";
            cout << "Destroied!~" << endl;
            break;
        default:
            cout << "sth else" << endl;
            break;
        }
    }
    else
    {
        return CallNextHookEx(hookID, nCode, wparam, lparam);
    }
    outfile.close();
}

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

__declspec(dllexport) void UnistallHook()
{
    UnhookWindowsHookEx(hookID);
}

这就是消费者应用程序

// Hook Executer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "..\Dll\dllmain.cpp"
#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
        {
            UnistallHook();
        }
        getchar();
        system("cls");
        cout << "1.Install Hook" << endl
            << "2.Unistall Hook" << endl
            << "0.Exit";
    } while (num != 0 && num < 3);


    return 0;
}

当我运行程序时,没有任何错误,甚至没有任何异常,就好像没有 DLL 或者我在该 DLL 中没有编写任何代码。它有什么问题?

【问题讨论】:

  • :-) include "..\Dll\dllmain.cpp" 不是拥有 DLL 的正确方法。您是否有包含 2 个项目、一个 EXE 和一个 DLL 的 Visual Studio 解决方案?
  • 是的,我愿意!如果我不这样做,我应该如何调用 dll?
  • 但是您的 EXE 不调用任何 DLL!您刚刚在主 EXE 中包含了 DLL cpp 源...
  • 第一步:禁止包含“..\Dll\dllmain.cpp”行!并将其替换为 include "..\Dll\dllmain.h" 在标题中,使用 __declspec(dllimport) 声明 InstallHook 和 UnistallHook
  • 看,你似乎不知道用 DLL 进行 C 编程的基础知识,你将很难尝试使用 CBT Hooks。您链接的 pastebin 在标题中显示了 DllMain 实现...如果我稍后有时间,我可能会发布一个答案。

标签: c++ windows visual-c++ hook


【解决方案1】:

在 CPP 文件中实现您的 DLL 代码,而不是在头文件中:

//dllmain.cpp
#include "stdafx.h" // include <Windows.h>
                    // and other std headers in stdafx.h, if not already done

HINSTANCE currentProcessHandle;
HHOOK hookID;

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( NULL, nCode, wparam, lparam );

    std::ofstream outfile;
    outfile.open( "test.txt",          // replace with an absolute path
                  std::fstream::app ); // append mode
    if (nCode >= 0) {
        switch( nCode ) {
            case HCBT_CREATEWND:
                outfile << "Created!\n";
                break;
            case HCBT_DESTROYWND:
                outfile << "Destroyed!\n";
                break;
            default:
                break;
        }
    }
    outfile.close();
    return 0;
}

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

void UninstallHook( void ) { // NEW NAME
    UnhookWindowsHookEx( hookID );
}    

在头文件中声明 DLL API。

// dllapi.h
void InstallHook( void );
void UninstallHook( void ); // NEW NAME

使用DEF文件导出,添加到DLL项目中

; Def file
EXPORTS
    InstallHook
    UninstallHook

在 EXE 项目中,只包含 DLL 头文件

 #include "..\Dll\dllapi.h"

在EXE项目中,进入properties-&gt;Linker-&gt;Input-&gt;Additional dependencies,添加构建DLL时生成的lib文件。替代方案:在Solution的项目依赖项中使DLL成为EXE的依赖项,并在EXE属性中为Linker-&gt;general-&gt;Use Library dependency Inputs设置Yes

【讨论】:

  • 感谢一百万它编译和构建得很好,现在它创建了文本文件,但它是空的!并且控制台上什么也没有显示(也许 dll 不支持控制台窗口?)我还应该怎么做才能让它工作?
  • 我更改了它,以便它附加它找到的内容,现在这就是我在文本文件中得到的内容:) 5A4F1B9C 5A4F1B9C 5A4F1BB4 5A4F1BB4 5A4F1BB4 5A4F1B9C 5A4F1B9C 5A4F1B9C 5A4F1B9C 非常感谢先生,我会挖掘更多了解是什么原因造成的。明白了,我删除了 L 并且它工作得很好 :) 太棒了 :)
  • 您是否使用了文本文件的绝对路径,如“c:\\temp\\test.txt”?
  • 是的,我完全按照你的建议做了,现在它就像梅赛德斯奔驰一样工作:)
  • 在写 L"string" 时使用 wofstream,而不是 ofstream。或者不要以 L 为前缀 :-)
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
相关资源
最近更新 更多