1 // APCInject.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "APCInject.h" 6 7 #include <windows.h> 8 #include <TlHelp32.h> 9 10 #include <iostream> 11 #include <string> 12 13 14 15 #define _WIN32_WINNT 0x0400 16 17 #define DEF_BUF_SIZE 1024 18 19 20 #ifdef _DEBUG 21 #define new DEBUG_NEW 22 #endif 23 24 25 // 唯一的应用程序对象 26 27 CWinApp theApp; 28 29 using namespace std; 30 31 32 typedef long(__fastcall *pfnRtlAdjustPrivilege64)(ULONG, ULONG, ULONG, PVOID); 33 pfnRtlAdjustPrivilege64 RtlAdjustPrivilege; 34 BOOL InjectModuleToProcessById(DWORD dwProcessId); 35 // 用于存储注入模块DLL的路径全名 36 char szDllPath[DEF_BUF_SIZE] = { 0 }; 37 int main() 38 { 39 int nRetCode = 0; 40 // 取得当前工作目录路径 41 GetCurrentDirectoryA(DEF_BUF_SIZE, szDllPath); 42 43 // 生成注入模块DLL的路径全名 44 strcat(szDllPath, "\\MessageBox32.dll"); 45 46 DWORD dwProcessId = 0; 47 // 接收用户输入的目标进程ID 48 while (cout << "请输入目标进程ID:" && cin >> dwProcessId && dwProcessId > 0) 49 { 50 BOOL bRet = InjectModuleToProcessById(dwProcessId); 51 cout << (bRet ? "注入成功!" : "注入失败!") << endl; 52 } 53 54 return nRetCode; 55 } 56 57 58 59 // 使用APC机制向指定ID的进程注入模块 60 BOOL InjectModuleToProcessById(DWORD dwProcessId) 61 { 62 DWORD dwRet = 0; 63 BOOL bStatus = FALSE; 64 LPVOID lpData = NULL; 65 UINT uLen = strlen(szDllPath) + 1; 66 LPTHREAD_START_ROUTINE FuncAddress = NULL; 67 DWORD dwRetVal = 0; 68 #ifdef _WIN64 // x64 OpenProcess提权操作 69 //RtlAdjustPrivilege = (pfnRtlAdjustPrivilege64)GetProcAddress((HMODULE)(FuncAddress(L"ntdll.dll")), "RtlAdjustPrivilege"); 70 71 //if (RtlAdjustPrivilege == NULL) 72 //{ 73 // return FALSE; 74 //} 75 ///* 76 //.常量 SE_BACKUP_PRIVILEGE, "17", 公开 77 //.常量 SE_RESTORE_PRIVILEGE, "18", 公开 78 //.常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开 79 //.常量 SE_DEBUG_PRIVILEGE, "20", 公开 80 //*/ 81 //RtlAdjustPrivilege(20, 1, 0, &dwRetVal); //19 82 #endif 83 // 打开目标进程 84 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); 85 if (hProcess) 86 { 87 // 分配空间 88 lpData = VirtualAllocEx(hProcess, NULL, uLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 89 if (lpData) 90 { 91 // 写入需要注入的模块路径全名 92 bStatus = WriteProcessMemory(hProcess, lpData, szDllPath, uLen, NULL); 93 } 94 CloseHandle(hProcess); 95 } 96 97 if (bStatus == FALSE) 98 return FALSE; 99 100 // 创建线程快照 101 THREADENTRY32 te32 = { sizeof(THREADENTRY32) }; 102 HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 103 if (hThreadSnap == INVALID_HANDLE_VALUE) 104 return FALSE; 105 106 bStatus = FALSE; 107 // 枚举所线程 108 if (Thread32First(hThreadSnap, &te32)) 109 { 110 do { 111 // 判断是否目标进程中的线程 112 if (te32.th32OwnerProcessID == dwProcessId) 113 { 114 // 打开线程 115 HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID); 116 if (hThread) 117 { 118 // 向指定线程添加APC 119 DWORD dwRet = QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)lpData); 120 if (dwRet > 0) 121 bStatus = TRUE; 122 CloseHandle(hThread); 123 } 124 } 125 126 } while (Thread32Next(hThreadSnap, &te32)); 127 } 128 129 CloseHandle(hThreadSnap); 130 return bStatus; 131 }