Então, estou aprendendo C depois de anos de C# e imaginei que um bom projeto inicial seria algo um pouco mais simples.
Estou tentando invocar uma MessageBox em um aplicativo WPF em branco e parece que tudo funcionaria, mas por algum motivo não estou obtendo uma MessageBox.
Tanto o WpfApp quanto o aplicativo que criei são compilados em versões x64, então não vejo por que haveria problemas de arquitetura.
A saída de depuração também parece boa.
Tentei executar ambos os aplicativos com privilégios de administrador. Tentei invocar em diferentes aplicativos, como o Notepad (versão de 32 e 64 bits), assim como a Calculadora.
Process ID for WpfApp1.exe found: 948
Target process found. PID: 948
Opened handle to process.
Handle to user32.dll loaded successfully.
Address of MessageBoxA: 00007ffc67fc8b70
Allocated memory at remote address: 00000262a8500000
Successfully wrote message to remote memory.
Remote thread created successfully.
Remote thread completed.
Mas acho que há algo errado aqui?
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <unistd.h>
DWORD GetPID(const char *processName);
int main(void) {
DWORD processId = GetPID("WpfApp1.exe");
if (!processId) {
printf("Process not found\n");
fflush(stdout);
return 1;
}
printf("Target process found. PID: %lu\n", processId);
fflush(stdout);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if (!hProcess) {
printf("Failed to open process. Error code: %lu\n", GetLastError());
fflush(stdout);
return 1;
}
printf("Opened handle to process.\n");
fflush(stdout);
// Explicitly load user32.dll
HMODULE hUser32 = LoadLibrary("user32.dll");
if (!hUser32) {
printf("Failed to load user32.dll. Error code: %lu\n", GetLastError());
fflush(stdout);
CloseHandle(hProcess);
return 1;
}
printf("Handle to user32.dll loaded successfully.\n");
fflush(stdout);
LPVOID msgBoxAddress = (LPVOID)GetProcAddress(hUser32, "MessageBoxA");
if (!msgBoxAddress) {
printf("Failed to find address of MessageBoxA. Error code: %lu\n", GetLastError());
fflush(stdout);
FreeLibrary(hUser32);
CloseHandle(hProcess);
return 1;
}
printf("Address of MessageBoxA: %p\n", msgBoxAddress);
fflush(stdout);
LPVOID remoteString = VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!remoteString) {
printf("Failed to allocate memory in target process. Error code: %lu\n", GetLastError());
fflush(stdout);
FreeLibrary(hUser32);
CloseHandle(hProcess);
return 1;
}
printf("Allocated memory at remote address: %p\n", remoteString);
fflush(stdout);
if (!WriteProcessMemory(hProcess, remoteString, "Hello World!", 13, NULL)) {
printf("Failed to write to remote memory. Error code: %lu\n", GetLastError());
fflush(stdout);
VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
FreeLibrary(hUser32);
CloseHandle(hProcess);
return 1;
}
printf("Successfully wrote message to remote memory.\n");
fflush(stdout);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)msgBoxAddress, remoteString, 0, NULL);
if (!hThread) {
printf("Failed to create remote thread. Error code: %lu\n", GetLastError());
fflush(stdout);
VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
FreeLibrary(hUser32);
CloseHandle(hProcess);
return 1;
}
printf("Remote thread created successfully.\n");
fflush(stdout);
WaitForSingleObject(hThread, INFINITE);
printf("Remote thread completed.\n");
fflush(stdout);
VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
FreeLibrary(hUser32);
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
DWORD GetPID(const char *processName) {
PROCESSENTRY32 processEntry;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
printf("Failed to create snapshot. Error code: %lu\n", GetLastError());
fflush(stdout);
return 0;
}
processEntry.dwSize = sizeof(processEntry);
if (Process32First(hSnapshot, &processEntry)) {
do {
if (strcmp(processEntry.szExeFile, processName) == 0) {
DWORD pid = processEntry.th32ProcessID;
CloseHandle(hSnapshot);
printf("Process ID for %s found: %lu\n", processName, pid);
fflush(stdout);
return pid;
}
} while (Process32Next(hSnapshot, &processEntry));
}
printf("Failed to find process: %s\n", processName);
fflush(stdout);
CloseHandle(hSnapshot);
return 0;
}
Isso também parece bastante código comparado a vários artigos que li online.