1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| // injector.c #include <windows.h> #include <tlhelp32.h> #include <stdio.h> #include <string.h>
// 尋找指定進程名稱,回傳 PID (0 表示找不到) DWORD FindProcessId(const char* processName) { PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
DWORD pid = 0; if (Process32First(hSnapshot, &pe)) { do { // 不分大小寫比對可執行檔名稱 if (_stricmp(pe.szExeFile, processName) == 0) { pid = pe.th32ProcessID; break; } } while (Process32Next(hSnapshot, &pe)); }
CloseHandle(hSnapshot); return pid; }
int main() { // 1. 避免亂碼輸出:將輸出編碼設為 UTF-8 SetConsoleOutputCP(CP_UTF8);
// 2. 檢查 explorer.exe 是否已存在 DWORD pid = FindProcessId("explorer.exe"); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi));
if (pid == 0) { // 若沒找到,啟動新的 explorer.exe STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si);
// 參考記憶點:若想最小化啟動,可設置: // si.dwFlags = STARTF_USESHOWWINDOW; // si.wShowWindow = SW_SHOWMINIMIZED;
if (!CreateProcessA( "C:\\Windows\\explorer.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) { DWORD err = GetLastError(); printf("無法啟動 explorer.exe,錯誤碼: %lu\n", err); return 1; }
// 取得新的 explorer.exe PID pid = pi.dwProcessId; // 稍作等待讓 explorer.exe 初始化 Sleep(1000); }
// 3. 打開 explorer.exe 進程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (!hProcess) { DWORD err = GetLastError(); printf("OpenProcess 失敗,錯誤碼: %lu\n", err); return 1; }
// 4. 準備要注入的 DLL 路徑 const char* dllPath = "injected.dll"; // 若不在同一目錄,可用絕對路徑 size_t dllPathSize = strlen(dllPath) + 1;
// 在目標進程中分配記憶體 LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, dllPathSize, MEM_COMMIT, PAGE_READWRITE); if (!remoteMemory) { DWORD err = GetLastError(); printf("VirtualAllocEx 失敗,錯誤碼: %lu\n", err); CloseHandle(hProcess); return 1; }
// 寫入 DLL 路徑 if (!WriteProcessMemory(hProcess, remoteMemory, dllPath, dllPathSize, NULL)) { DWORD err = GetLastError(); printf("WriteProcessMemory 失敗,錯誤碼: %lu\n", err); VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; }
// 5. 建立遠端執行緒,以 LoadLibraryA 載入 injected.dll HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, remoteMemory, 0, NULL );
if (!hThread) { DWORD err = GetLastError(); printf("CreateRemoteThread 失敗,錯誤碼: %lu\n", err); VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; }
printf("成功注入到 explorer.exe (PID=%lu)\n", pid);
WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess);
// 若剛才有新建 explorer.exe,就等它結束 (可依需求保留或移除) if (pi.hProcess) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }
return 0; }
|