類初始化時傳入要注入的DLL文件名
只使用兩個函數
// 注入DLL到指定的地址空間
BOOL InjectModuleInto(DWORD dwProcessId);
// 從指定的地址空間卸載DLL
BOOL EjectModuleFrom(DWORD dwProcessId);
.h
1. #pragma once
2. #include <windows.h> //在頭文件中包含
3.
4. class CRemThreadInject
5. {
6. public:
7. CRemThreadInject(LPSTR lpDllName);
8. ~CRemThreadInject(void);
9.
10. protected:
11. char m_szDllName[MAX_PATH];
12. static BOOL EnableDebugPrivilege(BOOL bEnable);
13. public:
14. // 注入DLL到指定的地址空間
15. BOOL InjectModuleInto(DWORD dwProcessId);
16. // 從指定的地址空間卸載DLL
17. BOOL EjectModuleFrom(DWORD dwProcessId);
18. };
.cpp
1. #include "RemThreadInject.h"
2. #include <tlhelp32.h>
3.
4. www.2cto.com
5.
6. CRemThreadInject::CRemThreadInject(LPSTR lpDllName)
7. {
8. memcpy(m_szDllName, lpDllName, MAX_PATH);
9. EnableDebugPrivilege(TRUE);
10. }
11.
12.
13. CRemThreadInject::~CRemThreadInject(void)
14. {
15. EnableDebugPrivilege(FALSE);
16. }
17.
18. BOOL CRemThreadInject::EnableDebugPrivilege(BOOL bEnable)
19. {
20. HANDLE hToken = INVALID_HANDLE_VALUE;
21. //OpenProcessToken
22. if (0 == ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
23. {
24. return FALSE;
25. }
26. LUID luid;
27.
28. //
29. ::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
30. TOKEN_PRIVILEGES tp;
31. tp.PrivilegeCount = 1;
32. tp.Privileges[0].Luid = luid;
33. if (bEnable)
34. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
35. else
36. tp.Privileges[0].Attributes = 0;
37. if ( !AdjustTokenPrivileges(
38. hToken,
39. FALSE,
40. &tp,
41. sizeof(TOKEN_PRIVILEGES),
42. (PTOKEN_PRIVILEGES) NULL,
43. (PDWORD) NULL) )
44. {
45. return FALSE;
46. }
47. if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
48. {
49. return FALSE;
50. }
51. ::CloseHandle(hToken);
52. return TRUE;
53. }
54.
55. // 注入DLL到指定的地址空間
56. BOOL CRemThreadInject::InjectModuleInto(DWORD dwProcessId)
57. {
58. //
59. if (::GetCurrentProcessId() == dwProcessId)
60. {
61. return FALSE;
62. }
63. BOOL bFound;
64. /************************************************************************/
65. /* 遍歷模塊 */
66. /************************************************************************/
67. HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
68. MODULEENTRY32 me32;
69.
70. // Take a snapshot of all modules in the specified process.
71. hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
72. if( hModuleSnap == INVALID_HANDLE_VALUE )
73. {
74. return( FALSE );
75. }
76. me32.dwSize = sizeof( MODULEENTRY32 );
77. if( !Module32First( hModuleSnap, &me32 ) )
78. {
79. CloseHandle( hModuleSnap ); // Must clean up the snapshot object!
80. return( FALSE );
81. }
82. do
83. {
84. if (stricmp(me32.szModule, m_szDllName) == 0)
85. {
86. bFound = TRUE;
87. break;
88. }
89. } while( Module32Next( hModuleSnap, &me32 ) );
90.
91. // Do not forget to clean up the snapshot object.
92. CloseHandle( hModuleSnap );
93.
94. if (bFound) //如果已經加載了模塊,就不再加載
95. {
96. return FALSE;
97. }
98.
99. //如果沒加載,打開進程,遠程注入
100.
101. HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD |PROCESS_VM_OPERATION |PROCESS_VM_WRITE, FALSE, dwProcessId);
102. if (hProcess == NULL)
103. {
104. return FALSE;
105. }
106. HMODULE hKernerl32 = GetModuleHandle("kernel32.dll");
107. LPTHREAD_START_ROUTINE pfnLoadLibraryA = (LPTHREAD_START_ROUTINE)::GetProcAddress(hKernerl32, "LoadLibraryA");
108.
109. int cbSize = strlen(m_szDllName)+1;
110. LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, 0, cbSize, MEM_COMMIT, PAGE_READWRITE);
111. ::WriteProcessMemory(hProcess, lpRemoteDllName, m_szDllName, cbSize, NULL);
112. HANDLE hRemoteThread = ::CreateRemoteThreadEx(hProcess, NULL, 0, pfnLoadLibraryA, lpRemoteDllName, 0, NULL, NULL);
113. if (NULL == hRemoteThread)
114. {
115. ::CloseHandle(hProcess);
116. return FALSE;
117. }
118. //等待目標線程運行結束,即LoadLibraryA函數返回
119. ::WaitForSingleObject(hRemoteThread, INFINITE);
120. ::CloseHandle(hRemoteThread);
121. ::CloseHandle(hProcess);
122. return TRUE;
123. }
124.
125.
126. // 從指定的地址空間卸載DLL
127. BOOL CRemThreadInject::EjectModuleFrom(DWORD dwProcessId)
128. {
129. //
130. if (::GetCurrentProcessId() == dwProcessId)
131. {
132. return FALSE;
133. }
134. BOOL bFound;
135. /************************************************************************/
136. /* 遍歷模塊 */
137. /************************************************************************/
138. HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
139. MODULEENTRY32 me32;
140.
141. // Take a snapshot of all modules in the specified process.
142. hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
143. if( hModuleSnap == INVALID_HANDLE_VALUE )
144. {
145. return( FALSE );
146. }
147. me32.dwSize = sizeof( MODULEENTRY32 );
148. if( !Module32First( hModuleSnap, &me32 ) )
149. {
150. CloseHandle( hModuleSnap ); // Must clean up the snapshot object!
151. return( FALSE );
152. }
153. do
154. {
155. if (stricmp(me32.szModule, m_szDllName) == 0)
156. {
157. bFound = TRUE;
158. break;
159. }
160. } while( Module32Next( hModuleSnap, &me32 ) );
161.
162. // Do not forget to clean up the snapshot object.
163. CloseHandle( hModuleSnap );
164.
165. if (!bFound) //如果沒有加載模塊,就不能卸載
166. {
167. return FALSE;
168. }
169.
170. //如果加載了,打開進程,遠程注入
171.
172. HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD |PROCESS_VM_OPERATION |PROCESS_VM_WRITE, FALSE, dwProcessId);
173. if (hProcess == NULL)
174. {
175. return FALSE;
176. }
177. HMODULE hKernerl32 = GetModuleHandle("kernel32.dll");
178. LPTHREAD_START_ROUTINE pfnFreeLibrary = (LPTHREAD_START_ROUTINE)::GetProcAddress(hKernerl32, "FreeLibrary");
179.
180. int cbSize = strlen(m_szDllName)+1;
181. LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, 0, cbSize, MEM_COMMIT, PAGE_READWRITE);
182. ::WriteProcessMemory(hProcess, lpRemoteDllName, m_szDllName, cbSize, NULL);
183. HANDLE hRemoteThread = ::CreateRemoteThreadEx(hProcess, NULL, 0, pfnFreeLibrary, lpRemoteDllName, 0, NULL, NULL);
184. if (NULL == hRemoteThread)
185. {
186. ::CloseHandle(hProcess);
187. return FALSE;
188. }
189. //等待目標線程運行結束,即LoadLibraryA函數返回
190. ::WaitForSingleObject(hRemoteThread, INFINITE);
191. ::CloseHandle(hRemoteThread);
192. ::CloseHandle(hProcess);
193. return TRUE;
194. }