1 #include<stdio.h> 2 #include<Windows.h> 3 #include<TlHelp32.h> 4 5 6 //typedef unsigned long DWORD; 7 //typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR; 8 //typedef void *HANDLE; 9 10 DWORD getProcessHandle(LPCTSTR lpProcessName)//根据进程名查找进程PID 11 { 12 DWORD dwRet=0; 13 HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);/*CreateToolhelp32Snapshot函数为指定的进程、 14 进程使用的堆[HEAP]、模块[MODULE]、 15 线程[THREAD])建立一个快照[snapshot]。*/ 16 if(hSnapShot==INVALID_HANDLE_VALUE) 17 { 18 //句柄无效 19 printf(" 获得PID=%s的进程快照失败%d",lpProcessName,GetLastError()); 20 return dwRet; 21 } 22 23 //快照抓取成功 24 PROCESSENTRY32 pe32;//声明进程入口对象 25 pe32.dwSize=sizeof(PROCESSENTRY32 );//填充进程入口大小 26 Process32First(hSnapShot,&pe32);//遍历进程列表 27 do 28 { 29 if(!lstrcmp(pe32.szExeFile,lpProcessName)) 30 { 31 dwRet=pe32.th32ProcessID; 32 break; 33 } 34 } 35 while(Process32Next(hSnapShot,&pe32)); 36 CloseHandle(hSnapShot); 37 return dwRet; 38 39 } 40 41 42 void EnableDebugPriv() 43 { 44 HANDLE hToken; // 进程访问令牌的句柄 45 LUID luid; // 用于存储调试权对应的局local unique identifier 46 TOKEN_PRIVILEGES tkp; // 要设置的权限 47 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 48 // 获取访问令牌 49 LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); // 获得调试权的luid 50 tkp.PrivilegeCount = 1; // 设置调试权 51 tkp.Privileges[0].Luid = luid; 52 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 53 AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL); // 使进程拥有调试权 54 CloseHandle(hToken); 55 } 56 57 int main(int argc,char *argv[]) 58 { 59 DWORD dwpid=getProcessHandle("calc.exe"); 60 LPCSTR lpDllName="D:\WorkProject\C++\20160314\DLLImport\Debug\dllDemo.dll"; 61 EnableDebugPriv();//权限提升 62 HANDLE hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,dwpid);//获得要注入进程的句柄 63 64 if(hProcess==NULL) 65 { 66 printf(" 获取进程句柄错误%d",GetLastError()); 67 return -1; 68 } 69 70 DWORD dwSize=strlen(lpDllName)+1; 71 DWORD dwHasWrite; 72 LPVOID lpRemoteBuf=VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);//在远程空间分配地址 73 if(WriteProcessMemory(hProcess,lpRemoteBuf,lpDllName,dwSize,&dwHasWrite))//写入内存函数执行成功返回非零 74 { 75 if(dwHasWrite!=dwSize) 76 { 77 //写入内存不完整,释放内存 78 VirtualFreeEx(hProcess,lpRemoteBuf,dwSize,MEM_COMMIT); 79 CloseHandle(hProcess); 80 return -1; 81 } 82 } 83 else 84 { 85 printf(" 写入远程进程内存空间出错%d",GetLastError()); 86 CloseHandle(hProcess); 87 return -1; 88 } 89 //写入成功 90 DWORD dwNewThreadId; 91 LPVOID lpLoadDll=LoadLibraryA; 92 //将LoadLIbraryA作为线程函数,参数为Dll,创建新线程 93 HANDLE hNewRemoteThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpLoadDll,lpRemoteBuf,0,&dwNewThreadId); 94 //HANDLE hNewRemoteThread= 95 if(hNewRemoteThread==NULL) 96 { 97 printf(" 建立远程线程失败%d",GetLastError()); 98 CloseHandle(hProcess); 99 return -1; 100 } 101 //等待对象句柄返回 102 WaitForSingleObject(hNewRemoteThread,INFINITE); 103 104 CloseHandle(hNewRemoteThread); 105 106 107 //准备卸载之前注入的Dll 108 DWORD dwHandle,dwID; 109 LPVOID pFunc = GetModuleHandleA;//获得在远程线程中被注入的Dll的句柄 110 HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,lpRemoteBuf,0,&dwID); 111 WaitForSingleObject(hThread,INFINITE); 112 GetExitCodeThread(hThread,&dwHandle);//线程的结束码即为Dll模块儿的句柄 113 CloseHandle(hThread); 114 pFunc = FreeLibrary; 115 hThread = CreateRemoteThread(hThread,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,(LPVOID)dwHandle,0,&dwID); //将FreeLibraryA注入到远程线程中去卸载Dll 116 WaitForSingleObject(hThread,INFINITE); 117 CloseHandle(hThread); 118 CloseHandle(hProcess); 119 return 0; 120 }