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 0000000..40baa54
Binary files /dev/null and b/BadBuilder/Tools/fat32format.exe differ
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