From 9d8072d7670a32ef1417e5ae38398645c71ef9e1 Mon Sep 17 00:00:00 2001 From: Pdawg11239 <83825746+Pdawg-bytes@users.noreply.github.com> Date: Sat, 15 Mar 2025 00:09:47 -0400 Subject: [PATCH] Add source --- BadBuilder.sln | 22 +++++ BadBuilder/BadBuilder.csproj | 25 ++++++ BadBuilder/ConsoleExperiences/DiskMenu.cs | 52 ++++++++++++ BadBuilder/Helpers/DiskHelper.cs | 52 ++++++++++++ BadBuilder/Helpers/DownloadHelper.cs | 47 +++++++++++ BadBuilder/Helpers/ResourceHelper.cs | 26 ++++++ BadBuilder/Models/DiskInfo.cs | 40 ++++++++++ BadBuilder/Program.cs | 93 ++++++++++++++++++++++ BadBuilder/Tools/fat32format.exe | Bin 0 -> 49218 bytes LICENSE | 7 +- 10 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 BadBuilder.sln create mode 100644 BadBuilder/BadBuilder.csproj create mode 100644 BadBuilder/ConsoleExperiences/DiskMenu.cs create mode 100644 BadBuilder/Helpers/DiskHelper.cs create mode 100644 BadBuilder/Helpers/DownloadHelper.cs create mode 100644 BadBuilder/Helpers/ResourceHelper.cs create mode 100644 BadBuilder/Models/DiskInfo.cs create mode 100644 BadBuilder/Program.cs create mode 100644 BadBuilder/Tools/fat32format.exe diff --git a/BadBuilder.sln b/BadBuilder.sln new file mode 100644 index 0000000..ea1b940 --- /dev/null +++ b/BadBuilder.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BadBuilder", "BadBuilder\BadBuilder.csproj", "{654D211A-668A-4BA4-8BD4-174A11666A3B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {654D211A-668A-4BA4-8BD4-174A11666A3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {654D211A-668A-4BA4-8BD4-174A11666A3B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {654D211A-668A-4BA4-8BD4-174A11666A3B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {654D211A-668A-4BA4-8BD4-174A11666A3B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/BadBuilder/BadBuilder.csproj b/BadBuilder/BadBuilder.csproj new file mode 100644 index 0000000..533bf2d --- /dev/null +++ b/BadBuilder/BadBuilder.csproj @@ -0,0 +1,25 @@ + + + + Exe + net8.0 + enable + enable + true + true + + + + + + + + + + + + + + + + diff --git a/BadBuilder/ConsoleExperiences/DiskMenu.cs b/BadBuilder/ConsoleExperiences/DiskMenu.cs new file mode 100644 index 0000000..fbae1e1 --- /dev/null +++ b/BadBuilder/ConsoleExperiences/DiskMenu.cs @@ -0,0 +1,52 @@ +using Spectre.Console; +using BadBuilder.Models; +using BadBuilder.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BadBuilder +{ + internal partial class Program + { + static string PromptForDiskSelection(List disks) + { + var choices = new List(); + foreach (var disk in disks) + choices.Add($"{disk.DriveLetter} ({disk.SizeFormatted}) - {disk.Type}"); + + return AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Select a disk to format:") + .HighlightStyle(GreenStyle) + .AddChoices(choices) + ); + } + + static bool PromptFormatConfirmation(string selectedDisk) + { + return AnsiConsole.Prompt( + new TextPrompt($"[#FF7200 bold]WARNING: [/]Are you sure you would like to format [bold]{selectedDisk.Substring(0, 3)}[/]? All data on this drive will be lost.") + .AddChoice(true) + .AddChoice(false) + .DefaultValue(false) + .ChoicesStyle(GreenStyle) + .DefaultValueStyle(OrangeStyle) + .WithConverter(choice => choice ? "y" : "n") + ); + } + + static async Task FormatDisk(List disks, string selectedDisk) + { + int diskIndex = disks.FindIndex(disk => $"{disk.DriveLetter} ({disk.SizeFormatted}) - {disk.Type}" == selectedDisk); + + await AnsiConsole.Status().StartAsync($"[#76B900]Formatting disk[/] {selectedDisk}", async ctx => + { + if (diskIndex == -1) return; + await DiskHelper.FormatDisk(disks[diskIndex]); + }); + } + } +} diff --git a/BadBuilder/Helpers/DiskHelper.cs b/BadBuilder/Helpers/DiskHelper.cs new file mode 100644 index 0000000..784c299 --- /dev/null +++ b/BadBuilder/Helpers/DiskHelper.cs @@ -0,0 +1,52 @@ +using BadBuilder.Models; +using System.Diagnostics; +using System.Management; + +namespace BadBuilder.Helpers +{ + internal static class DiskHelper + { + public static List GetDisks() + { + var disks = new List(); + + foreach (DriveInfo drive in DriveInfo.GetDrives()) + { + if (drive.IsReady) + { + string driveLetter = drive.Name; + string volumeLabel = drive.VolumeLabel; + string type = drive.DriveType.ToString(); + long totalSize = drive.TotalSize; + long availableFreeSpace = drive.AvailableFreeSpace; + int diskNumber = 2; + + disks.Add(new DiskInfo(driveLetter, type, totalSize, volumeLabel, availableFreeSpace, diskNumber)); + } + } + + return disks; + } + + internal static async Task FormatDisk(DiskInfo disk) + { + ResourceHelper.ExtractEmbeddedBinary("fat32format.exe"); + + Process process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = @"fat32format.exe", + Arguments = $"-c64 {disk.DriveLetter}", + RedirectStandardOutput = false, + RedirectStandardError = false, + UseShellExecute = false, + CreateNoWindow = true + } + }; + + process.Start(); + await process.WaitForExitAsync(); + } + } +} \ No newline at end of file diff --git a/BadBuilder/Helpers/DownloadHelper.cs b/BadBuilder/Helpers/DownloadHelper.cs new file mode 100644 index 0000000..80db9f1 --- /dev/null +++ b/BadBuilder/Helpers/DownloadHelper.cs @@ -0,0 +1,47 @@ +using Spectre.Console; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BadBuilder.Helpers +{ + internal static class DownloadHelper + { + internal static async Task DownloadFile(HttpClient client, ProgressTask task, string url) + { + try + { + using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) + { + response.EnsureSuccessStatusCode(); + + task.MaxValue(response.Content.Headers.ContentLength ?? 0); + task.StartTask(); + + string filename = url.Substring(url.LastIndexOf('/') + 1); + + using (var contentStream = await response.Content.ReadAsStreamAsync()) + using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) + { + var buffer = new byte[8192]; + while (true) + { + var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); + if (read == 0) + break; + + task.Increment(read); + await fileStream.WriteAsync(buffer, 0, read); + } + } + } + } + catch (Exception ex) + { + AnsiConsole.MarkupLine($"[red]Error downloading:[/] {ex}"); + } + } + } +} \ No newline at end of file diff --git a/BadBuilder/Helpers/ResourceHelper.cs b/BadBuilder/Helpers/ResourceHelper.cs new file mode 100644 index 0000000..9670667 --- /dev/null +++ b/BadBuilder/Helpers/ResourceHelper.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BadBuilder.Helpers +{ + internal static class ResourceHelper + { + internal static void ExtractEmbeddedBinary(string resourceName) + { + var assembly = Assembly.GetExecutingAssembly(); + string fullResourceName = $"BadBuilder.Tools.{resourceName}"; + + using (Stream resourceStream = assembly.GetManifestResourceStream(fullResourceName)) + { + if (resourceStream == null) return; + + using (FileStream fileStream = new FileStream($@"{resourceName}", FileMode.Create, FileAccess.Write)) + resourceStream.CopyTo(fileStream); + } + } + } +} \ No newline at end of file diff --git a/BadBuilder/Models/DiskInfo.cs b/BadBuilder/Models/DiskInfo.cs new file mode 100644 index 0000000..f385250 --- /dev/null +++ b/BadBuilder/Models/DiskInfo.cs @@ -0,0 +1,40 @@ +namespace BadBuilder.Models +{ + internal class DiskInfo + { + internal string DriveLetter { get; init; } + internal string VolumeLabel { get; init; } + internal int DiskNumber { get; init; } + + internal string Type { get; init; } + internal string SizeFormatted { get; init; } + internal long TotalSize { get; init; } + internal long AvailableFreeSpace { get; init; } + + internal DiskInfo(string driveLetter, string type, long totalSize, string volumeLabel, long availableFreeSpace, int diskNumber) + { + DriveLetter = driveLetter; + VolumeLabel = volumeLabel; + DiskNumber = diskNumber; + + Type = type; + SizeFormatted = FormatSize(totalSize); + TotalSize = totalSize; + AvailableFreeSpace = availableFreeSpace; + } + + private static string FormatSize(long bytes) + { + const double KB = 1024.0; + const double MB = KB * 1024; + const double GB = MB * 1024; + const double TB = GB * 1024; + + if (bytes >= TB) return $"{bytes / TB:F2} TB"; + if (bytes >= GB) return $"{bytes / GB:F2} GB"; + if (bytes >= MB) return $"{bytes / MB:F2} MB"; + if (bytes >= KB) return $"{bytes / KB:F2} KB"; + return $"{bytes} bytes"; + } + } +} diff --git a/BadBuilder/Program.cs b/BadBuilder/Program.cs new file mode 100644 index 0000000..d133e66 --- /dev/null +++ b/BadBuilder/Program.cs @@ -0,0 +1,93 @@ +using Spectre.Console; +using BadBuilder.Models; +using BadBuilder.Helpers; + +namespace BadBuilder +{ + internal partial class Program + { + static readonly Style OrangeStyle = new Style(new Color(255, 114, 0)); + static readonly Style GreenStyle = new Style(new Color(118, 185, 0)); + static readonly Style GrayStyle = new Style(new Color(132, 133, 137)); + + static void Main(string[] args) + { + ShowWelcomeMessage(); + + while (true) + { + Console.WriteLine(); + string action = PromptForAction(); + + if (action == "Exit") Environment.Exit(0); + + List disks = DiskHelper.GetDisks(); + string selectedDisk = PromptForDiskSelection(disks); + + bool confirmation = PromptFormatConfirmation(selectedDisk); + if (confirmation) + { + FormatDisk(disks, selectedDisk).Wait(); + break; + } + } + + Console.WriteLine(); + + var items = new (string name, string url)[] + { + ("rbblitz", "https://download.digiex.net/Consoles/Xbox360/Arcade-games/RBBlitz.zip"), + ("BadUpdate", "https://github.com/grimdoomer/Xbox360BadUpdate/releases/download/v1.1/Xbox360BadUpdate-Retail-USB-v1.1.zip"), + ("BadUpdate Tools", "https://github.com/grimdoomer/Xbox360BadUpdate/releases/download/v1.1/Tools.zip"), + ("FreeMyXe", "https://github.com/FreeMyXe/FreeMyXe/releases/download/beta4/FreeMyXe-beta4.zip") + }; + + HttpClient client = new(); + + AnsiConsole.Progress() + .Columns( + [ + new TaskDescriptionColumn(), + new ProgressBarColumn().FinishedStyle(GreenStyle), + new PercentageColumn().CompletedStyle(GreenStyle), + new RemainingTimeColumn().Style(GrayStyle), + new SpinnerColumn(Spinner.Known.Dots12).Style(OrangeStyle) + ]) + .StartAsync(async ctx => + { + await Task.WhenAll(items.Select(async item => + { + var task = ctx.AddTask(item.name, new ProgressTaskSettings { AutoStart = false}); + await DownloadHelper.DownloadFile(client, task, item.url); + })); + }).Wait(); + + Console.WriteLine("Download completed!"); + } + + static void ShowWelcomeMessage() => AnsiConsole.Markup( + """ + [#107c10]██████╗ █████╗ ██████╗ ██████╗ ██╗ ██╗██╗██╗ ██████╗ ███████╗██████╗[/] + [#2ca243]██╔══██╗██╔══██╗██╔══██╗██╔══██╗██║ ██║██║██║ ██╔══██╗██╔════╝██╔══██╗[/] + [#76B900]██████╔╝███████║██║ ██║██████╔╝██║ ██║██║██║ ██║ ██║█████╗ ██████╔╝[/] + [#92C83E]██╔══██╗██╔══██║██║ ██║██╔══██╗██║ ██║██║██║ ██║ ██║██╔══╝ ██╔══██╗[/] + [#a1d156]██████╔╝██║ ██║██████╔╝██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║[/] + [#a1d156]╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝[/] + + [#76B900]────────────────────────────────────────────────────────────────────────────[/] + Xbox 360 [#FF7200]BadUpdate[/] USB Builder + [#848589]Created by Pdawg[/] + [#76B900]────────────────────────────────────────────────────────────────────────────[/] + + """); + + static string PromptForAction() => AnsiConsole.Prompt( + new SelectionPrompt() + .HighlightStyle(GreenStyle) + .AddChoices( + "Build exploit USB", + "Exit" + ) + ); + } +} \ No newline at end of file diff --git a/BadBuilder/Tools/fat32format.exe b/BadBuilder/Tools/fat32format.exe new file mode 100644 index 0000000000000000000000000000000000000000..40baa541c77a52da2cb4c9ed4778559323a869f9 GIT binary patch literal 49218 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 WXKKt@HQiPz^cqx&Ew+W^diHNdEVU2- literal 0 HcmV?d00001 diff --git a/LICENSE b/LICENSE index b756609..640d505 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ -BSD 2-Clause License +BSD 3-Clause License Copyright (c) 2025, Pdawg11239 +All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -12,6 +13,10 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE