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