Win32API - Injecting DLLs into remote processes =============================================== Injecting using the registry ---------------------------- * (Won't work with Windows98) To project your dll on the (whole) address space of user32.dll (all processes for their lifetime): [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows] "AppInit_DLLs"="MyLib1.dll MyLib2.dll ..." Injecting using Hooks --------------------- HWND hWndCtrl = GetFirstChild( GetFirstChild( FindWindow( TEXT("ProgMan"), NULL ))); - (Client). Get the window handle. (Use SpyXX to set the proper hirarchy) DWORD dwThreadId = GetWindowThreadProcessId(hWndCtrl, NULL); - (Client). * Ask server to set the hook g_dwMyThreadId = GetCurrentThreadId(); - (Server). Save our thread ID in a shared variable so that our GetMsgProc function can post a message back to to thread when the server window has been created g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstanceDll, dwDestThreadId); - (Server). Set hook that injects our DLL into the destination application address space PostThreadMessage(dwDestThreadId, WM_NULL, 0, 0); - (Server). Force a message to the thread's queue so that the hook function gets called CreateDialog(g_hInstanceDll, MAKEINTRESOURCE(IDD_MYDLG), NULL, Dlg_Proc); - (Server). Create modeless dialog box to handle messages on the server side PostThreadMessage(g_dwMyThreadId, WM_NULL, 0, 0); - (Server). Tell the client that the server is up and ready to handle requests CallNextHookEx(g_hHook, nCode, wParam, lParam); - (Server). Hook procedures are installed in chains for particular hook types. CallNextHookEx calls the next hook in the chain GetMessage(&msg, NULL, 0, 0); - (Client). Wait for the server window to be created. (custom synchronization) HWND hWndApp = FindWindow(NULL, TEXT("Window Name")); - (Client). Find the handle of the hidden dialog box window IsWindow(hwndApp); - (Client). Checks if the window was created SendMessage(hWndApp, WM_APP, (WPARAM) hwndCtrl, (cWhatToDo == TEXT('S'))); - (Client). Tell the server App window which Ctrl window to manimpulate SendMessage(hWndApp, WM_CLOSE, 0, 0); - (Client). Destroy the window (before unhooking!) DestroyWindow(hwnd); - (Server). UnhookWindowsHookEx(g_hHook); - (Server). Injecting using Remote Threads ------------------------------ * (Won't work with Windows98) Inject: ------ OpenProcess - Get the handle of the target process VirutalAllocEx - Allocate memory for the DLL file name in the remote process WriteProcessMemory - Copy the file name to the memory allocated above GetModuleHandle("kernel32.dll"); - Get the real address of kernel32.dll (we need the real addresses of the kernel functions) GetProcAddress(hKernel, "LoadLibrary"); - Get the real address of the LoadLibraryA/W functions CreateRemoteThread - Create a thread, in a remote process, that will call LoadLibraryA/w. On this stage, the DLL gets injected WaitForSingleObject - Wait for the thread to terminate VirtualFreeEx - Free the remote memory CloseHandle(hThread); CloseHandle(hProcess); - Terminate the thread and the process Eject: ----- CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId); - Take a snapshot of all the models in the process MODULEENTREE32 stModule = {sizeof(stModule)}; Module32First(hSnapshot, &stModule); - Get info about the first module associated with the process Module32Next(hSnapshot, &stModule); - Get info of the next module from the list. We should repeatadly call this function until stModule.szModule or stModule.szExePath is the same as the DLL file name that we have injected OpenProcess GetModuleHandle("kernel32.dll"); GetProceAddress(hKernel, "FreeLibrary"); CreateRemoteThread - Create the thread using stModule.modBaseAddr WaitForSingleObject CloseHandle(hSnapshot); CloseHandle(hThread); CloseHandle(hProcess);