CreateRemoteThread函数用于为指定进程创建线程,该线程将会在其他进程的地址空间中执行,访问其他进程的资源:
HANDLE WINAPI CreateRemoteThread(
  __in   HANDLE hProcess, //需要为其创建线程的目标进程句柄,该目标进程需要具有如下权限:
                              //PROCESS_CREATE_THREAD、PROCESS_QUERY_INFORMATION、
                              //PROCESS_VM_OPERATION、PROCESS_VM_WRITE、PROCESS_VM_READ
  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向安全描述符的指针,NULL为默认
  __in   SIZE_T dwStackSize, //线程堆栈大小,0表示使用默认值
  __in   LPTHREAD_START_ROUTINE lpStartAddress, //函数指针,指向存在与目标进程中的线程函数
  __in   LPVOID lpParameter, //传给线程函数的参数
  __in   DWORD dwCreationFlags, //0---线程创建后立即运行;
//CREATE_SUSPENDED---线程创建后挂起,知道ResumeThread函数调用才开始运行;
//STACK_SIZE_PARAM_IS_A_RESERVATION---dwStackSize参数指定初始保留的堆栈大小
//不指定该标志时,dwStackSize表示提交的大小(commit size)
  __out  LPDWORD lpThreadId //指向存放线程ID的缓冲区的指针,为NULL表示不保存线程ID
);
返回值:
成功时,返回新线程的句柄;
失败时,返回NULL。
 
WriteProcessMemory函数用于将数据写入到目标进程的虚拟地址空间中:
BOOL WINAPI WriteProcessMemory(
  __in   HANDLE hProcess, //目标进程句柄,操作进程需要有目标进程的PROCESS_VM_WRITE和
                            //PROCESS_VM_OPERATION权限
  __in   LPVOID lpBaseAddress, //写入数据的地址,目标进程虚拟地址空间中的地址
  __in   LPCVOID lpBuffer, //指向需要写入的数据
  __in   SIZE_T nSize, //写入数据的字节大小
  __out  SIZE_T *lpNumberOfBytesWritten //用于保存实际写入的数据的大小
);
返回值:
成功时,返回非零值;
失败时,返回零值。
 
实例代码:直接将远程进程地址空间中的API函数LoadLibraryW作为线程函数调用:
#include <windows.h>
 
/***********************************************************
* 功能:通过创建远程线程给其他进程加载DLL
* 参数:dwProcessId--目标进程PID
*       lpszLibName--DLL的路径
* 返回值:是否成功
***********************************************************/
BOOL LoadRemoteDll(DWORD dwProcessId, LPTSTR lpszLibName)
{
    BOOL bResult = FALSE;
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    PTSTR pszLibFileRemote = NULL;
    DWORD cch;
    PTHREAD_START_ROUTINE pfnThreadRtn;
    
    __try
    {
        //获得想要注入代码的进程的句柄
        hProcess = OpenProcess(PROCESS_ALL_ACCESS,
                              FALSE, dwProcessId);
        if(hProcess == NULL)
        {
            __leave;            
        }     
        //计算DLL路径名需要的字节数
        cch = lstrlen(lpszLibName) + 1;
        //在远程线程中为路径名分配空间
        pszLibFileRemote = (PTSTR)VirtualAllocEx(
                           hProcess, NULL, cch,
                           MEM_COMMIT, PAGE_READWRITE);
        if(pszLibFileRemote == NULL)
        {
            __leave;                    
        }
        
        //将DLL的路径名复制到远程进程的内存空间
        if(!WriteProcessMemory(hProcess, 
                  (PVOID)pszLibFileRemote,
                  (PVOID)lpszLibName,
                  cch,
                  NULL))
        {
            __leave;          
        } 
        
        //获得LoadLibrary在Kernel32.dll中的真实地址
        pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(
                     GetModuleHandle(TEXT("Kernel32")), TEXT("LoadLibraryW"));
        if(pfnThreadRtn == NULL)
        {
            __leave;                
        }
        
        //创建远程线程,并通过远程线程调用用户的DLL文件
        hThread = CreateRemoteThread(hProcess, NULL,
                0, pfnThreadRtn, (PVOID)pszLibFileRemote,
                0, NULL);
        if(hThread == NULL)
        {
            __leave;           
        } 
        
        //等待远程线程终止
        WaitForSingleObject(hThread, INFINITE);
        bResult = TRUE; 
    }     
    __finally
    {
        //关闭句柄
        if(pszLibFileRemote != NULL)
        {
            VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);
            pszLibFileRemote = NULL;                    
        }         
        if(hThread != NULL)
        {
            CloseHandle(hThread);
            hThread = NULL;
        }
        if(hProcess != NULL)
        {
            CloseHandle(hProcess);
            hProcess = NULL;            
        }
    }
    return bResult;
}