mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	Merge branch 'launcher_editor' into develop
This commit is contained in:
		| @@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FFXIVClassic World Server", | |||||||
| 		{3A3D6626-C820-4C18-8C81-64811424F20E} = {3A3D6626-C820-4C18-8C81-64811424F20E} | 		{3A3D6626-C820-4C18-8C81-64811424F20E} = {3A3D6626-C820-4C18-8C81-64811424F20E} | ||||||
| 	EndProjectSection | 	EndProjectSection | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher Editor", "Launcher Editor\Launcher Editor.csproj", "{0FFA9D2F-41C6-443C-99B7-665702CF548F}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @@ -42,6 +44,10 @@ Global | |||||||
| 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.ActiveCfg = Release|Any CPU | 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
| 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.Build.0 = Release|Any CPU | 		{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{0FFA9D2F-41C6-443C-99B7-665702CF548F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{0FFA9D2F-41C6-443C-99B7-665702CF548F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{0FFA9D2F-41C6-443C-99B7-665702CF548F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{0FFA9D2F-41C6-443C-99B7-665702CF548F}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								Launcher Editor/App.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Launcher Editor/App.config
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||||
|  | <configuration> | ||||||
|  |     <startup>  | ||||||
|  |         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> | ||||||
|  |     </startup> | ||||||
|  | </configuration> | ||||||
							
								
								
									
										60
									
								
								Launcher Editor/Launcher Editor.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Launcher Editor/Launcher Editor.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||||
|  |     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||||
|  |     <ProjectGuid>{0FFA9D2F-41C6-443C-99B7-665702CF548F}</ProjectGuid> | ||||||
|  |     <OutputType>Exe</OutputType> | ||||||
|  |     <AppDesignerFolder>Properties</AppDesignerFolder> | ||||||
|  |     <RootNamespace>Launcher_Editor</RootNamespace> | ||||||
|  |     <AssemblyName>Launcher Editor</AssemblyName> | ||||||
|  |     <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> | ||||||
|  |     <FileAlignment>512</FileAlignment> | ||||||
|  |     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <PlatformTarget>AnyCPU</PlatformTarget> | ||||||
|  |     <DebugSymbols>true</DebugSymbols> | ||||||
|  |     <DebugType>full</DebugType> | ||||||
|  |     <Optimize>false</Optimize> | ||||||
|  |     <OutputPath>bin\Debug\</OutputPath> | ||||||
|  |     <DefineConstants>DEBUG;TRACE</DefineConstants> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <PlatformTarget>AnyCPU</PlatformTarget> | ||||||
|  |     <DebugType>pdbonly</DebugType> | ||||||
|  |     <Optimize>true</Optimize> | ||||||
|  |     <OutputPath>bin\Release\</OutputPath> | ||||||
|  |     <DefineConstants>TRACE</DefineConstants> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Reference Include="System" /> | ||||||
|  |     <Reference Include="System.Core" /> | ||||||
|  |     <Reference Include="System.Xml.Linq" /> | ||||||
|  |     <Reference Include="System.Data.DataSetExtensions" /> | ||||||
|  |     <Reference Include="Microsoft.CSharp" /> | ||||||
|  |     <Reference Include="System.Data" /> | ||||||
|  |     <Reference Include="System.Net.Http" /> | ||||||
|  |     <Reference Include="System.Xml" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Compile Include="Program.cs" /> | ||||||
|  |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <None Include="App.config" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||||
|  |   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.  | ||||||
|  |        Other similar extension points exist, see Microsoft.Common.targets. | ||||||
|  |   <Target Name="BeforeBuild"> | ||||||
|  |   </Target> | ||||||
|  |   <Target Name="AfterBuild"> | ||||||
|  |   </Target> | ||||||
|  |   --> | ||||||
|  | </Project> | ||||||
							
								
								
									
										508
									
								
								Launcher Editor/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										508
									
								
								Launcher Editor/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,508 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.IO; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Launcher_Editor | ||||||
|  | { | ||||||
|  |     //ffxivboot.exe: | ||||||
|  |     //Offset | ||||||
|  |     //0x9663FC: Patch Server Port | ||||||
|  |     //0x966404: Patch Server URL | ||||||
|  |  | ||||||
|  |     //0x9663FC + 0x400000: Port Offset to search | ||||||
|  |     //0x966404 + 0x400000: URL Offset to search | ||||||
|  |  | ||||||
|  |     class Program | ||||||
|  |     { | ||||||
|  |         const string ORIGINAL_PATCH_PORT_STRING = "54996"; | ||||||
|  |         const string ORIGINAL_PATCH_URL_STRING = "ver01.ffxiv.com"; | ||||||
|  |         const string ORIGINAL_PATCH_LOGIN_STRING = "http://account.square-enix.com/account/content/ffxivlogin"; | ||||||
|  |  | ||||||
|  |         static void Main(string[] args) | ||||||
|  |         { | ||||||
|  |             byte[] exeDataBoot; | ||||||
|  |             byte[] exeDataLogin; | ||||||
|  |  | ||||||
|  |             string patchPortString; | ||||||
|  |             string patchUrlString; | ||||||
|  |             string loginUrlString; | ||||||
|  |   | ||||||
|  |             string lobbyUrlString = "lobby01.ffxiv.com"; | ||||||
|  |  | ||||||
|  |             Console.WriteLine("---------------------"); | ||||||
|  |             Console.WriteLine("FFXIV 1.0 EXE Patcher"); | ||||||
|  |             Console.WriteLine("By Ioncannon"); | ||||||
|  |             Console.WriteLine("Version 1.0"); | ||||||
|  |             Console.WriteLine("---------------------"); | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Please enter the full path to your FINAL FANTASY XIV folder. It should have ffxivgame.exe inside it."); | ||||||
|  |             string path = Console.ReadLine(); | ||||||
|  |  | ||||||
|  |             if (!File.Exists(path + "\\ffxivboot.exe")) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Missing ffxivboot.exe, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             if (!File.Exists(path + "\\ffxivgame.exe")) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Missing ffxivgame.exe, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             if (!File.Exists(path + "\\ffxivlogin.exe")) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Missing ffxivlogin.exe, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             Console.WriteLine("EXEs found!"); | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Please enter the url to the patch webpage (do not include \"http://\", max 32 characters)."); | ||||||
|  |             patchUrlString = Console.ReadLine(); | ||||||
|  |             Console.WriteLine("Please enter the port to the patch webpage (usually 80)."); | ||||||
|  |             patchPortString = Console.ReadLine(); | ||||||
|  |  | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 int.Parse(patchPortString); | ||||||
|  |             } | ||||||
|  |             catch (FormatException e) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Not a number, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             catch (OverflowException e) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Not a number, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Please enter the url to the login webpage (max 56 characters, please include \"http://\")."); | ||||||
|  |             loginUrlString = Console.ReadLine(); | ||||||
|  |  | ||||||
|  |             if (loginUrlString.Length > 0x56) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("URL too long, aborting"); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             long patchPortStringOffset = 0; | ||||||
|  |             long patchUrlStringOffset = 0; | ||||||
|  |             long lobbyUrlStringOffset = 0; | ||||||
|  |             long freeSpaceOffset = 0; | ||||||
|  |  | ||||||
|  |             long loginUrlOffset = 0; | ||||||
|  |             long freeSpaceInLoginOffset = 0; | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Patching started!"); | ||||||
|  |             exeDataBoot = File.ReadAllBytes(path + "\\ffxivboot.exe"); | ||||||
|  |             exeDataLogin = File.ReadAllBytes(path + "\\ffxivlogin.exe"); | ||||||
|  |  | ||||||
|  |             Console.WriteLine("---Editing FFXIVBOOT.EXE---"); | ||||||
|  |  | ||||||
|  |             patchPortStringOffset = PrintSearch(exeDataBoot, ORIGINAL_PATCH_PORT_STRING); | ||||||
|  |             patchUrlStringOffset = PrintSearch(exeDataBoot, ORIGINAL_PATCH_URL_STRING);             | ||||||
|  |             freeSpaceOffset = PrintFreeSpaceSearch(exeDataBoot); | ||||||
|  |  | ||||||
|  |             if (patchPortStringOffset == -1 || patchUrlStringOffset == -1 || freeSpaceOffset == -1) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("There was an error finding the address locations..."); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Writing \"{0}\" and updating offset to 0x{1:X}.", "80", freeSpaceOffset); | ||||||
|  |             WriteNewString(exeDataBoot, patchPortStringOffset, "80", freeSpaceOffset); | ||||||
|  |             Console.WriteLine("Writing \"{0}\" and updating offset to 0x{1:X}.", "127.0.0.1", freeSpaceOffset + 0x20); | ||||||
|  |             WriteNewString(exeDataBoot, patchUrlStringOffset, "127.0.0.1", freeSpaceOffset + 0x20); | ||||||
|  |  | ||||||
|  |             Console.WriteLine("---Editing FFXIVLOGIN.EXE---"); | ||||||
|  |             loginUrlOffset = PrintEncodedSearch(exeDataLogin, 0x739, ORIGINAL_PATCH_LOGIN_STRING); | ||||||
|  |             freeSpaceInLoginOffset = PrintFreeSpaceSearch(exeDataLogin); | ||||||
|  |  | ||||||
|  |             if (loginUrlOffset == -1 || freeSpaceInLoginOffset == -1) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("There was an error finding the address locations..."); | ||||||
|  |                 Console.ReadKey(); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Writing encoded \"{0}\" and updating offset to 0x{1:X}.", loginUrlString, freeSpaceInLoginOffset); | ||||||
|  |             WriteNewStringEncoded(exeDataLogin, loginUrlOffset, 0x739, loginUrlString, freeSpaceInLoginOffset); | ||||||
|  |  | ||||||
|  |             File.WriteAllBytes("C:\\Users\\Filip\\Desktop\\ffxivboot.exe", exeDataBoot); | ||||||
|  |             File.WriteAllBytes("C:\\Users\\Filip\\Desktop\\ffxivlogin.exe", exeDataLogin); | ||||||
|  |  | ||||||
|  |             Console.WriteLine("Done! New .EXEs created in the same folder as this application. Make sure to backup your originals!"); | ||||||
|  |             Console.WriteLine("Press any key to exit..."); | ||||||
|  |             Console.ReadKey(); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static void WriteNewString(byte[] exeData, long offsetLocation, string newString, long freeSpaceLocation) | ||||||
|  |         { | ||||||
|  |             using (MemoryStream memStream = new MemoryStream(exeData)) | ||||||
|  |             { | ||||||
|  |                 using (BinaryWriter binaryWriter = new BinaryWriter(memStream)) | ||||||
|  |                 { | ||||||
|  |                     binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin); | ||||||
|  |                     binaryWriter.Write((uint)freeSpaceLocation + 0x400000); | ||||||
|  |                     binaryWriter.BaseStream.Seek(freeSpaceLocation, SeekOrigin.Begin); | ||||||
|  |                     binaryWriter.Write(Encoding.ASCII.GetBytes(newString), 0, Encoding.ASCII.GetByteCount(newString) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(newString)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static void WriteNewStringEncoded(byte[] exeData, long offsetLocation, uint key, string newString, long freeSpaceLocation) | ||||||
|  |         { | ||||||
|  |             byte[] encodedString = FFXIVLoginStringEncode(key, newString); | ||||||
|  |             using (MemoryStream memStream = new MemoryStream(exeData)) | ||||||
|  |             { | ||||||
|  |                 using (BinaryWriter binaryWriter = new BinaryWriter(memStream)) | ||||||
|  |                 { | ||||||
|  |                     //binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin); | ||||||
|  |                     //binaryWriter.Write((uint)freeSpaceLocation + 0x400000); | ||||||
|  |                     binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin); | ||||||
|  |                     binaryWriter.Write(encodedString); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long PrintSearch(byte[] exeData, string searchString) | ||||||
|  |         { | ||||||
|  |             Console.Write("Searching for string \"{0}\"...", searchString); | ||||||
|  |             long offset = SearchForStringOffset(exeData, searchString); | ||||||
|  |  | ||||||
|  |             if (offset != -1) | ||||||
|  |                 Console.WriteLine(" FOUND @ 0x{0:X}!", offset); | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(" ERROR, could not find string.");                 | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return offset; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long PrintEncodedSearch(byte[] exeData, uint key, string searchString) | ||||||
|  |         { | ||||||
|  |             Console.Write("Searching for encoded string \"{0}\"...", searchString); | ||||||
|  |             long offset = SearchForEncodedStringOffset(exeData, key, searchString); | ||||||
|  |  | ||||||
|  |             if (offset != -1) | ||||||
|  |                 Console.WriteLine(" FOUND @ 0x{0:X}!", offset); | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(" ERROR, could not find string."); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return offset; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long PrintFreeSpaceSearch(byte[] exeData) | ||||||
|  |         { | ||||||
|  |             Console.Write("Searching for free space..."); | ||||||
|  |             long freeSpaceOffset = SearchForFreeSpace(exeData); | ||||||
|  |             if (freeSpaceOffset != -1) | ||||||
|  |                 Console.WriteLine(" FOUND @ 0x{0:X}!", freeSpaceOffset); | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(" ERROR, could not find free space."); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return freeSpaceOffset; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static bool EditOffset(long offset, uint value) | ||||||
|  |         { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long SearchForFreeSpace(byte[] exeData) | ||||||
|  |         { | ||||||
|  |             using (MemoryStream memStream = new MemoryStream(exeData)) | ||||||
|  |             { | ||||||
|  |                 using (BinaryReader binReader = new BinaryReader(memStream)) | ||||||
|  |                 { | ||||||
|  |                     //Find the .data section header | ||||||
|  |                     long textSectionOffset = -1; | ||||||
|  |                     int strCheckoffset = 0; | ||||||
|  |                     while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length) | ||||||
|  |                     { | ||||||
|  |                         if (binReader.ReadByte() == ".text"[strCheckoffset]) | ||||||
|  |                         { | ||||||
|  |                             if (strCheckoffset == 0) | ||||||
|  |                                 textSectionOffset = binReader.BaseStream.Position - 1; | ||||||
|  |  | ||||||
|  |                             strCheckoffset++; | ||||||
|  |                             if (strCheckoffset == Encoding.ASCII.GetByteCount(".data")) | ||||||
|  |                                 break; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             strCheckoffset = 0; | ||||||
|  |                             textSectionOffset = -1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     //Read in the position and size | ||||||
|  |                     binReader.BaseStream.Seek(textSectionOffset, SeekOrigin.Begin); | ||||||
|  |                     binReader.ReadUInt64(); | ||||||
|  |                     uint virtualSize = binReader.ReadUInt32(); | ||||||
|  |                     uint address = binReader.ReadUInt32(); | ||||||
|  |                     uint sizeOfRawData = binReader.ReadUInt32(); | ||||||
|  |  | ||||||
|  |                     if (sizeOfRawData - virtualSize < 0x50) | ||||||
|  |                         return -1; | ||||||
|  |  | ||||||
|  |                     //Find a spot | ||||||
|  |                     binReader.BaseStream.Seek(address + sizeOfRawData, SeekOrigin.Begin); | ||||||
|  |                     while (binReader.BaseStream.Position >= address + virtualSize) | ||||||
|  |                     {                         | ||||||
|  |                         binReader.BaseStream.Seek(-0x50, SeekOrigin.Current); | ||||||
|  |                         long newPosition = binReader.BaseStream.Position; | ||||||
|  |  | ||||||
|  |                         bool foundNotZero = false; | ||||||
|  |                         for (int i = 0; i < 0x50; i++) | ||||||
|  |                         { | ||||||
|  |                             if (binReader.ReadByte() != 0) | ||||||
|  |                             { | ||||||
|  |                                 foundNotZero = true; | ||||||
|  |                                 break; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         if (!foundNotZero)                         | ||||||
|  |                             return newPosition;                         | ||||||
|  |                         else | ||||||
|  |                             binReader.BaseStream.Seek(newPosition, SeekOrigin.Begin); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long SearchForStringOffset(byte[] exeData, string testString) | ||||||
|  |         { | ||||||
|  |             testString += "\0"; | ||||||
|  |  | ||||||
|  |             using (MemoryStream memStream = new MemoryStream(exeData)) | ||||||
|  |             { | ||||||
|  |                 using (BinaryReader binReader = new BinaryReader(memStream)) | ||||||
|  |                 { | ||||||
|  |                     long strOffset = -1; | ||||||
|  |                     int strCheckoffset = 0; | ||||||
|  |                     while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length) | ||||||
|  |                     { | ||||||
|  |                         if (binReader.ReadByte() == testString[strCheckoffset]) | ||||||
|  |                         { | ||||||
|  |                             if (strCheckoffset == 0) | ||||||
|  |                                 strOffset = binReader.BaseStream.Position-1; | ||||||
|  |  | ||||||
|  |                             strCheckoffset++; | ||||||
|  |                             if (strCheckoffset == Encoding.ASCII.GetByteCount(testString)) | ||||||
|  |                                 break; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             strCheckoffset = 0; | ||||||
|  |                             strOffset = -1; | ||||||
|  |                         } | ||||||
|  |                     }                     | ||||||
|  |  | ||||||
|  |                     if (strOffset != -1) | ||||||
|  |                     { | ||||||
|  |                         strOffset += 0x400000; | ||||||
|  |  | ||||||
|  |                         binReader.BaseStream.Seek(0, SeekOrigin.Begin); | ||||||
|  |  | ||||||
|  |                         while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length) | ||||||
|  |                         { | ||||||
|  |                             if (binReader.ReadUInt32() == strOffset) | ||||||
|  |                                 return binReader.BaseStream.Position - 0x4; | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         return -1; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                         return -1; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long SearchForEncodedStringOffset(byte[] exeData, uint testKey, string testString) | ||||||
|  |         { | ||||||
|  |             byte[] encoded = FFXIVLoginStringEncode(testKey, testString); | ||||||
|  |  | ||||||
|  |             using (MemoryStream memStream = new MemoryStream(exeData)) | ||||||
|  |             { | ||||||
|  |                 using (BinaryReader binReader = new BinaryReader(memStream)) | ||||||
|  |                 { | ||||||
|  |                     long strOffset = -1; | ||||||
|  |                     int strCheckoffset = 0; | ||||||
|  |                     while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length) | ||||||
|  |                     { | ||||||
|  |                         if (binReader.ReadByte() == encoded[strCheckoffset]) | ||||||
|  |                         { | ||||||
|  |                             if (strCheckoffset == 0) | ||||||
|  |                                 strOffset = binReader.BaseStream.Position - 1; | ||||||
|  |  | ||||||
|  |                             strCheckoffset++; | ||||||
|  |                             if (strCheckoffset == encoded.Length) | ||||||
|  |                                 break; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             strCheckoffset = 0; | ||||||
|  |                             strOffset = -1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     return strOffset; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static string FFXIVLoginStringDecodeBinary(string path) | ||||||
|  |         { | ||||||
|  |             Console.OutputEncoding = System.Text.Encoding.UTF8; | ||||||
|  |             byte[] data = File.ReadAllBytes(path); | ||||||
|  |             //int offset = 0x5405a; | ||||||
|  |             //int offset = 0x5425d; | ||||||
|  |             int offset = 0x53ea0; | ||||||
|  |             while (true) | ||||||
|  |             { | ||||||
|  |                 string result = ""; | ||||||
|  |                 uint key = (uint)data[offset + 0] << 8 | data[offset + 1]; | ||||||
|  |                 uint key2 = data[offset + 2]; | ||||||
|  |                 key = RotateRight(key, 1) & 0xFFFF; | ||||||
|  |                 key -= 0x22AF; | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |                 key2 = key2 ^ key; | ||||||
|  |                 key = RotateRight(key, 1) & 0xFFFF; | ||||||
|  |                 key -= 0x22AF; | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |                 uint finalKey = key; | ||||||
|  |                 key = data[offset + 3]; | ||||||
|  |                 uint count = (key2 & 0xFF) << 8; | ||||||
|  |                 key = key ^ finalKey; | ||||||
|  |                 key &= 0xFF; | ||||||
|  |                 count |= key; | ||||||
|  |  | ||||||
|  |                 int count2 = 0; | ||||||
|  |                 while (count != 0) | ||||||
|  |                 { | ||||||
|  |                     uint encrypted = data[offset + 4 + count2]; | ||||||
|  |                     finalKey = RotateRight(finalKey, 1) & 0xFFFF; | ||||||
|  |                     finalKey -= 0x22AF; | ||||||
|  |                     finalKey &= 0xFFFF; | ||||||
|  |                     encrypted = encrypted ^ (finalKey & 0xFF); | ||||||
|  |  | ||||||
|  |                     result += (char)encrypted; | ||||||
|  |                     count--; | ||||||
|  |                     count2++; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 return result; | ||||||
|  |                 //offset += 4 + count2; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static string FFXIVLoginStringDecode(byte[] data) | ||||||
|  |         { | ||||||
|  |             Console.OutputEncoding = System.Text.Encoding.UTF8; | ||||||
|  |             while (true) | ||||||
|  |             { | ||||||
|  |                 string result = ""; | ||||||
|  |                 uint key = (uint)data[0] << 8 | data[1]; | ||||||
|  |                 uint key2 = data[2]; | ||||||
|  |                 key = RotateRight(key, 1) & 0xFFFF; | ||||||
|  |                 key -= 0x22AF; | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |                 key2 = key2 ^ key; | ||||||
|  |                 key = RotateRight(key, 1) & 0xFFFF; | ||||||
|  |                 key -= 0x22AF; | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |                 uint finalKey = key; | ||||||
|  |                 key = data[3]; | ||||||
|  |                 uint count = (key2 & 0xFF) << 8; | ||||||
|  |                 key = key ^ finalKey; | ||||||
|  |                 key &= 0xFF; | ||||||
|  |                 count |= key; | ||||||
|  |  | ||||||
|  |                 int count2 = 0; | ||||||
|  |                 while (count != 0) | ||||||
|  |                 { | ||||||
|  |                     uint encrypted = data[4 + count2]; | ||||||
|  |                     finalKey = RotateRight(finalKey, 1) & 0xFFFF; | ||||||
|  |                     finalKey -= 0x22AF; | ||||||
|  |                     finalKey &= 0xFFFF; | ||||||
|  |                     encrypted = encrypted ^ (finalKey & 0xFF); | ||||||
|  |  | ||||||
|  |                     result += (char)encrypted; | ||||||
|  |                     count--; | ||||||
|  |                     count2++; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 return result; | ||||||
|  |                 //offset += 4 + count2; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static byte[] FFXIVLoginStringEncode(uint key, string text) | ||||||
|  |         { | ||||||
|  |             key = key & 0xFFFF; | ||||||
|  |  | ||||||
|  |             uint count = 0; | ||||||
|  |             byte[] asciiBytes = Encoding.ASCII.GetBytes(text); | ||||||
|  |             byte[] result = new byte[4 + text.Length]; | ||||||
|  |             for (count = 0; count < text.Length; count++) | ||||||
|  |             { | ||||||
|  |                 result[result.Length - count - 1] = (byte)(asciiBytes[asciiBytes.Length - count - 1] ^ (key & 0xFF)); | ||||||
|  |                 key += 0x22AF; | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |                 key = RotateLeft(key, 1); | ||||||
|  |                 key &= 0xFFFF; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             count = count ^ key; | ||||||
|  |             result[3] = (byte)(count & 0xFF); | ||||||
|  |  | ||||||
|  |             key += 0x22AF; | ||||||
|  |             key &= 0xFFFF; | ||||||
|  |             key = RotateLeft(key, 1);  | ||||||
|  |             key &= 0xFFFF; | ||||||
|  |  | ||||||
|  |             result[2] = (byte)(key & 0xFF); | ||||||
|  |  | ||||||
|  |             key += 0x22AF; | ||||||
|  |             key &= 0xFFFF; | ||||||
|  |             key = RotateLeft(key, 1); | ||||||
|  |             key &= 0xFFFF; | ||||||
|  |  | ||||||
|  |             result[1] = (byte)(key & 0xFF); | ||||||
|  |             result[0] = (byte)((key >> 8) & 0xFF); | ||||||
|  |  | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static uint RotateLeft(uint value, int bits) | ||||||
|  |         { | ||||||
|  |             return (value << bits) | (value >> (16 - bits)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static uint RotateRight(uint value, int bits) | ||||||
|  |         { | ||||||
|  |             return (value >> bits) | (value << (16 - bits)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								Launcher Editor/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Launcher Editor/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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("Launcher Editor")] | ||||||
|  | [assembly: AssemblyDescription("")] | ||||||
|  | [assembly: AssemblyConfiguration("")] | ||||||
|  | [assembly: AssemblyCompany("")] | ||||||
|  | [assembly: AssemblyProduct("Launcher Editor")] | ||||||
|  | [assembly: AssemblyCopyright("Copyright ©  2017")] | ||||||
|  | [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("0ffa9d2f-41c6-443c-99b7-665702cf548f")] | ||||||
|  |  | ||||||
|  | // 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")] | ||||||
		Reference in New Issue
	
	Block a user