如何检测是否调用了SendMessage()API

时间:2011-10-13 07:08:22

标签: winapi detection sendmessage

我有第一个使用大量SendMessage() API的程序(用Win32 API编写);它已经完成并且有效。 问题是我想编写第二个可以检测到SendMessage()在第一个程序中被调用的文件,如果可能的话,捕获它的数据(HANDLE, WPARAM, LPARAM...

有没有人知道这个问题的解决方案?

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()获取数据?

1 个答案:

答案 0 :(得分:2)

您需要使用CreateRemoteThread将DLL注入第一个应用程序。在DLL的entrymain中,您编写代码以将对SendMessage的外部调用重新映射到您自己的SendMessageX,然后SendMessageX可以在调用SendMessage时告诉您的其他应用程序,然后将原始调用传递给WIN32子系统。