Compare commits

..

No commits in common. "main" and "v6" have entirely different histories.
main ... v6

15 changed files with 126 additions and 579 deletions

2
.gitignore vendored
View file

@ -2,5 +2,3 @@
*/bin/* */bin/*
*/obj/* */obj/*
.vs/* .vs/*
McEncryptor/.vs/*
McDecryptor/.vs/*

11
LICENSE
View file

@ -1,11 +0,0 @@
Copyright 2024 BedrockReverse
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, 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 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1 +0,0 @@
{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt","ProjectFileName":"LibMcCrypt.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Crypto.cs"},{"SourceFile":"Keys.cs"},{"SourceFile":"Manifest.cs"},{"SourceFile":"Marketplace.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Utils.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\packages\\Newtonsoft.Json.13.0.1\\lib\\net45\\Newtonsoft.Json.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.IO.Compression.FileSystem.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","OutputItemRelativePath":"LibMcCrypt.dll"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.pdb","OutputItemRelativePath":"LibMcCrypt.pdb"}],"CopyToOutputEntries":[]}

View file

@ -45,30 +45,15 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Config.cs" />
<Compile Include="Crypto.cs" /> <Compile Include="Crypto.cs" />
<Compile Include="Keys.cs" /> <Compile Include="Keys.cs" />
<Compile Include="Manifest.cs" /> <Compile Include="Manifest.cs" />
<Compile Include="Marketplace.cs" /> <Compile Include="Marketplace.cs" />
<Compile Include="PackData\PEntry.cs" />
<Compile Include="PackData\PReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Utils.cs" /> <Compile Include="Utils.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="default.cfg" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -4,7 +4,6 @@ using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Newtonsoft.Json.Linq;
namespace McCrypt namespace McCrypt
{ {
@ -44,66 +43,6 @@ namespace McCrypt
string signaturesJsonFile = Path.Combine(basePath, "signatures.json"); string signaturesJsonFile = Path.Combine(basePath, "signatures.json");
File.WriteAllText(signaturesJsonFile, signatureJson); File.WriteAllText(signaturesJsonFile, signatureJson);
} }
public static string ReadType(string manifestFile)
{
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if(manifestData.modules != null)
{
if(manifestData.modules.Count >= 1)
{
return manifestData.modules[0].type;
}
}
return Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(manifestFile)));
}
public static string ReadProductType(string manifestFile)
{
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if (manifestData.metadata != null)
{
if (manifestData.metadata.product_type != null)
{
return manifestData.metadata.product_type;
}
}
return null;
}
public static string[] ReadWorldPackList(string packListFile)
{
List<string> depUuidList = new List<string>();
string packStr = File.ReadAllText(packListFile);
dynamic packListData = JsonConvert.DeserializeObject(packStr);
for (int i = 0; i < packListData.Count; i++)
{
dynamic packData = packListData[i];
if(packData.pack_id != null) depUuidList.Add(packData.pack_id.ToString());
}
return depUuidList.ToArray();
}
public static string[] ReadDependancyUuids(string manifestFile)
{
List<string> depUuidList = new List<string>();
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if (manifestData.dependencies != null)
{
for(int i = 0; i < manifestData.dependencies.Count; i++)
{
dynamic manifestDependancy = manifestData.dependencies[i];
if(manifestDependancy.uuid != null)
{
depUuidList.Add(manifestDependancy.uuid.ToString());
}
}
}
return depUuidList.ToArray();
}
public static string ReadName(string manifestFile) public static string ReadName(string manifestFile)
{ {
string defaultName = Path.GetFileName(Path.GetDirectoryName(manifestFile)); string defaultName = Path.GetFileName(Path.GetDirectoryName(manifestFile));

View file

@ -12,6 +12,8 @@ namespace McCrypt
public class Marketplace public class Marketplace
{ {
// Hi mojang <3 // Hi mojang <3
// https://www.youtube.com/watch?v=jIM6dN3ogbk
// https://www.youtube.com/watch?v=mnnYCJNhw7w
private static string[] dontEncrypt = new string[] { "manifest.json", "contents.json", "texts", "pack_icon.png", "ui"}; private static string[] dontEncrypt = new string[] { "manifest.json", "contents.json", "texts", "pack_icon.png", "ui"};
private struct contentsJson private struct contentsJson
@ -56,37 +58,6 @@ namespace McCrypt
} }
} }
// check if prid tag is present in a world
// can be used to check if its encrypted.
public static bool IsLevelEncrypted(string levelPath)
{
string ldbPath = Path.Combine(levelPath, "db");
if (!Directory.Exists(ldbPath)) return false;
string[] ldbFiles = Directory.GetFiles(ldbPath, "*.ldb", SearchOption.TopDirectoryOnly);
foreach (string ldbFile in ldbFiles)
{
string file = Path.Combine(ldbPath, ldbFile);
using (FileStream fs = File.OpenRead(file)) // Open file for reading
{
using (BinaryReader br = new BinaryReader(fs)) // Create a binary reader overlay of it
{
if (fs.Length <= 0x10)
continue;
uint version = br.ReadUInt32();
uint magic = br.ReadUInt32();
UInt64 unk = br.ReadUInt64();
if (version == 0 && magic == 0x9bcfb9fc) // is valid header?
return true;
}
}
}
return false;
}
// Change all skins type to "free" instead of "paid" // Change all skins type to "free" instead of "paid"
// This makes the game let you actually apply them // This makes the game let you actually apply them
public static void CrackSkinsJson(string skinsJsonFile) public static void CrackSkinsJson(string skinsJsonFile)
@ -189,14 +160,14 @@ namespace McCrypt
// For the file types that have a header- // For the file types that have a header-
private static byte[] worldOrContentsJsonDecrypt(string file) private static byte[] worldOrContentsJsonDecrypt(string file)
{ {
using (FileStream fs = File.OpenRead(file)) FileStream fs = File.OpenRead(file); // Open file for reading
{ // Open file for reading BinaryReader br = new BinaryReader(fs); // Create a binary reader overlay of it
using (BinaryReader br = new BinaryReader(fs))
{
// Create a binary reader overlay of it
if (fs.Length <= 0) if (fs.Length <= 0)
{
fs.Dispose();
return new byte[0] { }; return new byte[0] { };
}
uint version = br.ReadUInt32(); uint version = br.ReadUInt32();
uint magic = br.ReadUInt32(); uint magic = br.ReadUInt32();
@ -224,18 +195,19 @@ namespace McCrypt
byte[] plaintext = Crypto.Aes256CfbDecrypt(key, iv, ciphertext); // Decrypt data byte[] plaintext = Crypto.Aes256CfbDecrypt(key, iv, ciphertext); // Decrypt data
fs.Dispose();
return plaintext; return plaintext;
} }
else else
{ {
fs.Dispose();
throw new InvalidDataException("Not a valid LEVELDB or CONTENTS.JSON file."); throw new InvalidDataException("Not a valid LEVELDB or CONTENTS.JSON file.");
} }
}
}
} }
// Read contents.json, and decrypt all files inside // Read contents.json, and decrypt all files inside
// Now Multi-Threaded for speed! // Now Multi-Threaded for speed!
private static void decryptContentsJsonFiles(string contentsJsonPath, List<Thread> threadList) private static void decryptContentsJsonFiles(string contentsJsonPath, List<Thread> threadList)
@ -267,9 +239,8 @@ namespace McCrypt
File.WriteAllBytes(filePath, plainText); // Write back decrypted filie File.WriteAllBytes(filePath, plainText); // Write back decrypted filie
}); });
thrd.Priority = ThreadPriority.Highest; thrd.Priority = ThreadPriority.Highest;
threadList.Add(thrd);
thrd.Start(); thrd.Start();
if (!Config.MultiThread) thrd.Join();
else threadList.Add(thrd);
} }
} }
@ -340,12 +311,13 @@ namespace McCrypt
File.WriteAllBytes(fileToDecrypt, decryptedData); // Write to disk File.WriteAllBytes(fileToDecrypt, decryptedData); // Write to disk
} }
catch (InvalidDataException) catch (InvalidDataException)
{ } {
Console.Error.WriteLine("Failed to decrypt db/" + Path.GetFileName(levelDbFile));
}
}); });
thrd.Priority = ThreadPriority.Highest; thrd.Priority = ThreadPriority.Highest;
threadList.Add(thrd);
thrd.Start(); thrd.Start();
if (!Config.MultiThread) thrd.Join();
else threadList.Add(thrd);
} }
} }
} }

View file

@ -1,184 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace McCrypt.PackData
{
public class PEntry
{
private string originalPath;
public String FilePath
{
get
{
return originalPath;
}
}
public String ManifestPath
{
get
{
return Path.Combine(originalPath, "manifest.json");
}
}
public String WorldResourcePacksPath
{
get
{
return Path.Combine(this.FilePath, "world_resource_packs.json");
}
}
public String WorldBehaviourPacksPath
{
get
{
return Path.Combine(this.FilePath, "world_behavior_packs.json");
}
}
public String SubResourcePacks
{
get
{
return Path.Combine(this.FilePath, "resource_packs");
}
}
public String SubBehaviourPacks
{
get
{
return Path.Combine(this.FilePath, "behavior_packs");
}
}
public bool IsEncrypted
{
get
{
if (this.ProductType != "minecraftWorlds") return true;
else return Marketplace.IsLevelEncrypted(this.FilePath);
}
}
public bool HasDependancies
{
get
{
return DependsUUID.Length >= 1;
}
}
public String[] DependsUUID
{
get
{
if (File.Exists(this.ManifestPath))
{
return Manifest.ReadDependancyUuids(this.ManifestPath);
}
else if(this.Type == "minecraftWorlds")
{
List<String> uuids = new List<String>();
if(File.Exists(WorldResourcePacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldResourcePacksPath));
if(File.Exists(WorldBehaviourPacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldBehaviourPacksPath));
return uuids.ToArray();
}
else
{
return new String[0] { };
}
}
}
public String Name
{
get
{
if (File.Exists(this.ManifestPath))
return Manifest.ReadName(this.ManifestPath);
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
return File.ReadAllText(Path.Combine(FilePath, "levelname.txt"));
else
return "Untitled";
}
}
public String Type {
get
{
if(File.Exists(this.ManifestPath))
return Manifest.ReadType(this.ManifestPath);
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
return "minecraftWorlds";
else
return Path.GetFileName(Path.GetDirectoryName(this.FilePath));
}
}
public String ProductType
{
get
{
if (File.Exists(this.ManifestPath))
{
string ptype = Manifest.ReadProductType(this.ManifestPath);
if (ptype == null)
{
string type = Manifest.ReadType(this.ManifestPath);
switch (type)
{
case "resources":
return "resource_packs";
case "skin_pack":
return "skin_packs";
case "world_template":
return "world_templates";
case "data":
return "behaviour_packs";
case "persona_piece":
return "persona";
}
}
return ptype;
}
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
{
return "minecraftWorlds";
}
else if (this.HasDependancies)
{
return "addon";
}
else
{
return Path.GetFileName(Path.GetDirectoryName(this.FilePath));
}
}
}
public String Uuid
{
get
{
if(File.Exists(this.ManifestPath))
{
return Manifest.ReadUUID(this.ManifestPath);
}
else
{
return new Guid().ToString();
}
}
}
public PEntry(string path)
{
this.originalPath = path;
}
}
}

View file

@ -1,104 +0,0 @@
using McCrypt.PackData;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace McCrypt.PackData
{
public class PReader
{
private List<PEntry> entries = new List<PEntry>();
private HashSet<string> hiddenUuids = new HashSet<String>();
public PEntry[] GetDependancies(PEntry baseentry)
{
List<PEntry> dependancyList = new List<PEntry>();
foreach (PEntry pentry in entries)
{
if (baseentry.DependsUUID.Contains<string>(pentry.Uuid))
dependancyList.Add(pentry);
// check sub packs in world templates ..
if(pentry.ProductType == "world_templates")
{
if (Directory.Exists(pentry.SubResourcePacks))
{
foreach (string resourcePack in Directory.GetDirectories(pentry.SubResourcePacks, "*", SearchOption.TopDirectoryOnly))
{
PEntry subPentry = new PEntry(Path.Combine(pentry.SubResourcePacks, resourcePack));
if (baseentry.DependsUUID.Contains<string>(subPentry.Uuid))
dependancyList.Add(subPentry);
}
}
if (Directory.Exists(pentry.SubBehaviourPacks))
{
foreach (string behaviourPack in Directory.GetDirectories(pentry.SubBehaviourPacks, "*", SearchOption.TopDirectoryOnly))
{
PEntry subPentry = new PEntry(Path.Combine(pentry.SubBehaviourPacks, behaviourPack));
if (baseentry.DependsUUID.Contains<string>(subPentry.Uuid))
dependancyList.Add(subPentry);
}
}
}
}
return dependancyList.ToArray();
}
public PEntry[] PEntryList
{
get
{
List<PEntry> publicEntries = new List<PEntry>();
foreach (PEntry entry in entries)
{
if (!hiddenUuids.Contains(entry.Uuid))
{
publicEntries.Add(entry);
}
}
return publicEntries.ToArray();
}
}
public PReader()
{
// search premium cache
foreach (string searchFolder in Config.SearchFolders)
{
foreach (string searchModule in Config.SearchModules)
{
string moduleFolder = Path.Combine(searchFolder, searchModule);
if (Directory.Exists(moduleFolder))
{
foreach (string moduleItem in Directory.GetDirectories(moduleFolder, "*", SearchOption.TopDirectoryOnly))
{
PEntry entry = new PEntry(moduleItem);
if (entry.ProductType == "minecraftWorlds" && !Config.DecryptExistingWorlds) continue;
if (entry.ProductType != "minecraftWorlds" && !hiddenUuids.Contains(entry.Uuid)) foreach (string uuid in entry.DependsUUID) hiddenUuids.Add(uuid);
if (!entry.IsEncrypted) continue;
entries.Add(entry);
}
}
}
}
if (Config.DecryptExistingWorlds && Directory.Exists(Config.WorldsFolder))
{
foreach (string moduleItem in Directory.GetDirectories(Config.WorldsFolder, "*", SearchOption.TopDirectoryOnly))
{
PEntry entry = new PEntry(moduleItem);
if (entry.ProductType != "minecraftWorlds" && !hiddenUuids.Contains(entry.Uuid)) foreach (string uuid in entry.DependsUUID) hiddenUuids.Add(uuid);
if (!entry.IsEncrypted) continue;
entries.Add(entry);
}
}
}
}
}

6
McDecryptor/App.config Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup>
</configuration>

View file

@ -1,4 +1,4 @@
using McCrypt.Properties; using McDecryptor.Properties;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -7,9 +7,9 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace McCrypt namespace McDecryptor
{ {
public class Config internal class Config
{ {
public static string LocalAppdata = Environment.GetEnvironmentVariable("LOCALAPPDATA"); public static string LocalAppdata = Environment.GetEnvironmentVariable("LOCALAPPDATA");
public static string RoamingAppdata = Environment.GetEnvironmentVariable("APPDATA"); public static string RoamingAppdata = Environment.GetEnvironmentVariable("APPDATA");
@ -23,21 +23,18 @@ namespace McCrypt
public static string LocalState; public static string LocalState;
public static string LocalCache; public static string LocalCache;
public static string ComMojang;
public static string KeysDbPath; public static string KeysDbPath;
public static string PremiumCache; public static string PremiumCache;
public static string ServerPackCache; public static string ServerPackCache;
public static string RealmsPremiumCache; public static string RealmsPremiumCache;
public static string WorldsFolder;
public static string OptionsTxt; public static string OptionsTxt;
public static string OutFolder; public static string OutFolder;
public static bool CrackPacks; public static bool CrackPacks;
public static bool ZipPacks; public static bool ZipPacks;
public static bool MultiThread;
public static bool DecryptExistingWorlds;
public static string[] SearchFolders public static string[] SearchFolders
{ {
get get
@ -69,17 +66,13 @@ namespace McCrypt
searchModules.Add("persona"); searchModules.Add("persona");
searchModules.Add("behavior_packs"); searchModules.Add("behavior_packs");
searchModules.Add("resource"); searchModules.Add("resource");
searchModules.Add("minecraftWorlds");
} }
private static void rebaseLocalData() private static void rebaseLocalData()
{ {
OutFolder = Path.Combine(LocalState, "games", "com.mojang");
PremiumCache = Path.Combine(LocalState, "premium_cache"); PremiumCache = Path.Combine(LocalState, "premium_cache");
ServerPackCache = Path.Combine(LocalCache, "packcache"); ServerPackCache = Path.Combine(LocalCache, "packcache");
RealmsPremiumCache = Path.Combine(LocalCache, "premiumcache"); RealmsPremiumCache = Path.Combine(LocalCache, "premiumcache");
ComMojang = Path.Combine(LocalState, "games", "com.mojang");
OptionsTxt = Path.Combine(ComMojang, "minecraftpe", "options.txt");
WorldsFolder = Path.Combine(ComMojang, "minecraftWorlds");
rebaseSearchFolders(); rebaseSearchFolders();
} }
private static void rebaseAll() private static void rebaseAll()
@ -99,7 +92,6 @@ namespace McCrypt
str = str.Replace("$LOCALSTATE", LocalState); str = str.Replace("$LOCALSTATE", LocalState);
str = str.Replace("$LOCALCACHE", LocalCache); str = str.Replace("$LOCALCACHE", LocalCache);
str = str.Replace("$COMMOJANG", ComMojang);
str = str.Replace("$PREMIUMCACHE", PremiumCache); str = str.Replace("$PREMIUMCACHE", PremiumCache);
str = str.Replace("$SERVERPACKCACHE", ServerPackCache); str = str.Replace("$SERVERPACKCACHE", ServerPackCache);
@ -117,7 +109,6 @@ namespace McCrypt
ApplicationDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); ApplicationDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
KeysDbPath = Path.Combine(ApplicationDirectory, "keys.db"); KeysDbPath = Path.Combine(ApplicationDirectory, "keys.db");
MinecraftFolder = Path.Combine(LocalAppdata, "Packages", "Microsoft.MinecraftUWP_8wekyb3d8bbwe"); MinecraftFolder = Path.Combine(LocalAppdata, "Packages", "Microsoft.MinecraftUWP_8wekyb3d8bbwe");
rebaseAll(); rebaseAll();
} }
@ -168,14 +159,6 @@ namespace McCrypt
rebaseSearchFolders(); rebaseSearchFolders();
break; break;
case "ComMojang":
ComMojang = resolve(keyvalpair[1]);
break;
case "WorldsFolder":
WorldsFolder = resolve(keyvalpair[1]);
break;
case "OutputFolder": case "OutputFolder":
OutFolder = resolve(keyvalpair[1]); OutFolder = resolve(keyvalpair[1]);
break; break;
@ -201,12 +184,7 @@ namespace McCrypt
case "ZipThePacks": case "ZipThePacks":
ZipPacks = (resolve(keyvalpair[1]).ToLower() == "yes"); ZipPacks = (resolve(keyvalpair[1]).ToLower() == "yes");
break; break;
case "MultiThread":
MultiThread = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
case "DecryptExistingWorlds":
DecryptExistingWorlds = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
} }
} }
} }

View file

@ -49,8 +49,18 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Config.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="default.cfg" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\McCrypt\LibMcCrypt.csproj"> <ProjectReference Include="..\McCrypt\LibMcCrypt.csproj">
@ -58,6 +68,12 @@
<Name>LibMcCrypt</Name> <Name>LibMcCrypt</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="illager.ico" /> <Content Include="illager.ico" />
</ItemGroup> </ItemGroup>

View file

@ -2,11 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Net.Configuration;
using System.Runtime.Remoting.Messaging;
using System.Threading; using System.Threading;
using McCrypt; using McCrypt;
using McCrypt.PackData;
namespace McDecryptor namespace McDecryptor
{ {
@ -48,8 +45,7 @@ namespace McDecryptor
}); });
thrd.Priority = ThreadPriority.Highest; thrd.Priority = ThreadPriority.Highest;
thrd.Start(); thrd.Start();
if (!Config.MultiThread) thrd.Join(); threads.Add(thrd);
else threads.Add(thrd);
} }
foreach (Thread t in threads.ToArray()) foreach (Thread t in threads.ToArray())
@ -66,8 +62,7 @@ namespace McDecryptor
}); });
thrd.Priority = ThreadPriority.Highest; thrd.Priority = ThreadPriority.Highest;
thrd.Start(); thrd.Start();
if (!Config.MultiThread) thrd.Join(); threads.Add(thrd);
else threads.Add(thrd);
} }
@ -77,28 +72,6 @@ namespace McDecryptor
threads.Clear(); threads.Clear();
} }
static void DecryptPack(string filePath)
{
string levelDatFile = Path.Combine(filePath, "level.dat");
string skinsJsonFile = Path.Combine(filePath, "skins.json");
string oldSchoolZipe = Path.Combine(filePath, "content.zipe");
Marketplace.DecryptContents(filePath);
if (Config.CrackPacks)
{
if (File.Exists(oldSchoolZipe))
Marketplace.CrackZipe(oldSchoolZipe);
if (File.Exists(levelDatFile))
Marketplace.CrackLevelDat(levelDatFile);
if (File.Exists(skinsJsonFile))
Marketplace.CrackSkinsJson(skinsJsonFile);
}
}
static void Main(string[] args) static void Main(string[] args)
{ {
Console.WriteLine("-- McDecryptor --"); Console.WriteLine("-- McDecryptor --");
@ -145,21 +118,39 @@ namespace McDecryptor
} }
List<ContentListing> premiumContents = new List<ContentListing>();
Console.WriteLine("\n\n"); Console.WriteLine("\n\n");
Console.WriteLine("Select what to decrypt: "); Console.WriteLine("Select what to decrypt: ");
int total = 1; int total = 1;
PReader pReader = new PReader();
PEntry[] entries = pReader.PEntryList;
foreach (PEntry entry in entries) foreach (string searchFolder in Config.SearchFolders)
{ {
Console.WriteLine(total.ToString() + ") (" + entry.ProductType + ") " + entry.Name); foreach(string searchModule in Config.SearchModules)
{
string moduleFolder = Path.Combine(searchFolder, searchModule);
if (Directory.Exists(moduleFolder))
{
foreach (string moduleItem in Directory.GetDirectories(moduleFolder, "*", SearchOption.TopDirectoryOnly))
{
ContentListing cList = new ContentListing();
cList.Name = Manifest.ReadName(Path.Combine(moduleItem, "manifest.json"));
cList.Type = searchModule;
cList.Id = total;
cList.Path = moduleItem;
premiumContents.Add(cList);
Console.WriteLine(cList.Id.ToString() + ") (" + cList.Type + ") " + cList.Name);
total++; total++;
} }
}
}
}
Console.WriteLine("Select one or multiple (seperated by ',') or write \"ALL\", numerical values"); Console.WriteLine("Select multiple (seperated by ',') or write \"ALL\"");
List<int> toDecrypt = new List<int>(); List<int> toDecrypt = new List<int>();
while (true) while (true)
@ -174,9 +165,9 @@ namespace McDecryptor
toDecrypt.Add(i); toDecrypt.Add(i);
break; break;
} }
string[] txtentries = readText.Split(','); string[] entries = readText.Split(',');
foreach(string entry in txtentries) { foreach(string entry in entries) {
int tdc = Convert.ToInt32(entry.Trim())-1; int tdc = Convert.ToInt32(entry.Trim())-1;
if (tdc < 0 || tdc >= total) if (tdc < 0 || tdc >= total)
continue; continue;
@ -192,8 +183,8 @@ namespace McDecryptor
foreach (int decryptMe in toDecrypt.ToArray()) foreach (int decryptMe in toDecrypt.ToArray())
{ {
PEntry cEntry = entries[decryptMe]; ContentListing cListing = premiumContents.ToArray()[decryptMe];
string outFolder = Path.Combine(Config.OutFolder, cEntry.ProductType, EscapeFilename(cEntry.Name)); string outFolder = Path.Combine(Config.OutFolder, cListing.Type, EscapeFilename(cListing.Name));
int counter = 1; int counter = 1;
string ogOutFolder = outFolder; string ogOutFolder = outFolder;
@ -203,65 +194,39 @@ namespace McDecryptor
counter++; counter++;
} }
Console.WriteLine("Decrypting: " + cEntry.Name);
Console.WriteLine("Decrypting: " + cListing.Name);
Directory.CreateDirectory(outFolder); Directory.CreateDirectory(outFolder);
CopyDirectory(cListing.Path, outFolder);
try try
{ {
if (cEntry.ProductType == "addon") string levelDatFile = Path.Combine(outFolder, "level.dat");
{ string skinsJsonFile = Path.Combine(outFolder, "skins.json");
// copy & decrypt main file string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
string subDir = Path.Combine(outFolder, cEntry.Type);
Directory.CreateDirectory(subDir);
CopyDirectory(cEntry.FilePath, subDir);
DecryptPack(subDir);
// copy & decrypt file dependancies Marketplace.DecryptContents(outFolder);
PEntry[] deps = pReader.GetDependancies(cEntry);
foreach (PEntry dependancy in deps)
{
string newDir = Path.Combine(outFolder, dependancy.Type);
Console.WriteLine("Decrypting dependancy: " + dependancy.Type + "/" + dependancy.Name);
Directory.CreateDirectory(newDir);
CopyDirectory(dependancy.FilePath, newDir); if (Config.CrackPacks)
DecryptPack(newDir);
}
}
else if(cEntry.ProductType == "minecraftWorlds")
{ {
CopyDirectory(cEntry.FilePath, outFolder); if (File.Exists(oldSchoolZipe))
DecryptPack(outFolder); Marketplace.CrackZipe(oldSchoolZipe);
PEntry[] deps = pReader.GetDependancies(cEntry); if (File.Exists(levelDatFile))
foreach (PEntry dependancy in deps) Marketplace.CrackLevelDat(levelDatFile);
{
Console.WriteLine("Decrypting dependancy: " + dependancy.ProductType+"/"+dependancy.Name);
string newDir = Path.Combine(outFolder, dependancy.ProductType, Path.GetFileName(dependancy.FilePath));
CopyDirectory(dependancy.FilePath, newDir); if (File.Exists(skinsJsonFile))
DecryptPack(newDir); Marketplace.CrackSkinsJson(skinsJsonFile);
}
}
else
{
CopyDirectory(cEntry.FilePath, outFolder);
DecryptPack(outFolder);
} }
if (Config.ZipPacks) if (Config.ZipPacks)
{ {
Console.WriteLine("Zipping: " + cEntry.Name); Console.WriteLine("Zipping: " + cListing.Name);
string ext = ""; string ext = "";
if (cEntry.ProductType == "world_templates") if (File.Exists(levelDatFile))
ext += ".mctemplate"; ext += ".mctemplate";
else if (cEntry.ProductType == "minecraftWorlds") else if (false)
ext += ".mcworld";
else if (cEntry.ProductType == "addon")
ext += ".mcaddon"; ext += ".mcaddon";
else if (cEntry.ProductType == "persona")
ext += ".mcpersona";
else else
ext += ".mcpack"; ext += ".mcpack";
@ -276,12 +241,11 @@ namespace McDecryptor
} }
catch (Exception e) catch (Exception e)
{ {
Console.Error.WriteLine("Failed to decrypt: " + cEntry.Name + " " + e.Message); Console.Error.WriteLine("Failed to decrypt: " + cListing.Name+ " "+e.Message);
Directory.Delete(outFolder, true); Directory.Delete(outFolder, true);
} }
} }
Console.WriteLine("Finished."); Console.WriteLine("Finished.");

View file

@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace McCrypt.Properties { namespace McDecryptor.Properties {
using System; using System;
@ -39,7 +39,7 @@ namespace McCrypt.Properties {
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("McCrypt.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("McDecryptor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;

View file

@ -11,14 +11,11 @@ KeysDb: $EXECDIR\keys.db
# These folders only exist in UWP Versions of Bedrock # These folders only exist in UWP Versions of Bedrock
# On WIN32 versions it may be under "internalStorage" # On WIN32 versions it may be under "internalStorage"
LocalState: $MCDIR\LocalState LocalState: $MCDIR\LocalState
LocalCache: $MCDIR\LocalCache LocalCache: $MCDIR\LocalCache\McDecryptor
# location of games/com.mojang folder
ComMojang: $LOCALSTATE\games\com.mojang
# Path to options.txt # Path to options.txt
# needed to decrypt .ent files since beta 1.19. # needed to decrypt .ent files since beta 1.19.
OptionsTxt: $COMMOJANG\minecraftpe\options.txt OptionsTxt: $LOCALSTATE\games\com.mojang\minecraftpe\options.txt
# Locations of Premium Cache (marketplace contents) # Locations of Premium Cache (marketplace contents)
# Server Pack Cache (server resource packs) # Server Pack Cache (server resource packs)
@ -26,10 +23,6 @@ OptionsTxt: $COMMOJANG\minecraftpe\options.txt
PremiumCache: $LOCALSTATE\premium_cache PremiumCache: $LOCALSTATE\premium_cache
ServerPackCache: $LOCALCACHE\packcache ServerPackCache: $LOCALCACHE\packcache
RealmsPremiumCache: $LOCALCACHE\premiumcache RealmsPremiumCache: $LOCALCACHE\premiumcache
WorldsFolder: $COMMOJANG\minecraftWorlds
# Should i allow decrypting pre-existing world files
DecryptExistingWorlds: yes
# Should it crack the packs (change skin packs to free, remove prid from worlds) # Should it crack the packs (change skin packs to free, remove prid from worlds)
CrackThePacks: yes CrackThePacks: yes
@ -37,9 +30,6 @@ CrackThePacks: yes
# Should i zip packs to .mcpack/.mctemplate # Should i zip packs to .mcpack/.mctemplate
ZipThePacks: yes ZipThePacks: yes
# Use Multiple threads to decrypt (faster, but requires good CPU)
MultiThread: yes
# Where to output the decrypted data, (deafult to install into the game) # Where to output the decrypted data, (deafult to install into the game)
OutputFolder: $EXECDIR\output_packs OutputFolder: $EXECDIR\output_packs
@ -48,7 +38,7 @@ OutputFolder: $EXECDIR\output_packs
# for packs. # for packs.
# You can use AdditionalModuleDir to add new folders to look for encrypted data inside of the search folders # You can use AdditionalModuleDir to add new folders to look for encrypted data inside of the search folders
# normally it'll just look inside say "resource_packs" "skin_packs" "persona", "behaviour_packs" etc # normally it'll just look inside say "resource_packs" "skin_packs" "persona", "behaviour packs" etc
#AdditionalSearchDir: C:\Some\Folder\With\ResourcePacks #AdditionalSearchDir: C:\Some\Folder\With\ResourcePacks
#AdditionalSearchDir: C:\Some\Other\Folder\With\ResourcePacks #AdditionalSearchDir: C:\Some\Other\Folder\With\ResourcePacks
@ -61,7 +51,6 @@ OutputFolder: $EXECDIR\output_packs
# $EXECDIR - Folder the program is running in # $EXECDIR - Folder the program is running in
# $LOCALSTATE - LocalState Folder # $LOCALSTATE - LocalState Folder
# $LOCALCACHE - LocalCache Folder. # $LOCALCACHE - LocalCache Folder.
# $COMMOJANG - ComMojang Folder.
# $PREMIUMCACHE - Premium Cache Folder # $PREMIUMCACHE - Premium Cache Folder
# $SERVERPACKCACHE - Server Pack Cache Folder # $SERVERPACKCACHE - Server Pack Cache Folder
# $REALMSPREMIUMCACHE - Realms Pack Cache Folder # $REALMSPREMIUMCACHE - Realms Pack Cache Folder