| 114 | #pragma comment(linker, "/export:InjectProcess=_InjectProcess@16") |
| 115 | #endif |
| 116 | void CALLBACK InjectProcess(HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow) |
| 117 | { |
| 118 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |
| 119 | setlocale(LC_ALL, ""); |
| 120 | DWORD processId = 0; |
| 121 | try |
| 122 | { |
| 123 | processId = std::stoul(lpszCmdLine); |
| 124 | |
| 125 | wil::unique_handle hProcess(OpenProcess( |
| 126 | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, |
| 127 | FALSE, |
| 128 | processId)); |
| 129 | THROW_LAST_ERROR_IF(!hProcess.is_valid()); |
| 130 | |
| 131 | auto selfPath = GetDllSelfPath(); |
| 132 | size_t bufferSize = (wcslen(selfPath.get()) + 1) * sizeof(wchar_t); |
| 133 | |
| 134 | LPVOID remoteBuf = VirtualAllocEx( |
| 135 | hProcess.get(), |
| 136 | nullptr, |
| 137 | bufferSize, |
| 138 | MEM_COMMIT, |
| 139 | PAGE_READWRITE); |
| 140 | THROW_LAST_ERROR_IF(!remoteBuf); |
| 141 | |
| 142 | WriteProcessMemory( |
| 143 | hProcess.get(), |
| 144 | remoteBuf, selfPath.get(), |
| 145 | bufferSize, |
| 146 | nullptr); |
| 147 | |
| 148 | HMODULE hModuleKernel32 = nullptr; |
| 149 | THROW_LAST_ERROR_IF( |
| 150 | GetModuleHandleExW( |
| 151 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, |
| 152 | L"kernel32.dll", |
| 153 | &hModuleKernel32) == FALSE); |
| 154 | auto threadProc = reinterpret_cast<LPTHREAD_START_ROUTINE>( |
| 155 | GetProcAddress(hModuleKernel32, "LoadLibraryW")); |
| 156 | |
| 157 | wil::unique_handle hThread(CreateRemoteThread( |
| 158 | hProcess.get(), |
| 159 | nullptr, |
| 160 | 0, |
| 161 | threadProc, |
| 162 | remoteBuf, |
| 163 | 0, |
| 164 | nullptr)); |
| 165 | THROW_LAST_ERROR_IF(!hThread.is_valid()); |
| 166 | |
| 167 | WaitForSingleObject(hThread.get(), INFINITE); |
| 168 | // VirtualFreeEx(hProcess.get(), remoteBuf, 0, MEM_RELEASE); |
| 169 | sfh::EventLog::GetInstance().LogDllInjectProcessSuccess(processId); |
| 170 | } |
| 171 | catch (std::exception& e) |
| 172 | { |
| 173 | sfh::EventLog::GetInstance().LogDllInjectProcessFailure( |
nothing calls this directly
no test coverage detected