Почему этот общесистемный хук CBT не работает должным образом?

Я пытаюсь создать общесистемный крючок для мониторинга процессов и завершения нежелательных. Я искал и обнаружил, что мне нужно использовать крючки CBT, моя первая попытка не удалась, и это вторая, первый вопрос может быть находится здесь.

Следующий код строится просто отлично, но кажется, что хуки даже не вызываются, так как я пытался установить точку останова в DllMain(), но так и не дошел до нее. Хотя другие функции кажутся доступными!

Вот фрагменты кода:

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. Что с этим не так?


person Rika    schedule 13.12.2013    source источник
comment
:-) include ..\Dll\dllmain.cpp НЕ является правильным способом иметь DLL. У вас есть решение Visual Studio с двумя проектами, одним EXE и одним DLL?   -  person manuell    schedule 13.12.2013
comment
Да,! если я этого не сделаю, как мне вызвать dll?   -  person Rika    schedule 13.12.2013
comment
Но ваш EXE не вызывает НИ ОДНОЙ DLL! Вы только что включили источник DLL cpp в свой основной EXE...   -  person manuell    schedule 13.12.2013
comment
Первый шаг: подавить строку include ..\Dll\dllmain.cpp! и замените его на include ..\Dll\dllmain.h В заголовке объявите InstallHook и UnistallHook с помощью __declspec(dllimport)   -  person manuell    schedule 13.12.2013
comment
Я сделал это, и вот результат: pastebin.com/8Xg4uyiU Теперь мое приложение не запускается! Он просто падает при выполнении и говорит: Приложение не удалось запустить правильно (0xc0000007b). Нажмите «ОК», чтобы закрыть приложение)   -  person Rika    schedule 13.12.2013
comment
я перестроил решение, а также удалил dllexport, как показано здесь: pastebin.com/Z0vryTrZ все равно ничего не работает! как будто хука нет!!!(программа работает нормально, но не делает то, что должна делать)   -  person Rika    schedule 13.12.2013
comment
Послушай, ты, кажется, не знаешь основ программирования на C с DLL, тебе будет очень трудно использовать CBT Hooks. Связанный вами pastebin показывает реализацию DllMain в заголовке ... Я могу опубликовать ответ, если у меня будет время позже.   -  person manuell    schedule 13.12.2013
comment
спасибо, буду благодарен   -  person Rika    schedule 13.12.2013


Ответы (1)


реализовать свой код DLL в файле CPP, а не в заголовке:

//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 );
}    

Объявите API-интерфейсы DLL в заголовочном файле.

// 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->Linker->Input->Additional dependencies и добавьте файл lib, сгенерированный во время сборки DLL. Альтернатива: сделать DLL зависимостью EXE в проектных зависимостях Solution, а в свойствах EXE установить Yes для Linker->general->Use Library dependency Inputs

person manuell    schedule 13.12.2013
comment
Огромное спасибо, он компилируется и строится просто отлично, и теперь он создает текстовый файл, но он пустой! и ничего не отображается на консоли (может быть, dll не поддерживает консольные окна?), что еще я должен сделать, чтобы заставить это работать? - person Rika; 13.12.2013
comment
Я изменил его так, чтобы он добавлял то, что нашел, и теперь это то, что я получаю в текстовом файле :) 5A4F1B9C 5A4F1B9C 5A4F1BB4 5A4F1BB4 5A4F1BB4 5A4F1B9C 5A4F1B9C 5A4F1B9C 5A4F1B9C Большое спасибо, сэр, я буду копать больше, чтобы увидеть, что вызывает это. Понял, я удалил L, и все работает отлично :) круто :) - person Rika; 13.12.2013
comment
Вы использовали абсолютный путь для текстового файла, как c:\\temp\\test.txt ? - person manuell; 13.12.2013
comment
Да, я сделал именно то, что вы предложили, и теперь он работает как Mercedes Benz :) - person Rika; 13.12.2013
comment
используйте wofstream, а не ofstream, при написании Lstring. Или не ставьте префикс L :-) - person manuell; 13.12.2013