C++學習之DLL注入,學習dll注入
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 }