internal DnProcess(DnDebugger ownerDebugger, ICorDebugProcess process, int incrementedId) { this.ownerDebugger = ownerDebugger; this.appDomains = new DebuggerCollection<ICorDebugAppDomain, DnAppDomain>(CreateAppDomain); this.threads = new DebuggerCollection<ICorDebugThread, DnThread>(CreateThread); this.process = new CorProcess(process); this.incrementedId = incrementedId; }
static bool WriteBytes(CorProcess process, ulong addr, byte[] data) { if (process == null || addr == 0 || data == null) return false; uint oldProtect; if (!NativeMethods.VirtualProtect(new IntPtr((long)addr), data.Length, NativeMethods.PAGE_EXECUTE_READWRITE, out oldProtect)) return false; int sizeWritten; try { process.WriteMemory(addr, data, 0, data.Length, out sizeWritten); } finally { NativeMethods.VirtualProtect(new IntPtr((long)addr), data.Length, oldProtect, out oldProtect); } return sizeWritten == data.Length; }
bool Initialize(CorProcess process, string debuggeeVersion) { try { var mgr = new ECallManager(process.ProcessId, debuggeeVersion); if (!mgr.FoundClrModule) return false; const string debuggerClassName = "System.Diagnostics.Debugger"; ulong addr; bool error = false, b; bool isClrV2OrOlder = debuggeeVersion != null && (debuggeeVersion.StartsWith("v1.", StringComparison.OrdinalIgnoreCase) || debuggeeVersion.StartsWith("v2.", StringComparison.OrdinalIgnoreCase)); // Launch() returns true in CLR 4.x and false in earlier CLR versions when there's // no debugger. At least on my system... b = mgr.FindFunc(debuggerClassName, "LaunchInternal", out addr); error |= !b; if (b) error |= !(isClrV2OrOlder ? WriteReturnFalse(process, addr) : WriteReturnTrue(process, addr)); b = mgr.FindFunc(debuggerClassName, "get_IsAttached", out addr); if (!b) b = mgr.FindFunc(debuggerClassName, "IsDebuggerAttached", out addr); error |= !b; if (b) error |= !WriteReturnFalse(process, addr); b = mgr.FindFunc(debuggerClassName, "IsLogging", out addr); error |= !b; if (b) error |= !WriteReturnFalse(process, addr); return !error; } catch { return false; } }
static bool WriteReturnTrue(CorProcess process, ulong addr) { return WriteBytes(process, addr, returnTrue); }
public CorProcessReader(CorProcess process) { if (process == null) throw new ArgumentNullException(); this.process = process; }
protected override void OnRun(DebuggerStartInfo startInfo) { // Create the debugger string dversion; try { dversion = CorDebugger.GetDebuggerVersionFromFile(startInfo.Command); } catch { dversion = CorDebugger.GetDefaultDebuggerVersion(); } dbg = new CorDebugger(dversion); Dictionary <string, string> env = new Dictionary <string, string> (); foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { env[(string)de.Key] = (string)de.Value; } foreach (KeyValuePair <string, string> var in startInfo.EnvironmentVariables) { env[var.Key] = var.Value; } // The second parameter of CreateProcess is the command line, and it includes the application being launched string cmdLine = "\"" + startInfo.Command + "\" " + startInfo.Arguments; int flags = 0; if (!startInfo.UseExternalConsole) { flags = 0x08000000; /* CREATE_NO_WINDOW*/ flags |= CorDebugger.CREATE_REDIRECT_STD; } process = dbg.CreateProcess(startInfo.Command, cmdLine, startInfo.WorkingDirectory, env, flags); processId = process.Id; process.OnCreateProcess += new CorProcessEventHandler(OnCreateProcess); process.OnCreateAppDomain += new CorAppDomainEventHandler(OnCreateAppDomain); process.OnAssemblyLoad += new CorAssemblyEventHandler(OnAssemblyLoad); process.OnAssemblyUnload += new CorAssemblyEventHandler(OnAssemblyUnload); process.OnCreateThread += new CorThreadEventHandler(OnCreateThread); process.OnThreadExit += new CorThreadEventHandler(OnThreadExit); process.OnModuleLoad += new CorModuleEventHandler(OnModuleLoad); process.OnModuleUnload += new CorModuleEventHandler(OnModuleUnload); process.OnProcessExit += new CorProcessEventHandler(OnProcessExit); process.OnUpdateModuleSymbols += new UpdateModuleSymbolsEventHandler(OnUpdateModuleSymbols); process.OnDebuggerError += new DebuggerErrorEventHandler(OnDebuggerError); process.OnBreakpoint += new BreakpointEventHandler(OnBreakpoint); process.OnStepComplete += new StepCompleteEventHandler(OnStepComplete); process.OnBreak += new CorThreadEventHandler(OnBreak); process.OnNameChange += new CorThreadEventHandler(OnNameChange); process.OnEvalComplete += new EvalEventHandler(OnEvalComplete); process.OnEvalException += new EvalEventHandler(OnEvalException); process.OnLogMessage += new LogMessageEventHandler(OnLogMessage); process.OnStdOutput += new CorTargetOutputEventHandler(OnStdOutput); process.OnException2 += new CorException2EventHandler(OnException2); process.Continue(false); OnStarted(); }
internal static void TearDownOutputRedirection(SafeFileHandle outReadPipe, SafeFileHandle errorReadPipe, STARTUPINFO si, CorProcess ret) { if (outReadPipe != null) { // Close pipe handles (do not continue to modify the parent). // You need to make sure that no handles to the write end of the // output pipe are maintained in this process or else the pipe will // not close when the child process exits and the ReadFile will hang. si.hStdInput.Close(); si.hStdOutput.Close(); si.hStdError.Close(); ret.TrackStdOutput(outReadPipe, errorReadPipe); } }