2013-12-14 26 views
0

我创建了一个系统范围的钩DLL和我的DLL我试图得到通知每次一个新的进程创建或销毁。
当有新的进程被检测到时,我希望能够向调用程序发送消息,无论是布尔值还是自定义对象。 我该怎么做?
目前我正在使用一个文件来记录所有名字!这是可怕的 这是迄今为止代码:我怎样才能从DLL通信到调用应用程序在c + +

DEF文件

;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 << "Destroied!~" << endl; 
      //cout << "Destroied!~" << endl; 
      break; 
     default: 
      //cout << "sth else" << endl; 
      break; 
     } 
    } 
    outfile.close(); 
    return 0; 
} 

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

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

挂钩消费类控制台应用程序

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

回答

1

挂钩DLL加载后,由Windows,在钩进程的地址空间。你将不得不使用IPC。首先请参阅Interprocess Communications

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

请注意,数据复制在接收线程中需要一个活动(泵送)消息队列。

一种可能的方式来实现这(很多人可能):

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

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

在钩子DLL,你将有一个全局变量HWND。当想要使用WM_COPYDATA时,如果全局变量为空,则使用FindWindow来检索HWND,并将其存储以供下次使用。该代码将在每个挂钩进程中至少执行一次。

您可能希望使用SendMessageTimeout API发送WM_COPYDATA消息。

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

还要注意,你的主线程应该等待在安装钩子之前在辅助线程中正确创建虚拟窗口。

如果你的钩子EXE是一个窗口化的,你不需要辅助线程,但是你将不得不建立一个GUI。也许你也可以保持“只有一个线程”,并设法与一些API兼容,同时有一个活动的消息队列和你的代码,但我不建议这样做。

相关问题