2011-10-13 71 views
0

我有第一個使用很多SendMessage() API的程序(用Win32 API編寫)它已經完成並且工作。 問題是我想寫的第二個可檢測SendMessage()是所謂的第一個程序,如果可能,捕獲它的數據(HANDLE, WPARAM, LPARAM...如何檢測是否調用SendMessage()API

有誰知道這個問題的解決方案?

DLLStudy.dll

編輯:沒關係,這是我到目前爲止所。

#include <windows.h> 

#define SIZE 6 

typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT); 
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT); 

void BeginRedirect(LPVOID); 

pMessageBoxW pOrigMBAddress = NULL; 
BYTE oldBytes[SIZE] = {0}; 
BYTE JMP[SIZE] = {0}; 
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE; 

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) 
{ 
    switch(Reason) 
    { 
    case DLL_PROCESS_ATTACH: 
     MessageBoxA(NULL, "Test", "OK", MB_OK); 
     pOrigMBAddress = (pMessageBoxW) 
      GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW"); 
     if(pOrigMBAddress != NULL) 
      BeginRedirect(MyMessageBoxW);  
     break; 
    case DLL_PROCESS_DETACH: 
     memcpy(pOrigMBAddress, oldBytes, SIZE); 
    case DLL_THREAD_ATTACH: 
    case DLL_THREAD_DETACH: 
     break; 
    } 
    return TRUE; 
} 

void BeginRedirect(LPVOID newFunction) 
{ 
    BYTE tempJMP[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3}; 
    memcpy(JMP, tempJMP, SIZE); 
    DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5); 
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, 
        PAGE_EXECUTE_READWRITE, &oldProtect); 
    memcpy(oldBytes, pOrigMBAddress, SIZE); 
    memcpy(&JMP[1], &JMPSize, 4); 
    memcpy(pOrigMBAddress, JMP, SIZE); 
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL); 
} 

int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType) 
{ 
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL); 
    memcpy(pOrigMBAddress, oldBytes, SIZE); 
    int retValue = MessageBoxW(hWnd, lpText, lpCaption, uiType); 
    memcpy(pOrigMBAddress, JMP, SIZE); 
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL); 
    return retValue; 
} 

Injector.cpp

#include <windows.h> 
#include <iostream> 

using namespace std; 

char const Path[]="DLLStudy.dll"; 

int main(int argc, char* argv) 
{ 
    HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread; 
    DWORD PID; 

    hWnd = FindWindow(0,"Notepad"); 
    GetWindowThreadProcessId((HWND)hWnd, &PID); 

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID); 

    AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
    WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0); 
    hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0); 

    WaitForSingleObject(hRemoteThread, INFINITE); 

    VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT); 
    CloseHandle(hProcess); 
} 

編輯2:嗯,我已經成功地使其發揮作用。那麼如何從SendMessage()獲取數據?

+0

你可以修改第一個應用程序嗎?如果是,只需創建一個全局事件並在第一個應用程序,第二個應用程序打開事件和WaitForXXXObject中觸發它。 –

+0

假設第一個應用程序是受保護的,沒有源代碼! –

回答

1

您需要使用CreateRemoteThread將DLL注入第一個應用程序。在DLL的entrymain中,編寫代碼將外部調用重新映射到SendMessage到您自己的SendMessageX,然後可以告訴您的其他應用程序何時調用SendMessage,然後將原始調用傳遞給WIN32子系統。

+0

您能否提供樣品?我對此沒有太多的想法。 –

+0

@xjaphx使用此答案提供的關鍵字進行網絡搜索。 –

+0

任何想法爲什麼上面的代碼不工作? –

相關問題