X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:in-reply-to:subject:date:message-id :mime-version:content-type:content-transfer-encoding; q=dns; s= default; b=PMigfarg3vKzn2O/2R7wEuT1+WXpT391JvoItcWv1lazGhMhYgF7Y WZDysqgapl6UQ2k7FS9lWwatqcG2+8Gf1zURao8YSuaiBDmQ+W+cj8Cv2nvmjFoU zooY8BqC1dUTFduum7NXJqJdh4j9qSKGL1jp5IuUEvhl7caI1er/Lc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:in-reply-to:subject:date:message-id :mime-version:content-type:content-transfer-encoding; s=default; bh=ohXVhYOnPvhl9zg/0eMNNG+3uz8=; b=x2yQbxnuhgLG2i36WbF6oTzLB6mH GkYzudtF7K6bFqwNS5P8oNqH2CqY4P8k2a5zWtP+PAjhFOutM+snp+fnSq8zDFe8 yLqPZQmRYoc7dC2jMnYV85+boI/fmlIya+YL0yyjs0ctsL56jGpVKpTkl3O7hGHG ro1JLeN9Y7VXji4= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.7 required=5.0 tests=AWL,BAYES_50,KAM_COUK,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: smtp.demon.co.uk From: "Roger Orr" To: "'Dennis Hagarty \(dehagart\)'" , In-Reply-To: <3FEEC3A37A0B0A48AA326075128C32EE4EE27AEC@xmb-rcd-x01.cisco.com> Subject: RE: Very slow Cygwin startup on Windows 7 Date: Sat, 21 Feb 2015 12:03:08 -0000 Message-ID: <96140799EAC545F68F224090E2F2E0A5@Tamar> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-MDF-HostID: 18 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id t1LC3VvK017154 > > Sysinternals "ADInsight" is a 32bit only tool and, in order to work on > > a 64bit Windows you seem to have to manually inject the DLL > > ADInsightDll.dll (which is extracted into %TEMP%) into the target > > (32-bit!) process. > So, it seems ADInsight seems a non-starter - for my skill level anyway. In case it helps you, or another reader of the list, here is a simple program that injects a named dll into a target process. Example of using it to examine the ldap calls for cygwin's "echo.exe": - Compile as a 32-bit program using *32bit* cygwin (as ADInsight is a 32bit process): g++ inject.cpp -o inject.exe - Start ADInsight from SysInternals - Start Windows command shell - Invoke: inject.exe %TEMP%\ADInsightDll.dll c:\cygwin\bin\echo.exe hello Regards, Roger. ----- inject.cpp ----- /* NAME Inject.cpp DESCRIPTION Inject a DLL into another process COPYRIGHT Copyright (C) 2002,2015 by Roger Orr This software is distributed in the hope that it will be useful, but without WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Permission is granted to anyone to make or distribute verbatim copies of this software provided that the copyright notice and this permission notice are preserved, and that the distributor grants the recipient permission for further distribution as permitted by this notice. Comments and suggestions are always welcome. Please report bugs to rogero AT howzatt DOT demon DOT co DOT uk. EXAMPLE Inject MyDll fred.exe */ #include #include #include ////////////////////////////////////////////////////////////////////////// // Local functions int CreateProcessHelper(char ** it, char ** end, HANDLE & hProcess, HANDLE & hThread); int InjectDLL(std::string const &dllName, HANDLE hProcess); ////////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { if (argc < 3) { std::cerr << "Syntax: inject " << std::endl; return 1; } std::string const dllName = argv[1]; std::string const progName = argv[2]; HANDLE hProcess = 0; HANDLE hThread = 0; if (CreateProcessHelper(argv+2, argv+argc, hProcess, hThread) != 0) { return 1; } if (InjectDLL(dllName, hProcess) != 0) { TerminateProcess(hProcess, GetLastError()); return 1; } // resume the created process once we've loaded the DLL if (::ResumeThread(hThread) == (DWORD)-1) { std::cout << "ResumeThread failed with " << GetLastError() << std::endl; return 1; } DWORD ret = ::WaitForSingleObject(hProcess, INFINITE); if (ret == WAIT_OBJECT_0) { DWORD exitCode; if (GetExitCodeProcess(hProcess, &exitCode)) { std::cout << "Process " << progName << " terminated: " "return code: " << exitCode << std::endl; ret = exitCode; } else { ret = GetLastError(); std::cout << "Process terminated: return code unavailable: " << ret << std::endl; } } else if (ret == WAIT_FAILED) { std::cout << "Process wait failed: " << GetLastError() << std::endl; } else { std::cout << "Process wait failed: " << ret << std::endl; } return ret; } ////////////////////////////////////////////////////////////////////////// // Inject DLL 'dllName' into process 'hProcess' int InjectDLL(std::string const &dllName, HANDLE hProcess) { LPTHREAD_START_ROUTINE lpStartAddress = 0; // Create memory in target process LPVOID const chDllName = VirtualAllocEx(hProcess, 0, dllName.size() + 1, MEM_COMMIT, PAGE_READWRITE); if (chDllName == 0) { std::cerr << "VirtualAllocEx failed: " << GetLastError() << std::endl; return 1; } // Map into my process if (! WriteProcessMemory(hProcess, chDllName, dllName.c_str(), dllName.size()+1, 0)) { std::cerr << "WriteProcessMemory failed: " << GetLastError() << std::endl; return 1; } lpStartAddress = (LPTHREAD_START_ROUTINE)LoadLibrary; // Start a remote thread, at LoadLibraryA in the target process // Note we assume KERNEL32 has a fixed load address DWORD threadId(0); HANDLE const hRemoteThread = CreateRemoteThread(hProcess, 0, 0, lpStartAddress, chDllName, 0, &threadId); if (hRemoteThread == 0) { std::cerr << "CreateRemoteThread failed: " << GetLastError() << std::endl; return 1; } WaitForSingleObject(hRemoteThread, 10000); DWORD exitCode; if (! GetExitCodeThread(hRemoteThread, &exitCode)) { std::cerr << "GetExitCodeThread failed: " << GetLastError() << std::endl; return 1; } if (exitCode == STILL_ACTIVE) { std::cout << "Remote thread still running..." << std::endl; return 1; } else if (exitCode == 0) { std::cout << "Remote thread failed to load DLL" << std::endl; return 1; } // Tidy up the allocated memory. if (! VirtualFreeEx(hProcess, chDllName, 0, MEM_RELEASE)) { std::cout << "Warning: unable to free memory in target process: " << GetLastError() << std::endl; } return 0; } ////////////////////////////////////////////////////////////////////////// // Wrapper for create process. int CreateProcessHelper( char ** it, char ** end, HANDLE &hProcess, HANDLE &hThread) { char * executable = *it; // Search for possible executable matching the program name char szFullName[ MAX_PATH ]; if (0 != SearchPath(0, executable, ".exe", sizeof(szFullName), szFullName, 0)) executable = szFullName; std::string cmdLine; for (; it != end; ++it) { std::string curr(*it); if (cmdLine.length()) cmdLine += " "; if (curr.find(' ') != std::string::npos) { cmdLine += '"'; cmdLine += curr; cmdLine += '"'; } else { cmdLine += curr; } } STARTUPINFO startupInfo = { sizeof(startupInfo) }; startupInfo.dwFlags = STARTF_USESHOWWINDOW; startupInfo.wShowWindow = SW_SHOWNORMAL; // Assist GUI programs PROCESS_INFORMATION procInfo; if (! CreateProcess(executable, const_cast(cmdLine.c_str()), 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &startupInfo, & procInfo)) { std::cout << "CreateProcess for " << executable << " failed: " << GetLastError() << std::endl; return 1; } hProcess = procInfo.hProcess; hThread = procInfo.hThread; return 0; } ----- ends ----- -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple