进程保护(二)

来源:互联网 发布:全自动通话录音软件 编辑:程序博客网 时间:2024/05/21 17:09

 上一次做了个双进程保护。后来试着做了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);// 打开本进程TokenOpenProcessToken(GetCurrentProcess (),TOKEN_ADJUST_PRIVILEGES,&hToken);// 提权AdjustTokenPrivileges (hToken,FALSE,&priv,sizeof priv,0,0);// 返回值,错误信息,如果操作成功,则应为ERROR_SUCCESS,为Orv = GetLastError();// 关闭TokenCloseHandle (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-函数、接口、编程实例》
 
0 0
原创粉丝点击