| 255 | } |
| 256 | |
| 257 | bool InjectDll(DWORD processId, const char *dllDir, const char *dllFileName, bool capture) { |
| 258 | if (IsBeingInjected(processId, dllFileName)) { |
| 259 | MessageEvent("The process already attached."); |
| 260 | return true; |
| 261 | } |
| 262 | |
| 263 | MessageEvent("Start inject dll ..."); |
| 264 | bool success = true; |
| 265 | |
| 266 | const HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); |
| 267 | |
| 268 | if (process == nullptr) { |
| 269 | MessageEvent("Failed to open process", MessageType_Error); |
| 270 | OutputError(GetLastError()); |
| 271 | return false; |
| 272 | } |
| 273 | DWORD exitCode = 0; |
| 274 | |
| 275 | // Set dll directory |
| 276 | void *dllDirRemote = RemoteDup(process, dllDir, strlen(dllDir) + 1); |
| 277 | ExecuteRemoteKernelFuntion(process, "SetDllDirectoryA", dllDirRemote, exitCode); |
| 278 | VirtualFreeEx(process, dllDirRemote, 0, MEM_RELEASE); |
| 279 | |
| 280 | // Load the DLL. |
| 281 | void *remoteFileName = RemoteDup(process, dllFileName, strlen(dllFileName) + 1); |
| 282 | success &= ExecuteRemoteKernelFuntion(process, "LoadLibraryA", remoteFileName, exitCode); |
| 283 | VirtualFreeEx(process, remoteFileName, 0, MEM_RELEASE); |
| 284 | if (!success || exitCode == 0) { |
| 285 | MessageEvent("Failed to load library", MessageType_Error); |
| 286 | return false; |
| 287 | } |
| 288 | |
| 289 | |
| 290 | void *lpParam = nullptr; |
| 291 | if (capture) { |
| 292 | lpParam = (void *) VirtualAllocEx(process, 0, sizeof(RemoteThreadParam), MEM_COMMIT, |
| 293 | PAGE_READWRITE); |
| 294 | RemoteThreadParam param; |
| 295 | param.bRedirect = TRUE; |
| 296 | |
| 297 | ::WriteProcessMemory(process, lpParam, ¶m, sizeof(RemoteThreadParam), NULL); |
| 298 | } |
| 299 | |
| 300 | // Read shared data & call 'StartupHookMode()' |
| 301 | TSharedData data; |
| 302 | if (ReadSharedData(data)) { |
| 303 | DWORD threadId; |
| 304 | HANDLE thread = CreateRemoteThread(process, |
| 305 | nullptr, |
| 306 | 0, |
| 307 | (LPTHREAD_START_ROUTINE) data.lpInit, |
| 308 | (void *) lpParam, |
| 309 | 0, |
| 310 | &threadId); |
| 311 | |
| 312 | if (thread != nullptr) { |
| 313 | WaitForSingleObject(thread, INFINITE); |
| 314 | GetExitCodeThread(thread, &exitCode); |
no test coverage detected