#include #include #define log_info(msg, ...) printf("[*] " msg "\n", ##__VA_ARGS__) #define log_err(msg, ...) printf("[-] " msg "\n", ##__VA_ARGS__) #define log_ok(msg, ...) printf("[+] " msg "\n", ##__VA_ARGS__) wchar_t dll_path[] = L"my-dll.dll"; int main(int argc, char **argv) { if (argc < 2) { log_err("Usage: %s ", argv[0]); return -1; } DWORD pid = atoi(argv[1]); log_info("Using PID: %ld", pid); HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (process == NULL) { log_err("Failed to open process handle: %ld", GetLastError()); return -1; } log_ok("Sucessfully opened process handle"); LPVOID buffer = VirtualAllocEx(process, NULL, sizeof(dll_path), (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE); if (buffer == NULL) { log_err("Failed to allocate buffer in process: %ld", GetLastError()); CloseHandle(process); return -1; } log_ok("Successfully allocated a %lld byte buffer", sizeof(dll_path)); WriteProcessMemory(process, buffer, dll_path, sizeof(dll_path), NULL); log_info("Wrote DLL path to buffer"); HMODULE kernel32 = GetModuleHandleW(L"Kernel32"); if (kernel32 == NULL) { log_err("Failed to open 'Kernel32' module: %ld", GetLastError()); CloseHandle(process); return -1; } log_ok("Got ahdle to Kernel32.dll: 0x%p", kernel32); LPTHREAD_START_ROUTINE thread_callback = (LPTHREAD_START_ROUTINE)GetProcAddress(kernel32, "LoadLibraryW"); log_info("Got address of LoadLibrary(): 0x%p", thread_callback); DWORD thread_id = 0; HANDLE thread = CreateRemoteThreadEx(process, NULL, 0, thread_callback, buffer, 0, 0, &thread_id); if (thread == NULL) { log_err("Failed to create thread: %ld", GetLastError()); CloseHandle(process); return -1; } log_info("Waiting for thread to finish..."); WaitForSingleObject(thread, INFINITE); log_info("Thread finished!"); log_info("Cleaning up handles"); CloseHandle(process); CloseHandle(thread); return 0; }