我试图在 Windows .exe 进程中注入 dll,例如 notepad.exe,注入工作正常,但是当 dll 已经注入到进程中并且我尝试调用导出的函数时,它告诉我没有这样的函数dll 中的函数。
注射器
#include <Windows.h>
#include <stdio.h>
#include <cassert>
#include <TlHelp32.h> // Para enumerar módulos en el proceso remoto
// Función para obtener el handle del módulo cargado remotamente
HMODULE GetRemoteModuleHandle(HANDLE hProcess, const wchar_t* moduleName) {
HMODULE hModule = nullptr;
MODULEENTRY32 me = { sizeof(me) };
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(hProcess));
if (hSnapshot == INVALID_HANDLE_VALUE)
return nullptr;
if (Module32First(hSnapshot, &me)) {
do {
if (_wcsicmp(me.szModule, moduleName) == 0) {
hModule = me.hModule;
break;
}
} while (Module32Next(hSnapshot, &me));
}
CloseHandle(hSnapshot);
return hModule;
}
int main(int argc, const char* argv[]) {
if (argc < 3) {
printf("Usage: Inyector <pid> <dllPath>\n");
return 0;
}
auto pid = atoi(argv[1]);
// Abrir el proceso objetivo
HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, pid);
if (!hProcess) {
printf("Error opening process (%u)\n", GetLastError());
return 1;
}
// Reservar memoria en el proceso objetivo
auto p = VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
assert(p);
// Escribir la ruta de la DLL en la memoria del proceso
WriteProcessMemory(hProcess, p, argv[2], strlen(argv[2]) + 1, nullptr);
// Crear un hilo remoto que cargue la DLL usando LoadLibraryA
auto hThread = CreateRemoteThread(hProcess, nullptr, 0,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA"), p, 0, nullptr);
assert(hThread);
WaitForSingleObject(hThread, INFINITE);
// Obtener el handle del módulo cargado en el proceso remoto
HMODULE remoteModule = GetRemoteModuleHandle(hProcess, L"mydll.dll");
if (!remoteModule) {
printf("Error: No se pudo encontrar el módulo remoto\n");
return 1;
}
// Calcular la dirección de la función exportada en el proceso remoto
auto funcAddr = (LPVOID)GetProcAddress(GetModuleHandle(L"mydll.dll"), "MyFunc");
if (!funcAddr) {
printf("Error: No se pudo encontrar la función 'MyFunc'\n");
return 1;
}
// Ajustar la dirección de la función para el proceso remoto
uintptr_t remoteFuncAddr = (uintptr_t)funcAddr - (uintptr_t)GetModuleHandle(L"mydll.dll") + (uintptr_t)remoteModule;
// Crear un hilo remoto para llamar a MyFunc
auto hFuncThread = CreateRemoteThread(hProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)remoteFuncAddr, nullptr, 0, nullptr);
if (!hFuncThread) {
printf("Error: No se pudo ejecutar la función remota (%u)\n", GetLastError());
}
else {
printf("Función remota ejecutada con éxito.\n");
}
// Limpiar
CloseHandle(hFuncThread);
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
DLL
#include <windows.h>
// Exportar la función
extern "C" __declspec(dllexport) void MyFunc(long parm1) {
for (int i = 1; i <= 10; i++) {
// Mostrar un cuadro de mensaje en cada iteración
MessageBox(
NULL, // Ventana padre (NULL para ninguna)
L"Este es un mensaje de prueba", // Texto del mensaje
L"Iteración del MessageBox", // Título del cuadro de mensaje
MB_OK | MB_ICONINFORMATION // Botón OK con un ícono de información
);
}
}
// Función opcional para el punto de entrada de la DLL
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
可能发生什么事?
仔细检查 DLL 以确保函数确实按照您期望的方式导出。它可能会导出为
"_MyFunc“
甚至 "_MyFunc@4"
,具体取决于您的编译器设置。
但是,即使您可以实现此功能,您导出的 DLL 函数也不符合
CreateRemoteThread()
所期望的签名,因此以这种方式调用 DLL 函数是未定义的行为。 将签名更改为:
extern "C" __declspec(dllexport) DWORD WINAPI MyFunc(LPVOID parm1) {
...
return 0;
}
然后使用
.def
文件按照您想要的方式导出函数。