Как определить, вызывается ли API SendMessage()

У меня есть первая программа (написанная на Win32 API), использующая много SendMessage() 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(), если он вызывается?


person Pete Houston    schedule 13.10.2011    source источник
comment
Можете ли вы изменить первое приложение? Если да, просто создайте глобальное событие и запустите его в первом приложении, во втором событии открытия приложения и WaitForXXXObject.   -  person seva titov    schedule 13.10.2011
comment
Предполагая, что первое приложение защищено, нет исходного кода!   -  person Pete Houston    schedule 13.10.2011


Ответы (1)


Вам нужно использовать CreateRemoteThread для внедрения DLL в первое приложение. В файле entrymain вы должны написать код для переназначения внешнего вызова SendMessage на ваш собственный SendMessageX, который затем может сообщить вашему другому приложению, когда вызывается SendMessage, а затем передать исходный вызов подсистеме WIN32.

person Mahmoud Al-Qudsi    schedule 13.10.2011
comment
не могли бы вы предоставить образец? У меня нет большого представления об этом. - person Pete Houston; 13.10.2011
comment
@xjaphx выполните поиск в Интернете по ключевым словам, которые дает этот ответ. - person David Heffernan; 13.10.2011
comment
получилось! так как я могу переназначить внешний вызов на SendMessage()? - person Pete Houston; 13.10.2011