2017-02-27 48 views
0

時返回null。和SetWindowsHookEx鉤住我已經寫了下面的兩個應用程序(DLL,EXE)掛鉤一個dll到膩子,以聽鍵盤事件的特定線程

一種應用是DLL的應用程序,它包含鉤方法(meconnect)。

#include "stdafx.h" 
#include <stdio.h> 
#include <windows.h> 

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) { 
    /* open file */ 
    FILE *file; 
    fopen_s(&file, "C:\\temp.txt", "a+"); 

    switch (Reason) { 
    case DLL_PROCESS_ATTACH: 
     fprintf(file, "DLL attach function called.\n"); 
     break; 
    case DLL_PROCESS_DETACH: 
     fprintf(file, "DLL detach function called.\n"); 
     break; 
    case DLL_THREAD_ATTACH: 
     fprintf(file, "DLL thread attach function called.\n"); 
     break; 
    case DLL_THREAD_DETACH: 
     fprintf(file, "DLL thread detach function called.\n"); 
     break; 
    } 

    /* close file */ 
    fclose(file); 

    return TRUE; 
} 

extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) { 
    //FILE *file; 
    //fopen_s(&file, "C:\\function.txt", "a+"); 
    //fprintf(file, "Function keyboard_hook called.\n"); 
    //fclose(file); 

    OutputDebugString(L"function keyboard hook called. \n"); 
    //return 0; 
    return(CallNextHookEx(NULL, code, wParam, lParam)); 
} 

這裏meconnect方法將在PuTTY應用程序上觸發鍵盤事件時調用。

下面給出的是將注入上述DLL到膩子應用程序的代碼。

// program.exe.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <Windows.h> 
#include <string> 
#include <io.h> 

using namespace std; 

void Usage() 
{ 
    printf("Usage: InjectDLL pid path-to-dll [-privilege]"); 
} 


int _tmain(int argc, char* argv[]) 
{ 



    /* 
    * Load library in which we'll be hooking our functions. 
    */ 
    HMODULE dll = LoadLibrary(L"C:\\drivers\\dllinject.dll"); 
    //HMODULE dll = LoadLibrary((LPCTSTR)buf); 
    if (dll == NULL) { 
     printf("The DLL could not be found.\n"); 
     getchar(); 
     return -1; 
    } 

    /* 
    * Get the address of the function inside the DLL. 
    */ 
    HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "[email protected]"); 
    if (addr == NULL) { 
     printf("The function was not found.\n"); 
     getchar(); 
     return -1; 
    } 

    /* 
    * Hook the function. 
    */ 
    DWORD procID=0; 
    HWND targetWnd = FindWindowA("PuTTYConfigBox","PuTTY Configuration"); 
    //HWND windowHandle = FindWindowA(NULL, "Calculator.exe"); 
    DWORD threadID = GetWindowThreadProcessId(targetWnd, &procID); 

    wchar_t msgBuf[1024] = L""; 
    wchar_t msgBuf2[1024] = L""; 
    wsprintf(msgBuf, L"the proc Id is %d", threadID); 

    OutputDebugString(msgBuf); 
    HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, threadID); 
    DWORD x = GetLastError(); 
    wsprintf(msgBuf2, L"the last error is %d", x); 
    OutputDebugString(msgBuf2); 
    if (handle == NULL) { 
     printf("The KEYBOARD could not be hooked.\n"); 
    } 
    else{ 
     printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.\n"); 
    } 

    /* 
    * Unhook the function. 
    */ 

    getchar(); 
    UnhookWindowsHookEx(handle); 

    return 0; 
} 

當我運行上面的代碼,SetWindowsHookEx函數總是返回null,這意味着調用SetWindowsHookEx不鉤入膩子應用。任何人都可以幫助我理解我在這裏做錯了什麼。

+1

當'和SetWindowsHookEx()'失敗,是什麼GetLastError()是否返回? DLL是爲32位還是64位編譯的? PuTTY是32bit還是64bit?您不能將32位DLL注入64位進程,反之亦然。即使'SetWindowsHookEx()'成功,'meconnect()'也被聲明爲錯誤。返回值需要是'LRESULT'而不是'int',它必須使用'__stdcall'調用約定。 –

+2

改善你的錯誤處理,顯示GetLastError()返回的值。您傳遞的'procID'值不正確,它需要是線程標識,而不是進程標識。換句話說,你需要GetWindowThreadProcessId()的返回值。總是最好的工作從已知的良好的代碼順便說一句,這是不是很容易得到正確的。 –

+0

@RemyLebeau,感謝您的評論。我根據給出的評論修改了問題中的代碼。在meconnect發生變化後,它會顯示'The function was not found'。我修改了'meconnect'以使'__stdcall'調用約定和返回類型變爲LRESULT。爲什麼它沒有找到meconnect功能 – KItis

回答

1

需要在接下來的方式在DLL函數聲明:

extern "C" LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) { 
//... 
} 

#ifdef _X86_ 
#define EXP_meconnect "[email protected]" 
#elif defined(_AMD64_) 
#define EXP_meconnect "meconnect" 
#else 
#error "unknown platform" 
#endif 

__pragma(comment(linker, "/export:meconnect=" EXP_meconnect)) 

的始終名稱 「meconnect」 導出。另一種方式 - 使用def file


,或者如果你聲明爲

extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) { 
//... 
} 
在DLL

,你的exe需要下面的代碼:

#ifdef _X86_ 
#define EXP_meconnect "[email protected]" 
#elif defined(_AMD64_) 
#define EXP_meconnect "meconnect" 
#else 
#error "unknown platform" 
#endif 

HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, EXP_meconnect);