阅读 292

一文带你实现远程线程注入和卸载

1. 原理

主要通过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;

}
复制代码
文章分类
后端
文章标签