MCPcopy Create free account
hub / github.com/OpenSteam001/OpenSteamTool / InjectLibrary

Function InjectLibrary

src/OSTPlatform/Windows/RemoteProcess.cpp:207–277  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

205}
206
207InjectStatus InjectLibrary(uint32_t pid, const std::filesystem::path& libraryPath) {
208 Windows::UniqueHandle process(pid ? OpenProcess(kInjectAccess, FALSE, pid) : nullptr);
209 if (!process) {
210 OSTP_LOG_WARN("OpenProcess(pid={}, access=0x{:X}) failed (error={})", pid, kInjectAccess, GetLastError());
211 return InjectStatus::OpenProcessFailed;
212 }
213
214 const Architecture architecture = DetectArchitecture(process.get());
215 if (architecture == Architecture::Unknown) {
216 OSTP_LOG_WARN("InjectLibrary(pid={}): target architecture is unknown", pid);
217 return InjectStatus::UnknownArchitecture;
218 }
219
220 LPTHREAD_START_ROUTINE loadLibrary = ResolveRemoteLoadLibraryW(pid, architecture);
221 if (!loadLibrary) {
222 return InjectStatus::ResolveLoadLibraryFailed;
223 }
224
225 const std::wstring nativePath = libraryPath.wstring();
226 const size_t byteSize = (nativePath.size() + 1) * sizeof(wchar_t);
227 void* remotePath = VirtualAllocEx(process.get(), nullptr, byteSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
228 if (!remotePath) {
229 OSTP_LOG_WARN("VirtualAllocEx(size={}) failed (error={})", byteSize, GetLastError());
230 return InjectStatus::AllocFailed;
231 }
232 // Free the remote path on every exit path. It must outlive the remote
233 // thread, which reads it before LoadLibraryW returns; function scope (after
234 // the WaitForSingleObject below) satisfies that.
235 Windows::ScopeExit freeRemotePath([&] {
236 VirtualFreeEx(process.get(), remotePath, 0, MEM_RELEASE);
237 });
238
239 SIZE_T written = 0;
240 if (!WriteProcessMemory(process.get(), remotePath, nativePath.c_str(), byteSize, &written) ||
241 written != byteSize) {
242 OSTP_LOG_WARN("WriteProcessMemory(size={}) failed (written={}, error={})",
243 byteSize, static_cast<size_t>(written), GetLastError());
244 return InjectStatus::WriteFailed;
245 }
246
247 Windows::UniqueHandle thread(
248 CreateRemoteThread(process.get(), nullptr, 0, loadLibrary, remotePath, 0, nullptr));
249 if (!thread) {
250 OSTP_LOG_WARN("CreateRemoteThread failed (error={})", GetLastError());
251 return InjectStatus::CreateThreadFailed;
252 }
253
254 const DWORD wait = WaitForSingleObject(thread.get(), kRemoteLoadTimeoutMs);
255 if (wait != WAIT_OBJECT_0) {
256 if (wait == WAIT_FAILED) {
257 OSTP_LOG_WARN("WaitForSingleObject(remote thread) failed (error={})", GetLastError());
258 } else if (wait == WAIT_TIMEOUT) {
259 OSTP_LOG_WARN("WaitForSingleObject(remote thread) timed out after {} ms", kRemoteLoadTimeoutMs);
260 } else {
261 OSTP_LOG_WARN("WaitForSingleObject(remote thread) returned unexpected status {}", wait);
262 }
263 return InjectStatus::WaitFailed;
264 }

Callers 1

ApplyFunction · 0.85

Calls 4

DetectArchitectureFunction · 0.85
sizeMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected