1 // InjectAPC.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include <Windows.h>
6 #include <iostream>
7 #include <vector>
8 #include <TlHelp32.h>
9
10 using namespace std;
11 BOOL GrantPrivileges(WCHAR* PrivilegeName);
12 BOOL GetProcessIDByProcessImageName(IN WCHAR* wzProcessImageName, OUT UINT32* TargetProcessID);
13 BOOL GetThreadIDByProcessID(UINT32 ProcessID, vector<UINT32>& ThreadIDVector);
14 BOOL Inject(UINT32 ProcessID, UINT32 ThreadID);
15
16 WCHAR DllFullPath[MAX_PATH] = { 0 };
17 PVOID DllFullPathBufferData = NULL;
18
19 int main()
20 {
21 if(GrantPrivileges(SE_DEBUG_NAME)==FALSE)
22 {
23 printf("GrantPrivilege Error\r\n");
24 }
25 UINT32 ProcessID = 0;
26 GetCurrentDirectory(MAX_PATH, DllFullPath);
27 wcscat(DllFullPath, L"\\Dll.dll");
28 //getchar();
29 //printf("%S\r\n", DllFullPath);
30
31 #ifdef _WIN64
32 GetProcessIDByProcessImageName(L"Taskmgr.exe", &ProcessID);
33 // GetProcessIDByProcessImageName(L"explorer.exe", &ProcessID);
34 #else
35 GetProcessIDByProcessImageName(L"Taskmgr.exe", &ProcessID);
36 #endif
37 vector<UINT32> ThreadIDVector;
38 //printf("%d\r\n", ProcessID);
39 GetThreadIDByProcessID(ProcessID, ThreadIDVector);
40
41 UINT32 ThreadID = 0;
42 while (!ThreadIDVector.empty())
43 {
44 ThreadID = ThreadIDVector.back();
45 Inject(ProcessID, ThreadID);
46 ThreadIDVector.pop_back();
47 }
48 /*size_t ThreadCount = ThreadIDVector.size();
49 for (INT_PTR i = ThreadCount - 1; i >= 0; i--)
50 {
51 UINT32 ThreadID = ThreadIDVector[i];
52 Inject(ProcessID, ThreadID);
53 }*/
54 getchar();
55 return 0;
56 }
57 //提高的是自己的权限,提成自己想要的。
58
59 BOOL GrantPrivileges(WCHAR* PrivilegeName)
60 {
61 HANDLE TokenHandle = NULL;
62 TOKEN_PRIVILEGES PrivilegesToken;
63 LUID v1;
64 //打开权限令牌
65 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &TokenHandle))
66 {
67 return FALSE;
68 }
69 if (!LookupPrivilegeValue(NULL, PrivilegeName, &v1))
70 {
71 CloseHandle(TokenHandle);
72 return FALSE;
73 }
74 PrivilegesToken.PrivilegeCount = 1;
75 PrivilegesToken.Privileges[0].Luid = v1;
76 PrivilegesToken.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
77 //调整权限 //特权启用. 特权被用来访问一个对象或服务
78 if (!AdjustTokenPrivileges(TokenHandle, FALSE, &PrivilegesToken, sizeof(PrivilegesToken), NULL, NULL))
79 {
80 CloseHandle(TokenHandle);
81 TokenHandle = NULL;
82 return false;
83 }
84 //启用特权
85 CloseHandle(TokenHandle);
86
87 return TRUE;
88 }
89 //做好放的笔记里
90 BOOL GetProcessIDByProcessImageName(IN WCHAR * wzProcessImageName, OUT UINT32 * TargetProcessID)
91 {
92 HANDLE ProcessSnapshotHandle = NULL; //1.初始化
93
94 ProcessSnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
95 //一个班的学生
96 if (ProcessSnapshotHandle == INVALID_HANDLE_VALUE)
97 {
98 return FALSE;
99 }
100
101 PROCESSENTRY32 ProcessEntry32 = { 0 }; //用来存放快照进程信息的一个结构体
102 ProcessEntry32.dwSize = sizeof(PROCESSENTRY32);//初始化PROCESSENTRY结构
103 Process32First(ProcessSnapshotHandle, &ProcessEntry32); //把第一个进程 放在结构体中
104
105 do
106 {
107 if (lstrcmpi(ProcessEntry32.szExeFile, wzProcessImageName)==0) //不区分大小写
108 { //进程的名称
109 *TargetProcessID = ProcessEntry32.th32ProcessID;
110 break;
111 }
112 } while (Process32Next(ProcessSnapshotHandle, &ProcessEntry32));
113 //printf("%d\r\n", *TargetProcessID);
114 CloseHandle(ProcessSnapshotHandle);
115 ProcessSnapshotHandle = NULL;
116 return TRUE;
117 return 0;
118 }
119 //枚举对方的指定进程ID的所有线程,压入vector中,返回线程集合
120 BOOL GetThreadIDByProcessID(UINT32 ProcessID, vector<UINT32>& ThreadIDVector)
121 {
122 HANDLE ThreadSnapshotHandle = NULL;
123 THREADENTRY32 ThreadEntry32 = { 0 };
124 ThreadEntry32.dwSize = sizeof(THREADENTRY32);
125 ThreadSnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
126 if (ThreadSnapshotHandle == INVALID_HANDLE_VALUE) //指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE后才有效,
127 { //在其他情况下该参数被忽略,所有的进程都会被快照。所以不用修改0为ProcessID。
128 return FALSE;
129 }
130 BOOL bOk = Thread32First(ThreadSnapshotHandle, &ThreadEntry32);
131 if (bOk)
132 {
133 do
134 {
135 if (ThreadEntry32.th32OwnerProcessID == ProcessID)
136 {
137 ThreadIDVector.emplace_back(ThreadEntry32.th32ThreadID); //怀疑可能push.back枚举可以
138 }
139 } while (Thread32Next(ThreadSnapshotHandle, &ThreadEntry32));
140 }
141 CloseHandle(ThreadSnapshotHandle);
142 ThreadSnapshotHandle = NULL;
143 return TRUE;
144 }
145
146 BOOL Inject(UINT32 ProcessID, UINT32 ThreadID)
147 {
148 HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
149 HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
150 //220
151 SIZE_T ReturnLength = 0;
152
153
154 size_t DllFullPathLength = wcslen(DllFullPath) + 1;
155
156 if (DllFullPathBufferData == NULL)
157 {
158 //在对方进程空间申请内存,存储Dll完整路径。
159 DllFullPathBufferData = VirtualAllocEx(ProcessHandle, NULL, DllFullPathLength * 2, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
160 if (DllFullPathBufferData == NULL)
161 {
162 CloseHandle(ProcessHandle);
163 CloseHandle(ThreadHandle);
164 return FALSE;
165 }
166 //将DllFullPath写进刚刚申请的内存中 size是双字长度
167 BOOL bOk = WriteProcessMemory(ProcessHandle, DllFullPathBufferData, DllFullPath, DllFullPathLength*2,
168 &ReturnLength);
169
170 if (bOk == FALSE)
171 {
172 VirtualFreeEx(ProcessHandle,DllFullPathBufferData,(DllFullPathLength * 2), MEM_RELEASE);
173 CloseHandle(ProcessHandle);
174 CloseHandle(ThreadHandle);
175 return FALSE;
176 }
177 }
178
179 UINT_PTR LoadLibraryAddress = (UINT_PTR)GetProcAddress(GetModuleHandle(L"Kernel32.dll"),"LoadLibraryW");
180 //当前进程中获得导入模块Kernel32基地址
181 //Kernel32模块中的导出表中获得函数LoadLibraryW
182
183 /*
184 为什么这里用导出表中的地址LoadLibraryW不用导入表中的函数地址?
185 LoadLibraryW 当前进程导入表中的地址 比如 LoadLibraryW = 0x1234 0x1234 -->0x7564 相当于 0x1234[0x7564]
186
187
188 1.防止中一种病毒叫Hook IAT(ImportAddressTable) Hook
189 中这种病毒,修改了Kernel 地址 0x7564,这样寻不到址
190 2.确保地址OK
191
192 */
193 if (LoadLibraryAddress == NULL)
194 {
195 VirtualFreeEx(ProcessHandle, DllFullPathBufferData, (DllFullPathLength * 2), MEM_RELEASE);
196 CloseHandle(ProcessHandle);
197 return FALSE;
198 }
199 _try
200 {
201 ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadID);
202 QueueUserAPC((PAPCFUNC)LoadLibraryAddress,ThreadHandle,(UINT_PTR)DllFullPathBufferData);
203 //LoadLibraryAddress(DllFullPathBufferData)
204 }
205 _except(EXCEPTION_CONTINUE_EXECUTION)
206 {
207
208 }
209 CloseHandle(ProcessHandle);
210 CloseHandle(ThreadHandle);
211 return 0;
212 }