Код DLL будет автоматически передаваться различным процессам. Только для оптимизации вы должны выбрать хороший базовый адрес DLL (см. http://msdn.microsoft.com/en-US/library/f7f5138s.aspx).
Для обмена данными между процессами вы можете, например, использовать объекты общей памяти или просто поместить некоторые переменные, которые вам нужны, в раздел, который вы пометили как общий (см. http://support.microsoft.com/kb/100634 и http://msdn.microsoft.com/en-us/library/h90dkhs0.aspx для подробности). Чтобы пометить раздел «.SHAREDSECTIONNAME» как общедоступный, вы можете использовать
#pragma comment(linker, "/section:.SHAREDSECTIONNAME,RWS")
Чтобы не было конфликтов при записи / чтении из общей памяти, вы должны использовать именованное событие или мьютекс точно так же, как и во всех других случаях многопроцессорной связи.
ОБНОВЛЕНО на основе комментария: если вы создаете дочерний процесс самостоятельно, вы получаете дескриптор дочернего процесса с полными правами. Таким образом, у вас достаточно прав для заражения DLL в отношении CreateRemoteThread
API. Вот рабочий код на C, который запускает CMD.EXE и внедряет MyTest.dll в адресное пространство:
#include <Windows.h>
int main()
{
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi = {0};
TCHAR szCommandLine[4096] = TEXT("CMD.EXE");
BOOL bIsSuccess;
DWORD dwStatus;
LPCTSTR pszLibFile = TEXT("C:\\Oleg\\MyTest\\Release\\MyTest.dll");
PTSTR pszLibFileRemote = NULL;
HANDLE hThread = NULL;
int cb;
HMODULE hModule = NULL;
bIsSuccess = CreateProcess (NULL, szCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
// Calculate the number of bytes needed for the DLL's pathname
cb = (1 + lstrlen(pszLibFile)) * sizeof(TCHAR);
__try {
PTHREAD_START_ROUTINE pfnThreadRtn;
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PTSTR) VirtualAllocEx (pi.hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave; // error
// Copy the DLL's pathname to the remote process's address space
if (!WriteProcessMemory (pi.hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
// Real address of Kernel32.dll in dwProcessId and in our Process MUST be the same !!!
// Remote Process MUST have Kernel32.dll loaded (SMSSS.EXE and System havn't)!!!
#ifdef UNICODE
pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress (GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
#else
pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress (GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");
#endif
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread (pi.hProcess, NULL, 0, pfnThreadRtn, (LPVOID)pszLibFileRemote, 0, NULL);
if (hThread == NULL) __leave;
dwStatus = ResumeThread (pi.hThread);
// Wait for the remote thread to terminate
if (WaitForSingleObject (hThread, INFINITE) != WAIT_OBJECT_0) __leave;
GetExitCodeThread (hThread, (PDWORD)&hModule);
// hModule is the address in the destination process (CMD.EXE)
// of the injected DLL
// You can verify that it is really loaded for example with respect of
// Process Explorer (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx)
}
__finally {
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
bIsSuccess = VirtualFreeEx (pi.hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
bIsSuccess = CloseHandle (hThread);
if (pi.hProcess != NULL)
bIsSuccess = CloseHandle (pi.hProcess);
if (pi.hThread != NULL)
bIsSuccess = CloseHandle (pi.hThread);
}
return 0;
}