private string deObfuscateImage(ObfuscationMode obfMode, string pathOfInputGif, string strGuid)
        {
            string         pathToTemp = Path.GetTempPath();
            string         nameOfGifForOutputCompositeGif;
            int            pixelYDestination;
            int            pixelXDestination;
            DateTimeOffset now         = DateTimeOffset.UtcNow;
            string         strUtcTicks = now.UtcTicks.ToString();
            string         iso         = DateTime.UtcNow.ToString("yyyy.MM.ddTHH.mm.ss.fffff");

            if (obfMode == ObfuscationMode.DEOBFUSCATE)
            {
                nameOfGifForOutputCompositeGif = "{0}-TEMP-TEST-COMPOSITE-DEOBFUSCATE-OUTPUT-{1}-" + strGuid + "-{2}";
            }
            else
            {
                nameOfGifForOutputCompositeGif = "{0}-TEMP-TEST-COMPOSITE-OBFUSCATE-OUTPUT-{1}-" + strGuid + "-{2}";
            }
            string pathCompositeImageOutPreRotate  = Path.Combine(pathToTemp, String.Format(nameOfGifForOutputCompositeGif, iso, "A-PRE-ROTATE", TESTIMAGE_OBFUSCATED));
            string pathCompositeImageOutPostRotate = Path.Combine(pathToTemp, String.Format(nameOfGifForOutputCompositeGif, iso, "B-PST-ROTATE", TESTIMAGE_OBFUSCATED));

            ql(String.Format("Starting deObfuscateImage - about to start writing multiple tiles to a single file. Tile width : {0} and tile height : {1}.", SMALLTILEWIDTH, SMALLTILEHEIGHT));
            using (var image = new MagickImage(pathOfInputGif))
            {
                if (obfMode == ObfuscationMode.OBFUSCATE)
                {
                    image.Rotate(180);
                }
                int tilesHigh = image.Height / SMALLTILEHEIGHT;
                int tilesWide = image.Width / SMALLTILEWIDTH;
                int tileIndex = 0;

                //The 'Blue' background is just to highlight any problems with tile layout
                var imageout = new MagickImage(MagickColors.Blue, image.Width, image.Height);

                //Two steps to the List because I couldn't figure out a better way to do it !
                IEnumerable <IMagickImage <byte> > enumerableTiles = image.CropToTiles(SMALLTILEWIDTH, SMALLTILEHEIGHT);
                List <IMagickImage <byte> >        lstTiles        = enumerableTiles.ToList <IMagickImage <byte> >();
                //
                for (int ystepper = 0; ystepper < tilesHigh; ystepper++)
                {
                    pixelYDestination = ystepper * SMALLTILEHEIGHT;
                    for (int xstepper = 0; xstepper < tilesWide; xstepper++)
                    {
                        if ((ystepper % 2) == 0)
                        {
                            pixelXDestination = xstepper * SMALLTILEWIDTH;
                        }
                        else
                        {
                            pixelXDestination = ((((image.Width / SMALLTILEWIDTH) - 1) - xstepper) * SMALLTILEWIDTH);
                        }
                        //'Paste' the current tile onto the output image at the X/Y determined above
                        imageout.Composite(lstTiles[tileIndex], pixelXDestination, pixelYDestination);
                        ql(String.Format("Writing tile {0} at location ({1}, {2})", tileIndex, pixelXDestination, pixelYDestination));
                        tileIndex++;
                    }
                }

                imageout.Write(pathCompositeImageOutPreRotate);

                if (obfMode == ObfuscationMode.DEOBFUSCATE)
                {
                    imageout.Rotate(180);
                }
                imageout.Write(pathCompositeImageOutPostRotate);
            }
            //return Path.GetFileName(pathCompositeImageOutPostRotate).ToString();
            return(pathCompositeImageOutPostRotate);
        }
