- 原理
主要通过API:CreateRemoteThread 来进行远程线程注入
2.远程线程注入Dll的步骤
1.通过进程Id打开指定的进程
2.在指定的进程,分配一段大小为要导入的dll文件名长度的一段内存空间,将dll的文件名写入到分配的内存中。
3.获取目的进程中的loadLibrary的函数地址。
4.创建远程线程,通过上一步获得的loadlibrary函数进行dll导入。
5.释放内存,卸载dll。
3.代码远程注入注意点
1.不能调用除kernel32和user32之外动态库中的api函数。
2.不能使用static字符串
3. 去掉编译器的/GZ编译选项。这个选项是默认的,不然注入进去被注入的程序会崩溃。
4. 要么把ThreadFunc和AfterThreadFunc声明为static,要么关闭编译器的“增量连接(incremental linking)”(看附录C)。
5. ThreadFunc中的局部变量总大小必须小于4k字节。注意,当degug编译时,这4k中大约有10个字节会被事先占用。
(注入64位的程序,那么也需要64位的dll,主要用的函数:NtCreateThreadEx)
4.代码实现
//提升权限
BOOL cRemoteThreadInject::grantPriviledge(char* priName)
{
if(NULL == priName)
{
return FALSE;
}
TOKEN_PRIVILEGES tokenPriviledge, oldPriviledge;
DWORD dwRetLength = sizeof(oldPriviledge);
HANDLE tokenHandle = NULL;
LUID uId;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &tokenHandle))
{
if (ERROR_NO_TOKEN != GetLastError())
{
return FALSE;
}
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenHandle))
{
return FALSE;
}
}
if (!LookupPrivilegeValue(NULL, priName, &uId))
{
CloseHandle(tokenHandle);
tokenHandle = NULL;
return FALSE;
}
tokenPriviledge.PrivilegeCount = 1;
tokenPriviledge.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tokenPriviledge.Privileges[0].Luid = uId;
if (!AdjustTokenPrivileges(tokenHandle, FALSE, &tokenPriviledge, sizeof(TOKEN_PRIVILEGES), &oldPriviledge, &dwRetLength))
{
CloseHandle(tokenHandle);
tokenHandle = NULL;
return FALSE;
}
return TRUE;
}
/*
函数功能:通过进程名称获取进程PID
参数1:进程名称
参数2:返回的进程pid
*/
BOOL cRemoteThreadInject::GetProcessId(IN char* processName, OUT DWORD* processId)
{
if(NULL == processName)
{
return FALSE;
}
HANDLE handle = NULL;
PROCESSENTRY32 processTry32 ={0};
processTry32.dwSize = sizeof(PROCESSENTRY32);
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(INVALID_HANDLE_VALUE == handle)
{
return FALSE;
}
Process32First(handle, &processTry32);
do{
if(lstrcmpi(processTry32.szExeFile, processName) == 0)
{
*processId = processTry32.th32ProcessID;
break;
}
}while(Process32Next(handle, &processTry32));
CloseHandle(handle);
handle = NULL;
if(0 == *processId)
{
return FALSE;
}
return TRUE;
}
/*
功能:注入dll文件到进程
参数1:进程的名称
参数2:注入dll的路径
*/
BOOL cRemoteThreadInject::injectDll(char* processName, char* dllPath)
{
if((NULL == processName) || (NULL == dllPath))
{
return FALSE;
}
DWORD processId = 0;
GetProcessId(processName, &processId);
if(processId <= 0)
{
return FALSE;
}
grantPriviledge("SE_DEBUG_NAME");
HANDLE handle = NULL;
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if(NULL == handle)
{
return FALSE;
}
int dllPathLen = sizeof(dllPath) +1;
PVOID data = VirtualAllocEx(handle, NULL, dllPathLen, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(NULL == data)
{
CloseHandle(handle);
handle = NULL;
return FALSE;
}
SIZE_T RetLength = 0;
BOOL bWriteMem = WriteProcessMemory(handle, data, dllPath, strlen(dllPath)+1, &RetLength);
if(FALSE == bWriteMem)
{
return FALSE;
}
LPTHREAD_START_ROUTINE LoadLibraryAddress = NULL;
#ifdef _UNICODE
HMODULE Kernel32Module = GetModuleHandle(L"Kernel32");
LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryW");
#else
HMODULE Kernel32Module = GetModuleHandle(_T("Kernel32"));
LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryA");
#endif
HANDLE Threadhandle = CreateRemoteThread(handle, NULL, 0, LoadLibraryAddress, data, 0, NULL);
if (NULL == Threadhandle)
{
CloseHandle(handle);
handle = NULL;
return FALSE;
}
if (WaitForSingleObject(Threadhandle, INFINITE) == WAIT_FAILED)
{
return FALSE;
}
CloseHandle(handle);
handle = NULL;
CloseHandle(Threadhandle);
Threadhandle = NULL;
return TRUE;
}
/*
函数功能:卸载注入到进程后的dll
参数1:进程的名称
参数2:要卸载的dll
*/
BOOL cRemoteThreadInject::unitInjectDll(char* processName, char* dllPath)
{
if((NULL == processName) || (NULL == dllPath))
{
return FALSE;
}
DWORD processId = 0;
GetProcessId(processName, &processId);
if(processId <= 0)
{
return FALSE;
}
BOOL bMore = FALSE;
BOOL bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = {sizeof(me)};
LPTHREAD_START_ROUTINE pThreadProc;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
bMore = Module32First(hSnapshot, &me);
for(; bMore; bMore = Module32Next(hSnapshot, &me))
{
if(!_tcsicmp(me.szModule, dllPath) || !_tcsicmp(me.szExePath, dllPath))
{
bFound = TRUE;
break;
}
}
if(!bFound)
{
CloseHandle(hSnapshot);
return FALSE;
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if(NULL == hProcess)
{
return FALSE;
}
hModule = GetModuleHandle("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hProcess);
hProcess = NULL;
CloseHandle(hThread);
hThread = NULL;
CloseHandle(hSnapshot);
hSnapshot = NULL;
return TRUE;
}