public static void Do(bool online) { var frontDir = DetermineVersion.DetermineWebSiteFolder(); var onlineFile = Path.Combine(frontDir, "IsOnline.aspx"); var isonline = File.Exists(onlineFile); if (isonline != online) { var offlineFile = Path.Combine(frontDir, "IsOnline.offline.aspx"); if (online) { var offlineFile2 = Path.Combine(frontDir, "IsOnline.off.aspx"); if (File.Exists(offlineFile)) { File.Move(offlineFile, onlineFile); } else if (File.Exists(offlineFile2)) { File.Move(offlineFile2, onlineFile); } } else { File.Move(onlineFile, offlineFile); } } }
public static Tuple <string, string> ReadServerPath(string serverPath, Dictionary <string, string> fileMappings) { var s = serverPath.Split(':'); var server = s.Length == 2 ? s[0] : string.Empty; var path = s.Length == 2 ? s[1] : s[0]; if (server.Length < 2) { server = string.Empty; path = serverPath; } string result; if (fileMappings != null && fileMappings.TryGetValue(path, out result)) { path = result; } else if (fileMappings != null) { if (!fileMappings.Values.Contains(path)) { // throw new InvalidOperationException("Illegal path"); } } if (path.Contains("$front")) { path = path.Replace("$front", DetermineVersion.DetermineWebSiteFolder()); } return(new Tuple <string, string>(server, path)); }
public static void DoCommand(Socket peer, Stream input, Stream output, Dictionary <string, string> fileMappings, Dictionary <Regex, string> colorMappings) { using (input) { var crash = false; try { var line = ReadLine(input); var i3 = line.LastIndexOf((char)3); if (i3 != -1) { line = line.Substring(i3 + 1); } var lineOrig = line; line = line.ToLowerInvariant(); switch (line) { case "age": { var serverPath = ReadServerPath(ReadLine(input), fileMappings); var server = serverPath.Item1; var path = serverPath.Item2; var ms = new MemoryStream(); FileTailer.Tail(server, path, 1, false, ms); var str = Encoding.ASCII.GetString(ms.ToArray()); str = str.Substring(0, Math.Min(str.Length, 100)).Replace(",", "."); string os = null; var endsWithU = false; while (str.Length > 0) { DateTime dt; if (DateTime.TryParse(str, CultureInfo.InvariantCulture, endsWithU ? DateTimeStyles.AssumeUniversal : DateTimeStyles.AssumeLocal, out dt)) { os = ((long)(DateTime.Now - dt).TotalSeconds).ToString(); break; } endsWithU = str.EndsWith("U") && !str.EndsWith(" U"); str = str.Substring(0, str.Length - 1); } Write(os ?? "null", output); break; } case "apppools": { Shell.Do(peer, input, output, @"c:\windows\system32\inetsrv\appcmd", "list apppool /config /xml", false); break; } case "bend": { Remote.Do(peer, input, output); break; } case "buildtime": { Write(Environment.MachineName + " " + Date(BuildDate.RetrieveLinkerTimestamp()) + "\r\n", output); break; } case "crash": { crash = true; throw new InvalidOperationException(); } case "date": { var serverPath = ReadServerPath(ReadLine(input), fileMappings); var server = serverPath.Item1; var path = serverPath.Item2; var pattern = ReadLine(input); DateFinder.Find(new LogStream(server, path), output, pattern); break; } case "download": { var path = ReadLine(input); Zip.Download(path, output); break; } case "downloadzip": { var path = ReadLine(input); Zip.Zipit(path, output); break; } case "dump": { var path = ReadLine(input); var process = ReadLine(input); DumpFile.Create(path, process); break; } case "filecount": { var serverPath = ReadServerPath(ReadLine(input), fileMappings); var path = Path.GetDirectoryName(serverPath.Item2); var pattern = Path.GetFileName(serverPath.Item2); Write(Directory.GetFiles(path, pattern).Length.ToString(CultureInfo.InvariantCulture), output); break; } case "fulldump": { var enable = int.Parse(ReadLine(input)); DumpConfig.Enable(enable != 0); break; } case "fulldumpenabled": { var enabled = DumpConfig.IsEnabled(); Write(enabled ? "1" : "0", output); break; } case "isonline": { Write(Environment.MachineName + " ", output); FetchUri.FetchHeaders("http://localhost/IsOnline.aspx", output); Write($" {Path.GetFileName(Path.GetDirectoryName(DetermineVersion.DetermineWebSiteFolder()))} \r\n", output); break; } case "isonline2": { FetchUri.FetchHeaders("http://localhost/IsOnline.aspx", output); break; } case "ls": { foreach (var fi in LogStream.GetLocalFileInfos(ReadLine(input))) { Write($"- 1 root root {fi.Size} {fi.Modification.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture)} {fi.Name}\n", output); } break; } case "mem": { MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX(); if (GlobalMemoryStatusEx(memStatus)) { Write($"{Math.Round((double)memStatus.ullTotalPhys / (1024 * 1024 * 1024))} GB", output); } break; } case "netrelease": { var release = Convert.ToInt64(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", "Release", null)); Write(release.ToString(CultureInfo.InvariantCulture), output); break; } case "ntp": { Shell.Do(peer, input, output, "ntpq.exe", "-np", false); break; } case "offline": { Online.Do(false); break; } case "online": { Online.Do(true); break; } case "patch": { List <string> args = new List <string>(); string arg; while ((arg = ReadLine(input)).Length > 0) { args.Add(arg); } bool rebootIfNeeded = args.Contains("reboot"); bool onlyList = args.Contains("onlylist"); Patch patch = new Patch(); patch.InstallPatches(rebootIfNeeded, onlyList, output); break; } case "pc": { var counter = ReadLine(input); Write(PerformanceCounter.GetValue(counter).ToString(CultureInfo.InvariantCulture), output); break; } case "post / http/1.0": case "post / http/1.1": { Http.Do(input, fileMappings, colorMappings); break; } case "powershell": { List <string> scripts = new List <string>(); string arg; while ((arg = ReadLine(input)).Length > 0) { scripts.Add(arg); } foreach (string script in scripts) { Shell.Do(peer, input, output, "powershell.exe", $"-file {script}", false); } break; } case "rpc": { var counter = ReadLine(input); var specs = (ReadLine(input) ?? "0").Split('|'); var index = int.Parse(specs[0]); if (index == 4) { Write(Date(PerformanceCounterClient.GetDate(counter)), output); } else { var value = PerformanceCounterClient.GetValue(counter, index); Write(value.ToString(CultureInfo.InvariantCulture), output); if (specs.Length == 2) { Write("\n", output); switch (specs[1].ToLowerInvariant()) { case "timespan": Write(TimeSpan.FromSeconds(value) + "\n", output); break; } } } break; } case "shell": { Shell.Do(peer, input, output); break; } case "sites": { Shell.Do(peer, input, output, @"c:\windows\system32\inetsrv\appcmd", "list site /config /xml", false); break; } case "stacktrace": case "stacktracenative": case "verifyheap": { var pidOrSpec = GetPid2(ReadLine(input)); switch (line) { case "stacktrace": StackTrace.DoManaged(peer, output, pidOrSpec); break; case "stacktracenative": StackTrace.DoNative(peer, output, pidOrSpec); break; case "verifyheap": StackTrace.VerifyHeap(peer, output, pidOrSpec); break; } break; } case "systeminfo": { Shell.Do(peer, input, output, "systeminfo.exe", "", false); break; } case "tail": { var serverPath = ReadServerPath(ReadLine(input), fileMappings); var server = serverPath.Item1; var path = serverPath.Item2; var countLine = ReadLine(input); int count = 0; if (!string.IsNullOrEmpty(countLine)) { count = int.Parse(countLine); } line = ReadLine(input); bool tail = false; if (!string.IsNullOrEmpty(line)) { tail = int.Parse(line) != 0; } FileTailer.Tail(server, path, count, tail, output); break; } case "tailc": { using (var fs = new FileStream(ReadLine(input), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { fs.Position = long.Parse(ReadLine(input)); fs.CopyTo(output); } break; } case "tasklist": { Shell.Do(peer, input, output, "tasklist.exe", "", false); break; } case "tasklistj": { Tasklist.JavaScript(output); break; } case "tasklistl": { Shell.Do(peer, input, output, "tasklist.exe", "/FO LIST", false); break; } case "tickcount": { var tc = Environment.TickCount; var now = DateTime.Now; var prev = -(long)int.MinValue + tc; var next = (long)int.MaxValue - tc; var bytes = Encoding.ASCII.GetBytes(Environment.MachineName + " Environment.TickCount is " + Environment.TickCount + " previous " + Date(now - TimeSpan.FromMilliseconds(prev)) + " next " + Date(now + TimeSpan.FromMilliseconds(next)) + " uptime " + GetUpTime() + "\r\n"); output.Write(bytes, 0, bytes.Length); break; } case "tickcount2": { Write(Environment.TickCount.ToString(CultureInfo.InvariantCulture), output); break; } case "tickcounts": { var tc = Environment.TickCount; var secs = ((double)int.MaxValue - tc) / 1000.0; Write(secs.ToString(CultureInfo.InvariantCulture) + "\n", output); Write(Date(DateTime.UtcNow.AddSeconds(secs)) + "\n", output); break; } case "time": { Write(Environment.MachineName + " " + Date() + "\r\n", output); break; } case "time2": { Write(Date(), output); break; } case "update": { var sourcePath = ReadLine(input); var destPath = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); var arguments = string.Format("/C net stop \"{0}\" && timeout /t 5 /nobreak && move /y \"{1}\\*\" \"{2}\" && net start \"{0}\"", Program.ServiceName, sourcePath, destPath); Shell.Spawn(arguments); break; } case "upload": { var path = ReadLine(input); Zip.Upload(path, input); break; } case "uploadzip": { var path = ReadLine(input); Zip.Unzipit(path, input); break; } case "uptime": { Write(GetUpTime().ToString(), output); break; } case "uptime2": { var tc = GetTickCount64(); Write((tc / 1000.0).ToString(CultureInfo.InvariantCulture) + "\n", output); Write(TimeSpan.FromMilliseconds(tc) + "\n", output); break; } case "uri": { var path = ReadLine(input); FetchUri.Fetch(path, output); break; } case "users": { Shell.Do(peer, input, output, "query.exe", "user", false); break; } case "version": case "version2": case "version3": { var pid = GetPid(ReadLine(input)); if (pid != -1) { DetermineVersion.Do(pid, output, line == "version" ? " " : (line == "version2" ? null : "\n")); } break; } case "wertrace": { var process = ReadLine(input); StackTrace.OpenWerDump(peer, output, process); break; } default: if (line.StartsWith("get /")) { Http.Do(lineOrig, input, fileMappings, colorMappings); } else { throw new InvalidOperationException($"Unknown command {line}."); } break; } } catch (Exception e) { if (crash) { throw; } if (!(e is IOException)) { LogError(e); } } } }
private static void Do(Socket peer, Stream output, string pidOrSpec, IEnumerable <string> commands) { const string key = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"; const string value = @"WinHttpSettings"; // netsh.exe winhttp set proxy proxy-server="a" bypass-list="*" var fakeProxy = new byte[] { 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, 0x00, 0x2a }; var old = Registry.GetValue(key, value, null); try { Registry.SetValue(key, value, fakeProxy); } catch (UnauthorizedAccessException) { } var tf = Path.GetTempFileName(); Directory.CreateDirectory(@"c:\symbols"); string sosPath = string.Empty; int pid = -1; if (!int.TryParse(pidOrSpec, out pid)) { pid = -1; } if (pid != -1) { var p = Process.GetProcessById(pid); foreach (ProcessModule module in p.Modules) { var path = Path.GetDirectoryName(module.FileName); if (!string.IsNullOrEmpty(path) && path.StartsWith(@"C:\Windows\Microsoft.NET\Framework64\") && Path.GetFileName(module.FileName) == "clr.dll") { sosPath = path; break; } } } else { sosPath = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"; } using (var fs = File.OpenWrite(tf)) { using (var wr = new StreamWriter(fs)) { // wr.WriteLine(@"!sym noisy"); var path = DetermineVersion.DetermineWebSiteFolder(); if (!string.IsNullOrEmpty(path)) { path += "\\bin;"; } wr.WriteLine(@".sympath {0}cache*c:\symbols;srv*http://msdl.microsoft.com/download/symbols", path); wr.WriteLine(@".load {0}\sos.dll", sosPath); // needs to be explicitly specified - $PATH may not be set correctly? wr.WriteLine(".reload"); foreach (var command in commands) { wr.WriteLine(command); } wr.WriteLine("qd"); } } var attachArguments = pid != -1 ? $"-p {pid}" : $"-z \"{pidOrSpec}\""; Shell.Do(peer, null, output, @"C:\Program Files\Windows Kits\10\Debuggers\x64\cdb.exe", $"{attachArguments} -cfr \"{tf}\"", false); try { Registry.SetValue(key, value, old); } catch (UnauthorizedAccessException) { } File.Delete(tf); }