示例#2
0
        public byte[] TransformWorkbookBytes(byte[] bytes, ObfuscationMode mode, string password = XorObfuscation.DefaultPassword)
        {
            VirtualStreamReader vsr = new VirtualStreamReader(new MemoryStream(bytes));
            MemoryStream        ms  = new MemoryStream();
            BinaryWriter        bw  = new BinaryWriter(ms);

            while (vsr.BaseStream.Position < vsr.BaseStream.Length)
            {
                BiffHeader bh;
                bh.id = (RecordType)vsr.ReadUInt16();

                //Handle case where RecordId is empty
                if (bh.id == 0)
                {
                    break;
                }

                bh.length = vsr.ReadUInt16();

                //Taken from https://social.msdn.microsoft.com/Forums/en-US/3dadbed3-0e68-4f11-8b43-3a2328d9ebd5/xls-xor-data-transformation-method-1


                byte XorArrayIndex = (byte)((vsr.BaseStream.Position + bh.length) % 16);


                //We remove the FilePass Record for the decrypted document
                if (mode == ObfuscationMode.Decrypt && bh.id == RecordType.FilePass)
                {
                    //Skip the remaining FilePass bytes
                    ushort encryptionMode = vsr.ReadUInt16();

                    if (encryptionMode != 0)
                    {
                        throw new NotImplementedException("FilePass EncryptionMode of " + encryptionMode +
                                                          " is unsupported.");
                    }

                    ushort key    = vsr.ReadUInt16();
                    ushort verify = vsr.ReadUInt16();

                    ushort passwordVerify = CreatePasswordVerifier_Method1(password);

                    if (verify != passwordVerify)
                    {
                        throw new ArgumentException(
                                  "Incorrect decryption password. Try bruteforcing the password with another tool.");
                    }

                    continue;
                }
                ;

                bw.Write(Convert.ToUInt16(bh.id));
                bw.Write(Convert.ToUInt16(bh.length));

                //If we're encrypting, then use the byte writer for our current position rather than the read stream
                if (mode == ObfuscationMode.Encrypt)
                {
                    XorArrayIndex = (byte)((bw.BaseStream.Position + bh.length) % 16);
                }

                //Nothing to decrypt for 0 length
                if (bh.length == 0)
                {
                    continue;
                }

                switch (bh.id)
                {
                case RecordType.BOF:
                case RecordType.FilePass:
                case RecordType.UsrExcl:
                case RecordType.FileLock:
                case RecordType.InterfaceHdr:
                case RecordType.RRDInfo:
                case RecordType.RRDHead:
                    byte[] recordBytes = vsr.ReadBytes(bh.length);
                    bw.Write(recordBytes);

                    //If this is the first BOF record, we inject the appropriate FilePass record
                    if (mode == ObfuscationMode.Encrypt &&
                        bh.id == RecordType.BOF &&
                        vsr.BaseStream.Position == (bh.length + 4))
                    {
                        ushort   key           = CreateXorKey_Method1(password);
                        ushort   verify        = CreatePasswordVerifier_Method1(password);
                        FilePass filePass      = new FilePass(key, verify);
                        byte[]   filePassBytes = filePass.GetBytes();
                        bw.Write(filePassBytes);
                    }

                    continue;

                case RecordType.BoundSheet8:
                    //Special Case - don't encrypt/decrypt the lbPlyPos Field
                    uint lbPlyPos = vsr.ReadUInt32();

                    //For encryption we need to adjust this by the added FilePass record length
                    //Decryption we auto-fix afterwards, but encrypted entries don't auto-fix well
                    // if (mode == ObfuscationMode.Encrypt)
                    // {
                    //     lbPlyPos += 10;
                    // }

                    bw.Write(lbPlyPos);
                    //Since we are skipping lbPlyPos, we need to update the XorArrayIndex offset as well
                    XorArrayIndex = (byte)((XorArrayIndex + 4) % 16);
                    byte[] remainingBytes = vsr.ReadBytes(bh.length - 4);
                    if (mode == ObfuscationMode.Decrypt)
                    {
                        byte[] decryptedBytes = DecryptData_Method1(password, remainingBytes, XorArrayIndex);
                        bw.Write(decryptedBytes);
                    }
                    else
                    {
                        byte[] encryptedBytes = EncryptData_Method1(password, remainingBytes, XorArrayIndex);
                        bw.Write(encryptedBytes);
                    }
                    continue;

                default:
                    byte[] preTransformBytes = vsr.ReadBytes(bh.length);
                    if (mode == ObfuscationMode.Decrypt)
                    {
                        byte[] decBytes = DecryptData_Method1(password, preTransformBytes, XorArrayIndex);
                        bw.Write(decBytes);
                    }
                    else
                    {
                        byte[] encBytes = EncryptData_Method1(password, preTransformBytes, XorArrayIndex);
                        bw.Write(encBytes);
                    }
                    continue;
                }
            }

            return(bw.GetBytesWritten());
        }
 /// <summary>
 ///
 /// This takes the path to input GIF which has been previously obfucscated by slicing up into tiles
 /// and then re-arranging the tiles before writing the de-obfucasted image to disk.
 ///
 /// Based on a previously known tile size and the width/height of the input image the process slices
 /// up the input image into a list of tiles. The list is then traversed and each tile is written to
 /// the output disk. The position of each tile in the output is determined by: in the odd numbered
 /// rows, writing out the tiles left to right and; in the even numbered rows writing out the tiles
 /// right to left.
 ///
 /// When the writing to output is finished the output image is rotated by 180 degrees.
 ///
 /// NOTE: The processing shown here may be thought to be weird but it emulates processing seen in
 /// another system so what it is is what it is ;-)
 ///
 /// </summary>
 /// <param name="pathOfInputGif">The path of input GIF.</param>
 private string deObfuscateImage(ObfuscationMode obfMode, string pathOfInputGif)
 {
     return(this.deObfuscateImage(obfMode, pathOfInputGif, System.Guid.NewGuid().ToString()));
 }