public void DecompressionProducesExpectedOutput() { var decompressed = VbaCompression.Decompress(_expectedCompressedBytes); Assert.Equal(_expectedDecompressedBytes.Length, decompressed.Length); Assert.True(_expectedDecompressedBytes.SequenceEqual(decompressed)); }
public void GivenLargeByteSequenceWithLowCompressibilityCompressingAndDecompressionProducesSameInput() { var data = GetLargeByteSequenceWithLowCompressibility().ToArray(); var compressedData = VbaCompression.Compress(data); var convertedData = VbaCompression.Decompress(compressedData); Assert.True(data != convertedData); Assert.True(data.LongLength == convertedData.LongLength); Assert.True(data.SequenceEqual(convertedData)); }
/** * Create VBA Project from file * * @param sPath path of macro enabled Excel, Powerpoint or Word file. */ public VBAProject(string sPath) { //Initialize pPath pPath = sPath; //Get unzip location unzipTempPath = CreateUniqueTempDirectory(); /* EvilClippy brute forces the file open, It does this in a fairly unclean manner. We will assume the file, * is named correctly (extension wise). This, although requiring more boiler plate will look a lot cleaner. */ // Get extension of file: string ext = Path.GetExtension(sPath); //Parse extension and create sOLEFileName switch (ext) { case ".xlsm": case ".xlam": isOpenXML = true; sOLEFileName = Path.Combine(unzipTempPath, "xl", "vbaProject.bin"); break; case ".docm": isOpenXML = true; sOLEFileName = Path.Combine(unzipTempPath, "word", "vbaProject.bin"); break; case ".pptm": isOpenXML = true; sOLEFileName = Path.Combine(unzipTempPath, "ppt", "vbaProject.bin"); //untested break; case ".xls": case ".doc": case ".ppt": //Copy path to sOLEFileName to prevent overwriting (we'll overrite this file directly) sOLEFileName = Path.Combine(unzipTempPath, Path.GetFileName(sPath)); File.Copy(sPath, sOLEFileName); break; default: Console.WriteLine("ERROR: Could not open file " + sPath); Console.WriteLine("Please make sure this file exists, has a valid extension and is of a valid type."); Console.WriteLine(); break; } //Unzip to unzipTemoPath if isOpenXML. Otherwise create compound file. if (isOpenXML) { ZipFile.ExtractToDirectory(sPath, unzipTempPath); } //Create Compound file from VBProject.bin or xls,doc,ppt file: cf = new CompoundFile(sOLEFileName, CFSUpdateMode.Update, 0); // Read relevant streams switch (ext) { case ".xlsm": case ".xlam": case ".docm": case ".pptm": commonStorage = cf.RootStorage; break; case ".doc": commonStorage = cf.RootStorage.GetStorage("Macros"); //Note you can also use `cf.RootStorage.TryGetStorage("Macros")` which returns null if not found. break; case ".ppt": //untested - don't know if this is the case for ppts case ".xls": commonStorage = cf.RootStorage.GetStorage("_VBA_PROJECT_CUR"); break; } vbaProjectStream = commonStorage.GetStorage("VBA").GetStream("_VBA_PROJECT").GetData(); //Contains VBA Project properties, including module names. Remove module names from this stream to hide them. //PROJECT stream: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/cc848a02-6f87-49a4-ad93-6edb3103f593 //More information: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/d88cb9d8-a475-423d-b370-cc0caaf78628 projectStream = commonStorage.GetStream("project").GetData(); //PROJECTwm stream contains all names of all Modules. //PROJECTwm stream: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/514acc65-ea7b-4813-aaf7-fabb1bca0ba2 //More Information: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/c458f2e6-f2cc-4c2d-96c7-91a3e63f2fe1 projectwmStream = commonStorage.GetStream("PROJECTwm").GetData(); //Contains names of visible modules and module source code text (compressed) //VBA Storage: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/b693e0ba-489f-4ac8-ac9d-6387fb5779bb //VBA StorageInfo: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/170f52a0-4cd6-4729-b51a-d08155cbd213 //Dir Stream: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ovba/672d276c-d83c-4452-993b-ca9eca3d8917 dirStream = VbaCompression.Decompress(commonStorage.GetStorage("VBA").GetStream("dir").GetData()); // Read project streams as string string projectStreamString = System.Text.Encoding.UTF8.GetString(projectStream); string projectwmStreamString = System.Text.Encoding.UTF8.GetString(projectwmStream); Console.WriteLine(System.Text.Encoding.UTF8.GetString(projectStream)); Console.WriteLine(System.Text.Encoding.UTF8.GetString(projectwmStream)); // Find all VBA modules in current file vbaModulesEx = ParseModulesFromDirStream(dirStream); // Write streams to debug log (if verbosity enabled) Console.WriteLine("Hex dump of original _VBA_PROJECT stream:\n" + Utils.HexDump(vbaProjectStream)); Console.WriteLine("Hex dump of original dir stream:\n" + Utils.HexDump(dirStream)); }