zoukankan      html  css  js  c++  java
  • 远程线程注入

    原理:

      打开目标进程以后,将要注入的动态库的路径写入这个地址空间,然后调用开启远程线程的函数,来执行LoadLibraryA或者LoadLibraryW(其实不存在LoadLibrary这个函数,他只是一个宏,如果是UNICODE环境的话会调用LoadLibraryW,否则就是LoadLibraryA)来执行这个动态库,动态库一旦被加载起来,DllMain中的DLL_PROCESS_ATTACH则会被执行,我们将要执行的代码写在DLL_PROCESS_ATTACH分支即可。之所以把LoadLibraryA(W)作为线程函数,是因为它刚好只有1个参数,在不考虑参数类型的情况下,可以认为它的原型与线程函数一样,示例如下:

    HMODULE WINAPI LoadLibraryW(
        _In_ LPCWSTR lpLibFileName
        );
    
    DWORD WINAPI ThreadProc(
        _In_ LPVOID lpParameter
        );

      注意:由于从Windows Vista 开始,微软为了增强系统的安全性,对系统服务和登录用户进行了会话(Session)隔离,系统服务属于会话0,登录的第一个用户属于会话1,之前系统服务和第一个登录用户都属于会话0。此方法并不能突破SESSION 0隔离。原因是在 CreateRemoteThread 函数中对此进行了检查,如果不在同一会话中,调用 CsrClientCallServer 为新进程进行登记的操作就会失败,这就直接导致了线程创建的失败。

    步骤:

    1. 打开目标进程
    2. 在目标进程中申请空间
    3. 将要注入的Dll路径写入刚申请的空间中
    4. 获取LoadLibrary函数地址
    5. 在目标进程中创建线程,线程回调函数就是LoadLibrary函数,回调函数参数就是要注入的Dll路径
    6. 等待线程结束
    7. 清理环境

    代码如下:

    BOOL CBiaoBai1Dlg::CreateRemoteThreadInjectDll(DWORD dwProcessId, char* pszDllFileName)
    {
    	// 1.打开目标进程
    	HANDLE hProcess = OpenProcess(
    		PROCESS_ALL_ACCESS,		// 打开权限
    		FALSE,					// 是否继承
    		dwProcessId);			// 进程PID
    	if (NULL == hProcess)
    	{
    		MessageBox("打开目标进程失败!");
    		return FALSE;
    	}
    
    	// 2.在目标进程中申请空间
    	LPVOID lpPathAddr = VirtualAllocEx(
    		hProcess,					// 目标进程句柄
    		0,							// 指定申请地址
    		strlen(pszDllFileName) + 1,	// 申请空间大小
    		MEM_RESERVE | MEM_COMMIT,	// 内存的状态
    		PAGE_READWRITE);			// 内存属性
    	if (NULL == lpPathAddr)
    	{
    		MessageBox("在目标进程中申请空间失败!");
    		CloseHandle(hProcess);
    		return FALSE;
    	}
    
    	// 3.在目标进程中写入Dll路径
    	SIZE_T dwWriteSize = 0;
    	if (FALSE == WriteProcessMemory(
    		hProcess,					// 目标进程句柄
    		lpPathAddr,					// 目标进程地址
    		pszDllFileName,					// 写入的缓冲区
    		strlen(pszDllFileName) + 1,	// 缓冲区大小
    		&dwWriteSize))				// 实际写入大小
    	{
    		MessageBox("目标进程中写入Dll路径失败!");
    		CloseHandle(hProcess);
    		return FALSE;
    	}
    
    	//获取LoadLibraryA的函数地址
    	//FARPROC可以自适应32位与64位
    	FARPROC pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    	if (NULL == pFuncProcAddr)
    	{
    		MessageBox("获取LoadLibrary函数地址失败!");
    		CloseHandle(hProcess);
    		return FALSE;
    	}
    
    	// 4.在目标进程中创建线程
    	HANDLE hThread = CreateRemoteThread(
    		hProcess,					// 目标进程句柄
    		NULL,						// 安全属性
    		NULL,						// 栈大小
    		(PTHREAD_START_ROUTINE)pFuncProcAddr,	// 回调函数
    		lpPathAddr,					// 回调函数参数
    		NULL,						// 标志
    		NULL						// 线程ID
    	);
    	if (NULL == hThread)
    	{
    		MessageBox("目标进程中创建线程失败!");
    		CloseHandle(hProcess);
    		return FALSE;
    	}
    
    	// 5.等待线程结束
    	WaitForSingleObject(hThread, -1);
    
    	DWORD code;
    	GetExitCodeThread(hThread, &code);
    	code = GetLastError();
    
    	// 6.清理环境
    	VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    	return TRUE;
    }
    

      

       

      

    直面挫折,顽强生长
  • 相关阅读:
    reset password for local admin on Windows2016 by Powershell
    解决AOP嵌套失效的问题
    在SpringBoot中使用Docker(利用dockerfile-maven-plugin插件)
    Docker启动的问题解决笔记
    SpringBoot中各配置文件的优先级及加载顺序
    【转】SpringBoot启动服务的三种方式
    【转】详解springboot-修改内置tomcat版本
    Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
    SpringCloud搭建Eureka集群
    SpringCloud警告(Eureka):EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
  • 原文地址:https://www.cnblogs.com/ndyxb/p/12751827.html
Copyright © 2011-2022 走看看