Как определить, вызван ли API SendMessage () - PullRequest
0 голосов
/ 13 октября 2011

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

1 Ответ

2 голосов
/ 13 октября 2011

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

...