diff --git a/Conv2PSV.sln b/Conv2PSV.sln new file mode 100644 index 0000000..565b9ec --- /dev/null +++ b/Conv2PSV.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.76 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Conv2PSV", "Conv2PSV\Conv2PSV.csproj", "{08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Conv2PSV/App.config b/Conv2PSV/App.config new file mode 100644 index 0000000..88fa402 --- /dev/null +++ b/Conv2PSV/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Conv2PSV/Conv2PSV.csproj b/Conv2PSV/Conv2PSV.csproj new file mode 100644 index 0000000..ac9b9c7 --- /dev/null +++ b/Conv2PSV/Conv2PSV.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {08DD69CC-AD7E-4173-BF1C-CD6E0C9C8B8C} + Exe + Conv2PSV + MCS2PSV + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Icon.ico + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Conv2PSV/Conv2PSV.csproj.user b/Conv2PSV/Conv2PSV.csproj.user new file mode 100644 index 0000000..3df7a31 --- /dev/null +++ b/Conv2PSV/Conv2PSV.csproj.user @@ -0,0 +1,8 @@ + + + + BASCUS-94228SPYRO.mcs + false + C:\Users\earsy\Documents\visual studio 2017\Projects\Conv2PSV\Conv2PSV\bin\Debug + + \ No newline at end of file diff --git a/Conv2PSV/Icon.ico b/Conv2PSV/Icon.ico new file mode 100644 index 0000000..30b246c Binary files /dev/null and b/Conv2PSV/Icon.ico differ diff --git a/Conv2PSV/Program.cs b/Conv2PSV/Program.cs new file mode 100644 index 0000000..96876d0 --- /dev/null +++ b/Conv2PSV/Program.cs @@ -0,0 +1,177 @@ +using System; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Windows.Forms; + +namespace Conv2PSV +{ + class Program + { + static string GetString(Stream fs) + { + String str = ""; + byte by = 0xFF; + while (true) + { + by = (byte)fs.ReadByte(); + if (by == 0x00) + break; + str += (char)by; + } + + return str; + } + static string ReadName(Stream fs) + { + fs.Seek(0xA, SeekOrigin.Begin); + String Name = GetString(fs); + return Name; + + } + + static void WriteMagic(Stream fs) + { + fs.WriteByte(0x00); + WriteString(fs, "VSP"); + } + + static void WriteString(Stream fs, String str) + { + char[] CharArray = str.ToArray(); + foreach(char Chr in CharArray) + { + fs.WriteByte((byte)Chr); + } + } + + static String GetTitle(String FileName) + { + if (Path.GetExtension(FileName) == ".mcs") + { + FileStream fs = File.OpenRead(FileName); + return ReadName(fs); + fs.Close(); + } + else + { + throw new FileNotFoundException(); + } + } + + + static byte[] SignatureGen(Stream fs) + { + byte[] HMAC_KEY = { 0x02, 0x62, 0x8C, 0x13, 0x94, 0x71, 0xF5, 0x0B, 0xC8, 0x94, 0x4E, 0x6B, 0xF0, 0xDC, 0xBC, 0x50, 0x30, 0x3F, 0x1F, 0x5B }; // Key for this specific seed, + + fs.Seek(0x00, SeekOrigin.Begin); + Console.WriteLine("Generating HMAC signature..."); + HMACSHA1 hmac = new HMACSHA1(HMAC_KEY); + byte[] Signature = hmac.ComputeHash(fs); + Console.WriteLine(BitConverter.ToString(Signature).Replace("-"," ")); + return Signature; + } + + static String GetPsvName(String SaveName) + { + String PsvName = ""; + char[] SaveArray = SaveName.ToArray(); + bool DashFound = false; + foreach(char SaveChar in SaveArray) + { + if(!DashFound) + { + if (SaveChar == '-') + { + DashFound = true; + } + PsvName += SaveChar; + } + else + { + if (Char.IsDigit(SaveChar)) + { + PsvName += SaveChar; + } + else + { + PsvName += String.Format("{0:X}", Convert.ToInt32(SaveChar)); + } + } + + } + PsvName += ".PSV"; + return PsvName; + } + + [STAThread] + static void Main(string[] args) + { + if(args.Length == 0) + { + Console.WriteLine("Select MCS"); + OpenFileDialog ofd = new OpenFileDialog(); + ofd.InitialDirectory = Directory.GetCurrentDirectory(); + ofd.Filter = "Memcard REX Single Save (*.mcs)|*.mcs"; + DialogResult res = ofd.ShowDialog(); + if (res == DialogResult.OK) + { + args = new String[] { ofd.FileName }; + } + } + + if (args.Length != 0) + { + String FilePath = args[0]; + String SaveTitle = GetTitle(FilePath); + + Console.Write("PsvName = "); + String PsvName = GetPsvName(SaveTitle); + Console.WriteLine(PsvName); + + FileStream PSV = File.Open(PsvName, FileMode.OpenOrCreate,FileAccess.ReadWrite); + PSV.SetLength(0); + BinaryWriter BW = new BinaryWriter(PSV); + WriteMagic(PSV); + BW.Write((UInt32)0); + + //Am lazy and dont want to implement sonys broken AES-CBC algorythm + //Just do a seed i know the hmac key for + //ps3 wont care. + + Byte[] StaticSeeed = { 0x42, 0x6C, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x42, 0x65, 0x20, 0x7E, 0x20, 0x57, 0x69, 0x63, 0x63, 0x61, 0x6E, 0x73 }; + //"Blessed Be ~ Wiccans"(0x14) - Allways nice to add personality to your code where-ever possible. + + PSV.Write(StaticSeeed, 0x00, 0x14); + + PSV.Write(new Byte[0x14], 0x00, 0x14); + Console.WriteLine("Writing Flags... "); + Byte[] Flags = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0x90, 0x00, 0x00}; + PSV.Write(Flags, 0x00, 0x34); + + int Padding = (0x20 - SaveTitle.Length); + Console.WriteLine("Writing " + SaveTitle + " +" + Padding.ToString()); + WriteString(PSV, SaveTitle); + BW.Write(new Byte[Padding], 0x00, Padding); + + Console.WriteLine("Writing SC Image"); + FileStream MCS = File.OpenRead(FilePath); + long SCLen = MCS.Length - 0x80; + MCS.Seek(0x80, SeekOrigin.Begin); + byte[] SCImage = new Byte[SCLen]; + MCS.Read(SCImage, 0x00, (int)SCLen); + PSV.Write(SCImage, 0x00, (int)SCLen); + + byte[] Signature = SignatureGen(PSV); + Console.WriteLine("Writing Signature to file..."); + PSV.Seek(0x1C, SeekOrigin.Begin); + PSV.Write(Signature, 0x00, 0x14); + Console.WriteLine("Done!\n\nBlessed Be ~"); + PSV.Close(); + MCS.Close(); + } + + + } + } +} diff --git a/Conv2PSV/Properties/AssemblyInfo.cs b/Conv2PSV/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f9293da --- /dev/null +++ b/Conv2PSV/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Conv2PSV")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Conv2PSV")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("08dd69cc-ad7e-4173-bf1c-cd6e0c9c8b8c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")]