public static Stream ReadCombinedAssets(this IAssetsFileProvider fp, string assetsFilePath) { string actualName = fp.CorrectAssetFilename(assetsFilePath); List <string> assetFiles = new List <string>(); if (actualName.ToLower().EndsWith("split0")) { assetFiles.AddRange(fp.FindFiles(actualName.Replace(".split0", ".split*")) .OrderBy(x => Convert.ToInt32(x.Split(new string[] { ".split" }, StringSplitOptions.None).Last()))); } else { return(fp.GetReadStream(actualName)); } MemoryStream msFullFile = new MemoryStream(); foreach (string assetsFile in assetFiles) { byte[] fileBytes = fp.Read(assetsFile); msFullFile.Write(fileBytes, 0, fileBytes.Length); } return(msFullFile); }
//if file ends in .split0 yes //if file ends in .assets yes //if file has no extension yes public List <string> FindAndLoadAllAssets() { List <string> loadedFiles = new List <string>(); var foundFiles = _fileProvider.FindFiles(_assetsRootPath + "*"); List <string> tryFiles = new List <string>(); foreach (var foundFile in foundFiles) { var filename = foundFile.Substring(_assetsRootPath.Length); if (filename.Any(x => x == '/')) { if (!filename.Substring(filename.LastIndexOf("/")).Contains(".")) { tryFiles.Add(filename); continue; } } else if (!filename.Contains(".")) { tryFiles.Add(filename); continue; } if (filename.ToLower().EndsWith(".split0")) { filename = filename.Substring(0, filename.Length - ".split0".Length); tryFiles.Add(filename); continue; } if (filename.ToLower().EndsWith(".assets")) { tryFiles.Add(filename); continue; } } foreach (var tryFile in tryFiles) { if (_openAssetsFiles.ContainsKey(tryFile.ToLower())) { loadedFiles.Add(tryFile); continue; } AssetsFile file; if (TryGetAssetsFile(tryFile, out file)) { loadedFiles.Add(tryFile); } } return(loadedFiles); }
public static Stream ReadCombinedAssets(this IAssetsFileProvider fp, string assetsFilePath, out bool wasCombined) { string actualName = fp.CorrectAssetFilename(assetsFilePath); List <string> assetFiles = new List <string>(); if (actualName.ToLower().EndsWith("split0")) { assetFiles.AddRange(fp.FindFiles(actualName.Replace(".split0", ".split*")) .OrderBy(x => Convert.ToInt32(x.Split(new string[] { ".split" }, StringSplitOptions.None).Last()))); } else { wasCombined = false; return(fp.GetReadStream(actualName)); } wasCombined = true; //TODO: property or something on the file provider interface letting this code know if it should use the combined stream // I think combined stream may perform horribly on zip files or cause other issues. if (true) { return(new CombinedStream(assetFiles, fp)); } else { MemoryStream msFullFile = new MemoryStream(); foreach (string assetsFile in assetFiles) { byte[] fileBytes = fp.Read(assetsFile); msFullFile.Write(fileBytes, 0, fileBytes.Length); } return(msFullFile); } }
public void Sign(IAssetsFileProvider fileProvider) { MemoryStream msManifestFile = new MemoryStream(); MemoryStream msSigFile = new MemoryStream(); byte[] keyBlock; MemoryStream msSignatureFileBody = new MemoryStream(); try { //create the MF file header using (StreamWriter swManifest = GetSW(msManifestFile)) { swManifest.WriteLine("Manifest-Version: 1.0"); swManifest.WriteLine("Created-By: emulamer"); swManifest.WriteLine(); } //so that we can do it in one pass, write the MF and SF line items at the same time to their respective streams foreach (var infFile in fileProvider.FindFiles("*").Where(x => !x.StartsWith("META-INF"))) { WriteEntryHashes(fileProvider, infFile, msManifestFile, msSignatureFileBody); } //compute the hash on the entirety of the manifest file for the SF file msManifestFile.Seek(0, SeekOrigin.Begin); var manifestFileHash = _sha.ComputeHash(msManifestFile); //write the SF to memory then copy it out to the actual file- contents will be needed later to use for signing, don't want to hit the zip stream twice byte[] sigFileBytes = null; using (StreamWriter swSignatureFile = GetSW(msSigFile)) { swSignatureFile.WriteLine("Signature-Version: 1.0"); swSignatureFile.WriteLine($"SHA1-Digest-Manifest: {Convert.ToBase64String(manifestFileHash)}"); swSignatureFile.WriteLine("Created-By: emulamer"); swSignatureFile.WriteLine(); } msSignatureFileBody.Seek(0, SeekOrigin.Begin); msSignatureFileBody.CopyTo(msSigFile); msSigFile.Seek(0, SeekOrigin.Begin); sigFileBytes = msSigFile.ToArray(); //get the key block (all the hassle distilled into one line), then write it out to the RSA file keyBlock = SignIt(sigFileBytes); //delete all the META-INF stuff that exists already fileProvider.DeleteFiles("META-INF*"); //write the 3 files msManifestFile.Seek(0, SeekOrigin.Begin); fileProvider.Write("META-INF/MANIFEST.MF", msManifestFile.ToArray(), true, true); fileProvider.Write("META-INF/BS.SF", sigFileBytes, true, true); fileProvider.Write("META-INF/BS.RSA", keyBlock, true, true); fileProvider.Save(); } finally { if (msManifestFile != null) { msManifestFile.Dispose(); } if (msSignatureFileBody != null) { msSignatureFileBody.Dispose(); } if (msManifestFile != null) { msManifestFile.Dispose(); } if (msSigFile != null) { msSigFile.Dispose(); } } }
private void BtnLoad_Click(object sender, EventArgs e) { ContextMenu cm = new ContextMenu(new MenuItem[] { new MenuItem("APK", (s, e2) => { OpenFileDialog ofd = new OpenFileDialog() { CheckFileExists = true, Title = "Open Bundle File", Multiselect = false }; if (ofd.ShowDialog() == DialogResult.Cancel) { return; } CloseStuff(); try { _fileProvider = new ApkAssetsFileProvider(ofd.FileName, FileCacheMode.Memory, false); _manager = new AssetsManager(_fileProvider, BSConst.KnownFiles.AssetsRootPath, BSConst.GetAssetTypeMap()); if (_fileProvider.FindFiles("globalgamemanagers").Count > 0) { _manager.GetAssetsFile("globalgamemanagers.assets"); } if (_fileProvider.FindFiles("globalgamemanagers.assets*").Count > 0) { _manager.GetAssetsFile("globalgamemanagers.assets"); } _manager.FindAndLoadAllAssets(); FillAssetsFiles(); this.Text = "Assets Explorer - " + Path.GetFileName(ofd.FileName); } catch (Exception ex) { Log.LogErr("Couldn't load APK!", ex); MessageBox.Show("Failed to load!"); if (_fileProvider != null) { _fileProvider.Dispose(); _fileProvider = null; } return; } }), new MenuItem("Folder", (s, e2) => { FolderBrowserDialog fbd = new FolderBrowserDialog() { ShowNewFolderButton = false, Description = "Select Assets Root Folder" }; if (fbd.ShowDialog() == DialogResult.Cancel) { return; } CloseStuff(); try { _fileProvider = new FolderFileProvider(fbd.SelectedPath, false); _manager = new AssetsManager(_fileProvider, "", BSConst.GetAssetTypeMap()); if (_fileProvider.FindFiles("globalgamemanagers").Count > 0) { _manager.GetAssetsFile("globalgamemanagers.assets"); } if (_fileProvider.FindFiles("globalgamemanagers.assets*").Count > 0) { _manager.GetAssetsFile("globalgamemanagers.assets"); } _manager.FindAndLoadAllAssets(); FillAssetsFiles(); this.Text = "Assets Explorer - " + Path.GetFileName(fbd.SelectedPath); } catch (Exception ex) { Log.LogErr("Couldn't load APK!", ex); MessageBox.Show("Failed to load!"); if (_fileProvider != null) { _fileProvider.Dispose(); _fileProvider = null; } return; } }), new MenuItem("Bundle", (s, e2) => { OpenFileDialog ofd = new OpenFileDialog() { CheckFileExists = true, Title = "Open Bundle File", Multiselect = false }; if (ofd.ShowDialog() == DialogResult.Cancel) { return; } CloseStuff(); try { _fileProvider = new BundleFileProvider(ofd.FileName, true); _manager = new AssetsManager(_fileProvider, "", BSConst.GetAssetTypeMap()); _manager.FindAndLoadAllAssets(); FillAssetsFiles(); this.Text = "Assets Explorer - " + Path.GetFileName(ofd.FileName); } catch (Exception ex) { Log.LogErr("Couldn't load bundle!", ex); MessageBox.Show("Failed to load!"); if (_fileProvider != null) { _fileProvider.Dispose(); _fileProvider = null; } return; } }) }); cm.Show(btnLoad, new Point(0, btnLoad.Height)); return; }