zoukankan      html  css  js  c++  java
  • 进程保护(二)

     上一次做了个双进程保护。后来试着做了DLL远程注入。可行性倒是没问题。问题在于,最理想的进程是注入在explorer里面,但是在WIN7 64位的系统注入不了。getlasterror()返回5.拒绝访问。不知道要怎么去解决。

    远程注入大致就几个步骤,首先。记得提升权限。

    DWORD EnablePrivilege (PCSTR name)
    {
    	HANDLE hToken;
    	BOOL rv;
    	//设置结构
    	TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
    	// 查找权限值
    	LookupPrivilegeValue (
    		0,
    		name,
    		&priv.Privileges[0].Luid
    		);
    	// 打开本进程Token
    	OpenProcessToken(
    		GetCurrentProcess (),
    		TOKEN_ADJUST_PRIVILEGES,
    		&hToken
    		);
    	// 提权
    	AdjustTokenPrivileges (
    		hToken,
    		FALSE,
    		&priv,
    		sizeof priv,
    		0,
    		0
    		);
    	// 返回值,错误信息,如果操作成功,则应为ERROR_SUCCESS,为O
    	rv = GetLastError();
    	// 关闭Token
    	CloseHandle (hToken);
    	return rv;
    }


    提升权限之后我们就可以开始注入了,先获取目标进程ID。之后再由ID来获得句柄。

    BOOL GetProcessIdByName(LPSTR szProcessName, LPDWORD lpPID)
    {
    	// 变量及初始化
    	STARTUPINFO st;
    	PROCESS_INFORMATION pi;
    	PROCESSENTRY32 ps;
    	HANDLE hSnapshot;
    	ZeroMemory(&st, sizeof(STARTUPINFO));
    	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    	st.cb = sizeof(STARTUPINFO);
    	ZeroMemory(&ps,sizeof(PROCESSENTRY32));
    	ps.dwSize = sizeof(PROCESSENTRY32);
    	// 遍历进程
    	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
    	if(hSnapshot == INVALID_HANDLE_VALUE)
    	{
    		return FALSE;
    	}
    
    	if(!Process32First(hSnapshot,&ps))
    	{
    		return FALSE;
    	}
    	do
    	{
    		// 比较进程名
    		if(lstrcmpi(ps.szExeFile,"explorer.exe")==0)
    		{
    			// 找到了
    			*lpPID = ps.th32ProcessID;
    			CloseHandle(hSnapshot);
    			return TRUE;
    		}
    	}
    	while(Process32Next(hSnapshot,&ps));
    	// 没有找到
    	CloseHandle(hSnapshot);
    	return FALSE;
    }


     

    上面这个函数就是由进程名而获取句柄咯。

    之后就开始正式工作。你要在人家的进程里面运行线程加载DLL模块,总要给人家一个地方去放DLL的路径不是?不然都不知道在哪里,怎么去运行。所以要计算DLL路径名的字节数。

    然后在开辟空间。开辟的空间比计算的字节数要大一。还有点要注意,DLL的路径最好是用绝对路径。总之我只用绝对路径才成功。

    开辟空间的函数

      pszLibFileRemote = (PSTR)VirtualAllocEx(
       hProcess, //申请内存所在的进程句柄
       NULL, //保留页面的内存地址;一般用NULL自动分配
       cch, //欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍
       MEM_COMMIT,
       PAGE_READWRITE
       );
    开辟空间后,就把DLL路径写进去。
     
    WriteProcessMemory(
       hProcess,//由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程
       (PVOID)pszLibFileRemote, //要写的内存首地址.再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。
       (PVOID)lpszLibName, //指向要写的DLL的路径的指针。
       cch, //要写入的字节数。
       NULL)
     
    然后在目标进程中通过函数LoadLibraryA来加载我们的DLL。LoadLibraryA函数在Kerne132.dll里面。通过显示调用,获取真实地址,然后用函数CreateRemoteThread创建远程线程,调用DLL。
     CreateRemoteThread(
       hProcess, //目标进程句柄.
       NULL, //一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结指定了线程的安全属性.
       0,//线程初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
       pfnThreadRtn, //在远程进程的地址空间中,该线程的线程函数的起始地址.
       (PVOID)pszLibFileRemote, //传给线程函数的参数.
       0, //线程的创建标志.
       NULL
       )
     
    至于怎么去获得DLL路径。
     int num;
     string x(szPath);
     num = x.length();
     x.replace(num - strlen("remote.exe"),num,"远程DLL.dll");
        LPTSTR lp=const_cast<char*>(x.c_str());
    其中remote.exe就是本进程名,远程DLL.dll就是我们的dll名。这样只要DLL和本身进程在一个目录。就能正确读取。
     
     
    BOOL LoadRometeDll(DWORD dwProcessId, LPTSTR lpszLibName)
    {
    	BOOL   bResult          = FALSE; 
    	HANDLE hProcess         = NULL;
    	HANDLE hThread          = NULL;
    	PSTR   pszLibFileRemote = NULL;
    	DWORD  cch;
    	PTHREAD_START_ROUTINE pfnThreadRtn;
    
    	__try 
    	{
    		// 获得想要注入代码的进程的句柄.
    		hProcess = OpenProcess(
    			PROCESS_ALL_ACCESS, 
    			FALSE, 
    			dwProcessId
    			);
    
    		if (hProcess == NULL)
    			__leave;
    
    		// 计算DLL路径名需要的字节数.
    		cch = 1 + lstrlen(lpszLibName);
    
    		// 在远程线程中为路径名分配空间.
    		pszLibFileRemote = (PSTR)VirtualAllocEx(
    			hProcess, //申请内存所在的进程句柄
    			NULL, //保留页面的内存地址;一般用NULL自动分配 
    			cch, //欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍 
    			MEM_COMMIT, 
    			PAGE_READWRITE
    			);
    
    		if (pszLibFileRemote == NULL) 
    			__leave;
    
    		// 将DLL的路径名复制到远程进程的内存空间.
    		if (!WriteProcessMemory(
    			hProcess,//由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程 
    			(PVOID)pszLibFileRemote, //要写的内存首地址.再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。
    			(PVOID)lpszLibName, //指向要写的DLL的路径的指针。
    			cch, //要写入的字节数。
    			NULL)) 
    			__leave;
    
    		// 获得LoadLibraryA在Kernel32.dll中的真正地址. 
    		pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(
    			GetModuleHandle(TEXT("Kernel32")), TEXT("LoadLibraryA"));
    
    		if (pfnThreadRtn == NULL) 
    			__leave;
    
    		// 创建远程线程,并通过远程线程调用用户的DLL文件. 
    		hThread = CreateRemoteThread(
    			hProcess, //目标进程句柄. 
    			NULL, //一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结指定了线程的安全属性.
    			0,//线程初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
    			pfnThreadRtn, //在远程进程的地址空间中,该线程的线程函数的起始地址.
    			(PVOID)pszLibFileRemote, //传给线程函数的参数.
    			0, //线程的创建标志.
    			NULL
    			);
    		
    		if (hThread == NULL) 
    		{
    					int a = GetLastError();
    					cout<<"error = "<<a<<endl;
    			__leave;
    		}
    
    		// 等待远程线程终止.
    		WaitForSingleObject(hThread, INFINITE);
    		bResult = TRUE; 
    	}
    	__finally 
    	{ 
    		// 关闭句柄. 
    		if (pszLibFileRemote != NULL) 
    			VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);
    		if (hThread  != NULL) 
    			CloseHandle(hThread);
    		if (hProcess != NULL) 
    			CloseHandle(hProcess);
    	}
    	return bResult;
    }

    这是效果图。。可是看出,对话框是由QQ弹出。
    DLL代码就不贴了。主要DLL里面要写线程,不要直接写函数。否则注入的进程直接会挂掉。
     
     
    本文代码参考自《精通Windows.API-函数、接口、编程实例》
     
  • 相关阅读:
    python DB.fetchall()--获取数据库所有记录列表
    pybot/robot命令参数说明【dos下执行命令pybot.bat --help查看】
    win7 dos命令窗口内容显示不全解决办法--将命令执行结果输出到一个文件中
    【python cookbook】【数据结构与算法】2 从任意长度的可迭代对象中分解元素
    【python cookbook】【数据结构与算法】1将序列分解为单独的变量
    wxPython_Phoenix在线安装
    Python 进阶(五)定制类
    Python 进阶(四)类的继承
    墓型价格分析表
    用碑情况统计
  • 原文地址:https://www.cnblogs.com/zkkkkkky/p/4423001.html
Copyright © 2011-2022 走看看