Tool for checking the integrity of an AME installation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

672 lines
25 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Threading;
  8. using System.Runtime.InteropServices;
  9. using System.ServiceProcess;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using Microsoft.Win32;
  13. namespace ame_integrity_check
  14. {
  15. public enum Type
  16. {
  17. File = 1,
  18. Directory = 2,
  19. Process = 3,
  20. Service = 4
  21. }
  22. internal class Scanner : IDisposable
  23. {
  24. private int result = 1;
  25. private bool allFound = true;
  26. private bool found = false;
  27. private bool errorOverride = false;
  28. public Task<bool> displayTask;
  29. public void Dispose() => GC.SuppressFinalize(this);
  30. public async Task<bool> DisplayQuery(string text, int time = 150)
  31. {
  32. Out.WriteCustomString(text, 3, 11);
  33. string maxSpaces = " ";
  34. for (int i = 1; i < 6; i++) {
  35. Console.SetCursorPosition(59, Console.CursorTop);
  36. var spaces = maxSpaces.Remove(0, i);
  37. Console.Write($"[ {spaces.PadLeft(spaces.Length + i, '*')} ]");
  38. Thread.Sleep(time);
  39. }
  40. return true;
  41. }
  42. private static void SetQueryStatus(string status, ConsoleColor color)
  43. {
  44. Console.SetCursorPosition(64 - status.Length, Console.CursorTop);
  45. Console.Write(" [ ");
  46. Out.WriteCustomString(status, 3, 0, foregroundColor: color);
  47. Console.WriteLine(" ]");
  48. }
  49. public async void Query(Type type, string item, bool finalize = false, bool modifyResult = true)
  50. {
  51. item = Environment.ExpandEnvironmentVariables(item);
  52. bool foundItem = false;
  53. try {
  54. switch (type) {
  55. case Type.File:
  56. if (item.Contains("*"))
  57. {
  58. var lastToken = item.LastIndexOf("\\");
  59. var parentPath = item.Remove(lastToken).TrimEnd('\\');
  60. if (parentPath.Contains("*")) throw new ArgumentException("Parent directories to a given file filter cannot contain wildcards.");
  61. var filter = item.Substring(lastToken + 1);
  62. foundItem = Directory.GetFiles(parentPath, filter).Any();
  63. break;
  64. }
  65. foundItem = File.Exists(item);
  66. break;
  67. case Type.Directory:
  68. if (item.Contains("*"))
  69. {
  70. var lastToken = item.LastIndexOf("\\");
  71. var parentPath = item.Remove(lastToken).TrimEnd('\\');
  72. if (parentPath.Contains("*")) throw new ArgumentException("Parent directories to a given file filter cannot contain wildcards.");
  73. var filter = item.Substring(lastToken + 1);
  74. var foundDirs = Directory.GetDirectories(parentPath, filter);
  75. foreach (var foundDir in foundDirs)
  76. {
  77. foreach (var file in Directory.GetFiles(foundDir, "*", SearchOption.AllDirectories))
  78. {
  79. if (!file.ToLower().EndsWith(".mui") && !file.ToLower().EndsWith(".pri") && !file.ToLower().EndsWith(".res"))
  80. {
  81. foundItem = true;
  82. }
  83. }
  84. }
  85. }
  86. else
  87. {
  88. if (Directory.Exists(item))
  89. {
  90. foreach (var file in Directory.GetFiles(item, "*", SearchOption.AllDirectories))
  91. {
  92. if (!file.ToLower().EndsWith(".mui") && !file.ToLower().EndsWith(".pri") && !file.ToLower().EndsWith(".res"))
  93. {
  94. foundItem = true;
  95. }
  96. }
  97. }
  98. }
  99. break;
  100. case Type.Process:
  101. foundItem = Process.GetProcessesByName(item).Any();
  102. break;
  103. case Type.Service:
  104. foundItem = ServiceController.GetServices().Any(x => x.ServiceName.Equals("wuauserv", StringComparison.CurrentCultureIgnoreCase));
  105. break;
  106. default:
  107. foundItem = false;
  108. break;
  109. }
  110. } catch (Exception e) {
  111. if (e.GetType().ToString() == "System.UnauthorizedAccessException" || e.GetType().ToString() == "System.Security.SecurityException")
  112. {
  113. foundItem = true;
  114. }
  115. else
  116. {
  117. errorOverride = true;
  118. }
  119. }
  120. if (foundItem) found = true;
  121. if (!finalize) return;
  122. await displayTask;
  123. if (errorOverride) {
  124. errorOverride = false;
  125. SetQueryStatus("ERROR", ConsoleColor.DarkRed);
  126. found = false;
  127. return;
  128. }
  129. if (!found) {
  130. if (modifyResult) allFound = false;
  131. SetQueryStatus("Absent", ConsoleColor.Green);
  132. } else {
  133. result = 2;
  134. if (allFound) result = 3;
  135. SetQueryStatus("Present", ConsoleColor.DarkRed);
  136. }
  137. found = false;
  138. }
  139. public void DisplayResult()
  140. {
  141. switch (result) {
  142. case 1:
  143. Out.WriteCustomString("\n\nAME Integrity validated", 1, foregroundColor: ConsoleColor.Green);
  144. break;
  145. case 2:
  146. Out.WriteCustomString("\n\nAME integrity compromised, contact the team for help.", 1, foregroundColor: ConsoleColor.Red);
  147. break;
  148. case 3:
  149. Out.WriteCustomString("\n\nYour system is not ameliorated.", 1, foregroundColor: ConsoleColor.Red);
  150. break;
  151. }
  152. }
  153. }
  154. internal static class Program
  155. {
  156. public static string PreviousTitle;
  157. public static int PreviousBufferHeight;
  158. public static int PreviousBufferWidth;
  159. public static int PreviousSizeHeight;
  160. public static int PreviousSizeWidth;
  161. public const string Ver = "1.0";
  162. public static void Main(string[] args)
  163. {
  164. PreviousSizeHeight = Console.WindowHeight;
  165. PreviousSizeWidth = Console.WindowWidth;
  166. PreviousBufferHeight = Console.BufferHeight;
  167. PreviousBufferWidth = Console.BufferWidth;
  168. try
  169. {
  170. Console.SetWindowSize(80, 26);
  171. Console.SetBufferSize(80, 26);
  172. Console.SetWindowSize(80, 26);
  173. } catch (Exception e)
  174. {
  175. }
  176. Console.Clear();
  177. Console.CursorVisible = false;
  178. PreviousTitle = Console.Title;
  179. Console.Title = "AME Integrity Check";
  180. try { Out.DisableResize(); } catch (Exception) { }
  181. try { Out.DisableQuickEdit(); } catch (Exception) { }
  182. Console.CancelKeyPress += Exit;
  183. Out.WriteCustomString("\n__________________________________________________________" +
  184. $"\n\n| AME Integrity Check v{Ver} |\n\n", 1);
  185. displayStart:
  186. Menu mainMenu = new Menu() {
  187. Choices = {"Check AME Integrity", "Get Support", "", "Exit"},
  188. EndString = "\n__________________________________________________________\n",
  189. Statement = "Use the arrows keys to navigate"
  190. };
  191. var choice = mainMenu.Load();
  192. switch (choice) {
  193. case 0:
  194. RunCheck();
  195. Out.ResetPane();
  196. goto displayStart;
  197. case 1:
  198. Process.Start("https://t.me/joinchat/CR-xFBGQKVt7HPZKgZfbxg");
  199. Out.ResetPane();
  200. goto displayStart;
  201. case 2:
  202. PrepProcessExit();
  203. Environment.Exit(0);
  204. break;
  205. default:
  206. PrepProcessExit();
  207. Environment.Exit(1);
  208. break;
  209. }
  210. }
  211. private static bool detected = false;
  212. private static int result = 1;
  213. private static void RunCheck()
  214. {
  215. Out.ResetPane();
  216. bool legacy = false;
  217. var registryKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
  218. int winVer = 1;
  219. if (registryKey != null) winVer = Int32.Parse(registryKey.GetValue("CurrentBuildNumber").ToString());
  220. if (winVer < 19044) legacy = true;
  221. using (var scanner = new Scanner())
  222. {
  223. scanner.displayTask = scanner.DisplayQuery("Checking for Windows Defender activity...", 250);
  224. scanner.Query(Type.Process, "MsMpEng", true);
  225. scanner.displayTask = scanner.DisplayQuery("Checking Windows Defender files...", 200);
  226. if (!legacy) {
  227. scanner.Query(Type.Directory, "%ProgramFiles%\\Windows Defender");
  228. scanner.Query(Type.Directory, "%ProgramData%\\Microsoft\\Windows Defender", true);
  229. }
  230. else scanner.Query(Type.Directory, "%ProgramFiles%\\Windows Defender", true);
  231. if (!legacy) {
  232. scanner.displayTask = scanner.DisplayQuery("Checking Windows Update service...", 350);
  233. scanner.Query(Type.Service, "wuauserv", true);
  234. }
  235. scanner.displayTask = scanner.DisplayQuery("Checking Windows Update files...", 220);
  236. scanner.Query(Type.File, "%WINDIR%\\System32\\wuaueng.dll");
  237. scanner.Query(Type.File, "%WINDIR%\\System32\\wuapi.dll", true);
  238. scanner.displayTask = scanner.DisplayQuery("Checking Microsoft Edge...", 200);
  239. scanner.Query(Type.Directory, "%ProgramFiles(x86)%\\Microsoft\\Edge");
  240. scanner.Query(Type.Directory, "%WINDIR%\\SystemApps\\*MicrosoftEdge*", true);
  241. scanner.displayTask = scanner.DisplayQuery("Checking for Microsoft Store activity...", 200);
  242. scanner.Query(Type.Process, "WinStore.App", true, false);
  243. scanner.displayTask = scanner.DisplayQuery("Checking Windows SmartScreen...");
  244. scanner.Query(Type.Process, "smartscreen");
  245. scanner.Query(Type.File, "%WINDIR%\\System32\\smartscreen.exe", true);
  246. scanner.displayTask = scanner.DisplayQuery("Checking SIH Client...");
  247. scanner.Query(Type.File, "%WINDIR%\\System32\\SIHClient.exe", true);
  248. scanner.displayTask = scanner.DisplayQuery("Checking Storage Sense...", 300);
  249. scanner.Query(Type.File, "%WINDIR%\\System32\\StorSvc.dll", true);
  250. scanner.DisplayResult();
  251. }
  252. Out.WriteCustomString("__________________________________________________________\n\n\nPress any key to return to the Menu: ", 3, 11);
  253. ClearBuffer();
  254. Console.CursorVisible = true;
  255. Console.ReadKey(false);
  256. Console.CursorVisible = false;
  257. }
  258. private static bool anyNotPresent;
  259. private static void ClearBuffer()
  260. {
  261. var posCacheTop = Console.CursorTop;
  262. var posCacheLeft = Console.CursorLeft;
  263. while (Console.KeyAvailable) {
  264. Console.ReadKey(true);
  265. }
  266. //Console.SetCursorPosition(posCacheLeft, posCacheTop);
  267. //Console.Write("".PadLeft(Console.WindowHeight, ' '));
  268. //Console.SetCursorPosition(posCacheLeft, posCacheTop);
  269. }
  270. private static void Exit(object sender, ConsoleCancelEventArgs args)
  271. {
  272. PrepProcessExit();
  273. Environment.Exit(0);
  274. }
  275. private static void PrepProcessExit()
  276. {
  277. var parent = ParentProcess.ProcessName;
  278. if (parent.Equals("Explorer", StringComparison.CurrentCultureIgnoreCase)) return;
  279. try { Out.EnableResize(); } catch (Exception) { }
  280. try { Out.EnableQuickEdit(); } catch (Exception) { }
  281. Console.CursorVisible = true;
  282. Console.Clear();
  283. Console.Title = PreviousTitle;
  284. try
  285. {
  286. Console.SetWindowSize(PreviousSizeWidth, PreviousSizeHeight);
  287. Console.SetBufferSize(PreviousBufferWidth, PreviousBufferHeight);
  288. } catch (Exception e)
  289. {
  290. }
  291. }
  292. }
  293. internal static class Out
  294. {
  295. public static void ResetPane(int fromTop = 6)
  296. {
  297. Console.SetCursorPosition(Console.CursorLeft, fromTop - 1);
  298. var length = Console.WindowHeight - fromTop - 1;
  299. for (int i = 0; i < length; i++) {
  300. Console.Write("".PadRight(Console.WindowWidth, ' '));
  301. }
  302. Console.SetCursorPosition(0, fromTop);
  303. }
  304. public static void WriteCustomString(string text, int type, int offset = 11, ConsoleColor foregroundColor = ConsoleColor.DarkYellow, ConsoleColor backgroundColor = ConsoleColor.DarkYellow)
  305. {
  306. bool resetColor = false;
  307. ConsoleColor foregroundCache = Console.ForegroundColor;
  308. ConsoleColor backgroundCache = Console.BackgroundColor;
  309. if (foregroundColor == ConsoleColor.DarkYellow) {
  310. foregroundColor = Console.ForegroundColor;
  311. }
  312. if (backgroundColor == ConsoleColor.DarkYellow) {
  313. backgroundColor = Console.BackgroundColor;
  314. }
  315. if (Console.ForegroundColor != foregroundColor) {
  316. resetColor = true;
  317. Console.ForegroundColor = foregroundColor;
  318. }
  319. if (Console.BackgroundColor != backgroundColor) {
  320. resetColor = true;
  321. Console.BackgroundColor = backgroundColor;
  322. }
  323. switch (type) {
  324. case 1:
  325. // Indented and centered
  326. Console.WriteLine(CenterString(text, offset));
  327. break;
  328. case 2:
  329. Console.WriteLine(text.Insert(0, new string(' ', offset)));
  330. break;
  331. case 3:
  332. var loopOnce = false;
  333. foreach (string line in text.Split('\n')) {
  334. if (line == "") {
  335. Console.WriteLine();
  336. continue;
  337. }
  338. Console.Write(line.Insert(0, new string(' ', offset)));
  339. }
  340. break;
  341. default:
  342. break;
  343. }
  344. if (resetColor) {
  345. Console.ForegroundColor = foregroundCache;
  346. Console.BackgroundColor = backgroundCache;
  347. }
  348. }
  349. private static string CenterString(string text, int offset = 11, int width = 58)
  350. {
  351. StringBuilder subLines = new StringBuilder();
  352. string newLine = "";
  353. foreach (string line in text.Split('\n')) {
  354. if (!subLines.ToString().Equals("")) newLine = "\n";
  355. if (line == "" && !subLines.ToString().Equals("")) {
  356. subLines.Append("\n");
  357. continue;
  358. }
  359. var space = "";
  360. if (!(line.Length % 2).Equals(0) && line.Length != width) {
  361. space = " ";
  362. }
  363. if (line.Length > width) {
  364. for (int index = 0; index < line.Length; index += (width - 10)) {
  365. if (!subLines.ToString().Equals("")) newLine = "\n";
  366. var subLine = line.Substring(index, Math.Min(width - 10, line.Length - index));
  367. subLine = subLine.Trim(' ');
  368. var subCentered = CenterString(subLine, offset, width);
  369. subLines.Append(newLine + subCentered);
  370. }
  371. continue;
  372. }
  373. var leadingLength = (width - line.Length) / 2;
  374. subLines.Append(newLine + space + line.PadLeft(line.Length + leadingLength, ' ').Insert(0, new string(' ', offset)));
  375. }
  376. return subLines.ToString();
  377. }
  378. private const int MF_BYCOMMAND = 0x00000000;
  379. public const int SC_CLOSE = 0xF060;
  380. public const int SC_MINIMIZE = 0xF020;
  381. public const int SC_MAXIMIZE = 0xF030;
  382. public const int SC_SIZE = 0xF000;//resize
  383. [DllImport("user32.dll")]
  384. public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);
  385. [DllImport("user32.dll")]
  386. private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
  387. [DllImport("kernel32.dll", ExactSpelling = true)]
  388. private static extern IntPtr GetConsoleWindow();
  389. public static void DisableResize()
  390. {
  391. IntPtr handle = GetConsoleWindow();
  392. IntPtr sysMenu = GetSystemMenu(handle, false);
  393. if (handle != IntPtr.Zero)
  394. {
  395. //DeleteMenu(sysMenu, SC_CLOSE, MF_BYCOMMAND);
  396. //DeleteMenu(sysMenu, SC_MINIMIZE, MF_BYCOMMAND);
  397. DeleteMenu(sysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
  398. DeleteMenu(sysMenu, SC_SIZE, MF_BYCOMMAND);//resize
  399. }
  400. }
  401. public static void EnableResize()
  402. {
  403. IntPtr handle = GetConsoleWindow();
  404. GetSystemMenu(handle, true);
  405. }
  406. const uint CHECK_QUICK_EDIT = 0x0040;
  407. const int ENABLE_QUICK_EDIT = 0x40 | 0x80;
  408. // STD_INPUT_HANDLE (DWORD): -10 is the standard input device.
  409. const int STD_INPUT_HANDLE = -10;
  410. [DllImport("kernel32.dll", SetLastError = true)]
  411. static extern IntPtr GetStdHandle(int nStdHandle);
  412. [DllImport("kernel32.dll")]
  413. static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
  414. [DllImport("kernel32.dll")]
  415. static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
  416. internal static void DisableQuickEdit() {
  417. IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
  418. // get current console mode
  419. uint consoleMode;
  420. GetConsoleMode(consoleHandle, out consoleMode);
  421. // set the new mode
  422. SetConsoleMode(consoleHandle, consoleMode &= ~CHECK_QUICK_EDIT);
  423. }
  424. internal static void EnableQuickEdit() {
  425. IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
  426. // get current console mode
  427. uint consoleMode;
  428. GetConsoleMode(consoleHandle, out consoleMode);
  429. // set the new mode
  430. SetConsoleMode(consoleHandle, consoleMode|(ENABLE_QUICK_EDIT));
  431. }
  432. }
  433. internal class Menu
  434. {
  435. public List<string> Choices;
  436. public string EndString;
  437. public string Statement;
  438. public int Offset;
  439. public Menu(int offset = 16, string endString = null)
  440. {
  441. Choices = new List<string>();
  442. EndString = endString;
  443. Offset = offset;
  444. }
  445. public int Load()
  446. {
  447. int max = -1;
  448. var posCache = Console.CursorTop;
  449. bool loopedOnce = false;
  450. foreach (string choice in Choices) {
  451. Console.SetCursorPosition(Offset - 2, Console.CursorTop);
  452. if (!loopedOnce) {
  453. Out.WriteCustomString("> " + choice, 2, 0, foregroundColor: ConsoleColor.Green);
  454. loopedOnce = true;
  455. } else {
  456. Out.WriteCustomString(choice, 2, 2);
  457. }
  458. max += 1;
  459. }
  460. if (EndString != null) Out.WriteCustomString(EndString, 1);
  461. if (Statement != null) Out.WriteCustomString(Statement, 2);
  462. int index = 0;
  463. ConsoleKey keyPressed;
  464. Console.SetCursorPosition(Offset, posCache);
  465. while ((keyPressed = Console.ReadKey(true).Key) != ConsoleKey.Enter) {
  466. if (keyPressed == ConsoleKey.DownArrow) {
  467. if (index >= max) continue;
  468. Console.SetCursorPosition(Offset - 2, Console.CursorTop);
  469. Out.WriteCustomString(Choices[index], 3, 2);
  470. if (!String.IsNullOrEmpty(Choices[index + 1])) {
  471. index += 1;
  472. Console.SetCursorPosition(Offset - 2, Console.CursorTop + 1);
  473. Out.WriteCustomString("> " + Choices[index], 3, 0, foregroundColor: ConsoleColor.Green);
  474. } else {
  475. index += 2;
  476. Console.SetCursorPosition(Offset - 2, Console.CursorTop + 2);
  477. Out.WriteCustomString("> " + Choices[index], 3, 0, foregroundColor: ConsoleColor.Green);
  478. }
  479. }
  480. if (keyPressed == ConsoleKey.UpArrow) {
  481. if (!(index > 0)) continue;
  482. Console.SetCursorPosition(Offset - 2, Console.CursorTop);
  483. Out.WriteCustomString(Choices[index], 3, 2);
  484. if (!String.IsNullOrEmpty(Choices[index - 1])) {
  485. index -= 1;
  486. Console.SetCursorPosition(Offset - 2, Console.CursorTop - 1);
  487. Out.WriteCustomString("> " + Choices[index], 3, 0, foregroundColor: ConsoleColor.Green);
  488. } else {
  489. index -= 2;
  490. Console.SetCursorPosition(Offset - 2, Console.CursorTop - 2);
  491. Out.WriteCustomString("> " + Choices[index], 3, 0, foregroundColor: ConsoleColor.Green);
  492. }
  493. }
  494. }
  495. return index;
  496. }
  497. }
  498. public static class ParentProcess
  499. {
  500. public static string ProcessName
  501. {
  502. get { return GetParentProcess().ProcessName; }
  503. }
  504. private static Process GetParentProcess()
  505. {
  506. int iParentPid = 0;
  507. int iCurrentPid = Process.GetCurrentProcess().Id;
  508. IntPtr oHnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  509. if (oHnd == IntPtr.Zero)
  510. return null;
  511. PROCESSENTRY32 oProcInfo = new PROCESSENTRY32();
  512. oProcInfo.dwSize =
  513. (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESSENTRY32));
  514. if (Process32First(oHnd, ref oProcInfo) == false)
  515. return null;
  516. do
  517. {
  518. if (iCurrentPid == oProcInfo.th32ProcessID)
  519. iParentPid = (int)oProcInfo.th32ParentProcessID;
  520. }
  521. while (iParentPid == 0 && Process32Next(oHnd, ref oProcInfo));
  522. if (iParentPid > 0)
  523. return Process.GetProcessById(iParentPid);
  524. else
  525. return null;
  526. }
  527. static uint TH32CS_SNAPPROCESS = 2;
  528. [StructLayout(LayoutKind.Sequential)]
  529. public struct PROCESSENTRY32
  530. {
  531. public uint dwSize;
  532. public uint cntUsage;
  533. public uint th32ProcessID;
  534. public IntPtr th32DefaultHeapID;
  535. public uint th32ModuleID;
  536. public uint cntThreads;
  537. public uint th32ParentProcessID;
  538. public int pcPriClassBase;
  539. public uint dwFlags;
  540. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  541. public string szExeFile;
  542. };
  543. [DllImport("kernel32.dll", SetLastError = true)]
  544. static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
  545. [DllImport("kernel32.dll")]
  546. static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
  547. [DllImport("kernel32.dll")]
  548. static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
  549. }
  550. }