1. 调整特权级别

使用CreateRemoteThread植入DLL,需要用OpenProcess打开进程 传递参数为 PROCESS_ALL_ACCESS 使用OpenProcess需要拥有调试特权,方法如下:

1)使用OpenProcessToken函数打开当前进程的访问令牌,得到句柄hToken
BOOL OpenProcessToken(
in HANDLE ProcessHandle, //要修改访问权限的进程句柄 in DWORD DesiredAccess, //指定你要进行的操作类型
__out PHANDLE TokenHandle //返回的访问令牌指针
);

2)使用 LookupPrivilegeValue 函数取得指定特权级别的 LUID,唯一标识
BOOL WINAPI LookupPrivilegeValue(
in_opt LPCTSTR lpSystemName, //表示索要查看的系统,本地为NULL in LPCTSTR lpName, //指定特权的名称
__out PLUID lpLuid //特权名称的信息,是一个结构体
);

3)AdjustTokenPrivileges函数调整访问令牌的特权级别(特权有效或无效)
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, //包含特权的句柄
BOOL DisableAllPrivileges, //禁用所有权限标志
PTOKEN_PRIVILEGES NewState, //新特权信息的指针(结构体)
DWORD BufferLength, //缓冲数据大小,以字节为单位的PreviousState的缓存区(sizeof)
PTOKEN_PRIVILEGES PreviousState , //接收被改变特权当前状态的Buffer
PDWORD ReturnLength //接收PreviousState缓存区要求的大小
);

4)关闭OpenProcessToken打开的进程访问令牌句柄

::CloseHandle(hToken);

2. 申请内存空间

LPVOID VirtualAllocEx(
HANDLE hPreocess,     //目标进程句柄
LPVOID lpAddress,        //指定为NULL表示由函数自行在某个最方便的位置申请内存
SIZE_T dwSize,               //函数应该分配的地址范围
DWORD flAllocation Type,  //如何分配地址,MEM_COMMIT表示为指定地址空间提交物理内存
DWORD flProtect         //指定保护类型,PAGE_READWRITE表示读写
);

使用WriteProcessMemory函数写内存
写入文件的代码
//在目标进程中申请空间,存放字符串pszDllName, 作为远程线程的参数
Int cbSize = (strlen(m_szDllName)+1);
LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, NULL, cbSize, MEM_COMMIT, PAGE_READWRITE);
::WriteProcessMemory(hProcess, lpRemoteDllName, m_szDllName, cbSize, NULL);

3. 取得 LoadLibraryA函数的地址,作为远程线程函数启动

HMODULE hModule=::GetModuleHandle("kernel32.dll");
    LPTHREAD_START_ROUTINE pfnStartRoutine = 
            (LPTHREAD_START_ROUTINE)::GetProcAddress(hModule, "LoadLibraryA");

4. 启动远程线程

HANDLE hRemoteThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnStartRoutine, lpRemoteDllName, 0, NULL);

5. 等待目标线程运行结束,即LoadLibraryA函数返回

::WaitForSingleObject(hRemoteThread, INFINITE);

::CloseHandle(hRemoteThread);
::CloseHandle(hProcess);