2013-12-14 28 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兼容,同時有一個活動的消息隊列和你的代碼,但我不建議這樣做。

相關問題