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("\n獲得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("\n獲取進程句柄錯誤%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("\n寫入遠程進程內存空間出錯%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("\n建立遠程線程失敗%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 }