Esempio n. 1
0
        private static Stack <AbstractPtg> UpdateSheetReferences(Stack <AbstractPtg> ptgStack, List <BoundSheet8> sheetRecords, ExternSheet externSheetRecord)
        {
            List <AbstractPtg> modifiedStack = new List <AbstractPtg>();

            foreach (var ptg in ptgStack)
            {
                if (ptg is PtgRef3d)
                {
                    PtgRef3d ref3d       = (ptg as PtgRef3d);
                    int      index       = ref3d.ixti;
                    XTI      relevantXti = externSheetRecord.rgXTI[index];
                    //Make sure this isn't a sheet or workbook level reference
                    if (relevantXti.itabFirst >= 0)
                    {
                        BoundSheet8 relevantSheet = sheetRecords[relevantXti.itabFirst];
                        string      sheetName     = relevantSheet.stName.Value;
                        modifiedStack.Add(new PtgRef3d(ref3d.rw, ref3d.col, ref3d.ixti, ref3d.rwRelative, ref3d.colRelative, sheetName));
                    }
                    else
                    {
                        modifiedStack.Add(ptg);
                    }
                }
                else
                {
                    modifiedStack.Add(ptg);
                }
            }
            modifiedStack.Reverse();
            return(new Stack <AbstractPtg>(modifiedStack));
        }
Esempio n. 2
0
        public void GenerateVelvetSweatshopMacroSheetSigs()
        {
            XorObfuscation xorObfuscation = new XorObfuscation();

            BoundSheet8 sheetVersion1 = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Macrosheet, "Sheet");
            BoundSheet8 sheetVersion2 = new BoundSheet8(BoundSheet8.HiddenState.Hidden, BoundSheet8.SheetType.Macrosheet, "Sheet1");
            BoundSheet8 sheetVersion3 = new BoundSheet8(BoundSheet8.HiddenState.VeryHidden, BoundSheet8.SheetType.Macrosheet, "Sheet2");

            BoundSheet8[] sheets = new[] { sheetVersion1, sheetVersion2, sheetVersion3 };

            int hiddenState = 0;

            foreach (BoundSheet8 currentSheet in sheets)
            {
                for (int offset = 0; offset < 16; offset += 1)
                {
                    byte[] header        = currentSheet.GetBytes().Take(4).ToArray();
                    byte[] data          = currentSheet.GetBytes().Skip(4).ToArray();
                    byte[] encryptedData = xorObfuscation.EncryptData_Method1(XorObfuscation.DefaultPassword, data, (byte)offset);

                    string ruleName = string.Format("$boundsheet8_hs{0}_vs_xor_offset{1}", hiddenState, offset);

                    string yaraSig = ruleName + " = { ";
                    yaraSig += BitConverter.ToString(header.Take(2).ToArray()).Replace("-", " ");
                    yaraSig += " [6] ";
                    yaraSig += BitConverter.ToString(encryptedData.Skip(4).Take(2).ToArray()).Replace("-", " ");
                    yaraSig += " }";
                    Console.WriteLine(yaraSig);
                }

                hiddenState += 1;
            }
        }
Esempio n. 3
0
        public WorkbookStream InsertBoundSheetRecord(BoundSheet8 boundSheet8)
        {
            List <BiffRecord> records = WbStream.Records;

            List <BoundSheet8> sheets = records.Where(r => r.Id == RecordType.BoundSheet8).Select(sheet => BuildBoundSheetFromBytes(sheet.GetBytes())).ToList();

            boundSheet8.lbPlyPos = sheets.First().lbPlyPos;
            sheets.Add(boundSheet8);

            foreach (var sheet in sheets)
            {
                sheet.lbPlyPos += boundSheet8.Length;
            }


            var preSheetRecords  = records.TakeWhile(r => r.Id != RecordType.BoundSheet8);
            var postSheetRecords = records.SkipWhile(r => r.Id != RecordType.BoundSheet8)
                                   .SkipWhile(r => r.Id == RecordType.BoundSheet8);

            List <BiffRecord> newRecordList = preSheetRecords.Concat(sheets).Concat(postSheetRecords).ToList();

            WorkbookStream newStream = new WorkbookStream(newRecordList);

            WbStream = newStream;

            return(WbStream);
        }
Esempio n. 4
0
        public WorkbookStream AddMacroSheet(List <BiffRecord> macroSheetRecords, string sheetName, BoundSheet8.HiddenState hiddenState = BoundSheet8.HiddenState.Visible)
        {
            BoundSheet8 macroBoundSheet = new BoundSheet8(hiddenState, BoundSheet8.SheetType.Macrosheet, sheetName);

            WbStream = WbStream.AddSheet(macroBoundSheet, macroSheetRecords);
            return(WbStream);
        }
Esempio n. 5
0
        public void TestContainsRecord()
        {
            byte[]         wbBytes = TestHelpers.GetTemplateMacroBytes();
            WorkbookStream wbs     = new WorkbookStream(wbBytes);

            BoundSheet8 notContainedRecord = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Worksheet, "MySheetName");
            BoundSheet8 containedRecord    = wbs.GetAllRecordsByType <BoundSheet8>().First();

            Assert.IsTrue(wbs.ContainsRecord(containedRecord));
            Assert.IsFalse(wbs.ContainsRecord(notContainedRecord));
        }
        public void TestBiffRecordCloneAndGetBytes()
        {
            BoundSheet8 bs8 = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Worksheet, "MySheetName");

            byte[]     bs8bytes       = bs8.GetBytes();
            BiffRecord bs8CloneRecord = (BiffRecord)bs8.Clone();

            byte[] bs8cloneBytes = bs8CloneRecord.GetBytes();
            Assert.AreEqual(bs8bytes, bs8cloneBytes);
            BoundSheet8 bs8Clone = bs8CloneRecord.AsRecordType <BoundSheet8>();

            byte[] bs8asRecordBytes = bs8Clone.GetBytes();
            Assert.AreEqual(bs8bytes, bs8asRecordBytes);
        }
Esempio n. 7
0
        public WorkbookStream UnhideSheets()
        {
            List <BoundSheet8> sheetRecords = WbStream.GetAllRecordsByType <BoundSheet8>();

            foreach (var sheetRecord in sheetRecords)
            {
                BoundSheet8 unhiddenRecord = ((BiffRecord)sheetRecord.Clone()).AsRecordType <BoundSheet8>();
                unhiddenRecord.hsState = BoundSheet8.HiddenState.Visible;
                WbStream = WbStream.ReplaceRecord(sheetRecord, unhiddenRecord);
            }

            WbStream = WbStream.FixBoundSheetOffsets();

            return(WbStream);
        }
Esempio n. 8
0
        public WorkbookStream AddSheet(BoundSheet8 sheetHeader, byte[] sheetBytes)
        {
            WorkbookStream     newStream           = new WorkbookStream(Records);
            List <BoundSheet8> existingBoundSheets = newStream.GetAllRecordsByType <BoundSheet8>();
            BoundSheet8        lastSheet8          = existingBoundSheets.Last();

            newStream = newStream.InsertRecord(sheetHeader, lastSheet8);

            List <BiffRecord> sheetRecords = RecordHelper.ParseBiffStreamBytes(sheetBytes);

            newStream = newStream.InsertRecords(sheetRecords);

            newStream = newStream.FixBoundSheetOffsets();

            return(newStream);
        }
Esempio n. 9
0
        public void TestAddMacroSheet()
        {
            byte[]         wbBytes = TestHelpers.GetTemplateMacroBytes();
            WorkbookStream wbs     = new WorkbookStream(wbBytes);

            byte[]            mtBytes             = TestHelpers.GetMacroTestBytes();
            WorkbookStream    macroWorkbookStream = new WorkbookStream(mtBytes);
            BoundSheet8       macroSheet          = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Macrosheet, "MacroSheet");
            List <BOF>        macroWorkbookBofs   = macroWorkbookStream.GetAllRecordsByType <BOF>();
            BOF               LastBofRecord       = macroWorkbookBofs.Last();
            List <BiffRecord> sheetRecords        = macroWorkbookStream.GetRecordsForBOFRecord(LastBofRecord);

            byte[] sheetBytes = RecordHelper.ConvertBiffRecordsToBytes(sheetRecords);

            wbs = wbs.AddSheet(macroSheet, sheetBytes);
            ExcelDocWriter writer = new ExcelDocWriter();

            writer.WriteDocument(TestHelpers.AssemblyDirectory + Path.DirectorySeparatorChar + "addedsheet.xls", wbs.ToBytes());
        }
Esempio n. 10
0
        public void TestReplaceRecord()
        {
            byte[]         wbBytes = TestHelpers.GetTemplateMacroBytes();
            WorkbookStream wbs     = new WorkbookStream(wbBytes);

            BoundSheet8 bs8 = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Worksheet, "MySheetName");

            var recordCount = wbs.Records.Count;

            BoundSheet8 oldSheetRecord = wbs.GetAllRecordsByType <BoundSheet8>().First();

            WorkbookStream wbs2 = wbs.ReplaceRecord(oldSheetRecord, bs8);

            Assert.AreEqual(recordCount, wbs2.Records.Count);

            BoundSheet8 newSheetRecord = wbs2.GetAllRecordsByType <BoundSheet8>().First();

            Assert.AreEqual(newSheetRecord.stName.Value, bs8.stName.Value);

            Assert.IsFalse(wbs2.ContainsRecord(oldSheetRecord));
            Assert.IsTrue(wbs2.ContainsRecord(bs8));
        }
Esempio n. 11
0
        /// <summary>
        /// Needs to be called any time that we add a record that changes the start
        /// offset of worksheet streams.
        /// </summary>
        /// <returns></returns>
        public WorkbookStream FixBoundSheetOffsets()
        {
            List <BoundSheet8> oldSheetBoundRecords = GetAllRecordsByType <BoundSheet8>();

            //We ignore the first BOF record for the global/workbook stream
            List <BOF> bofRecords = GetAllRecordsByType <BOF>().Skip(1).ToList();

            WorkbookStream newStream = new WorkbookStream(Records);

            int sheetOffset = 0;

            //Assign each offset in order of definition (as per specification)
            foreach (var boundSheet in oldSheetBoundRecords)
            {
                long        offset         = newStream.GetRecordByteOffset(bofRecords[sheetOffset]);
                BoundSheet8 newBoundSheet8 = ((BiffRecord)boundSheet.Clone()).AsRecordType <BoundSheet8>();
                newBoundSheet8.lbPlyPos = (uint)offset;
                newStream    = newStream.ReplaceRecord(boundSheet, newBoundSheet8);
                sheetOffset += 1;
            }

            return(newStream);
        }
Esempio n. 12
0
        public void TestAddingSheetRecord()
        {
            byte[]         wbBytes = TestHelpers.GetTemplateMacroBytes();
            WorkbookStream wbs     = new WorkbookStream(wbBytes);

            BoundSheet8 bs8 = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Macrosheet, "MyMacroSheet");
            BoundSheet8 correctOffsetBs8 = ((BiffRecord)bs8.Clone()).AsRecordType <BoundSheet8>();

            BoundSheet8 oldSheetRecord = wbs.GetAllRecordsByType <BoundSheet8>().First();
            BoundSheet8 newSheetRecord = ((BiffRecord)oldSheetRecord.Clone()).AsRecordType <BoundSheet8>();

            // bs8.lbPlyPos = (uint) (oldSheetRecord.lbPlyPos + bs8.GetBytes().Length);

            List <BOF> bofRecords     = wbs.GetAllRecordsByType <BOF>();
            BOF        spreadSheetBOF = bofRecords.Last();



            // newSheetRecord.lbPlyPos = bs8.lbPlyPos;
            long offset = wbs.GetRecordByteOffset(spreadSheetBOF);

            bs8.lbPlyPos = oldSheetRecord.lbPlyPos;
            wbs          = wbs.InsertRecord(bs8, oldSheetRecord);
            offset       = wbs.GetRecordByteOffset(spreadSheetBOF);


            correctOffsetBs8.lbPlyPos = (uint)offset;
            newSheetRecord.lbPlyPos   = (uint)offset;

            wbs = wbs.ReplaceRecord(bs8, correctOffsetBs8);
            wbs = wbs.ReplaceRecord(oldSheetRecord, newSheetRecord);

            ExcelDocWriter writer = new ExcelDocWriter();

            writer.WriteDocument(TestHelpers.AssemblyDirectory + Path.DirectorySeparatorChar + "testbook.xls", wbs.ToBytes());
        }
Esempio n. 13
0
 public WorkbookStream AddSheet(BoundSheet8 sheetHeader, List <BiffRecord> records)
 {
     return(AddSheet(sheetHeader, RecordHelper.ConvertBiffRecordsToBytes(records)));
 }
Esempio n. 14
0
        /// <summary>
        /// Extracts the data from the stream
        /// </summary>
        public override void extractData()
        {
            BiffHeader bh;

            //try
            //{
            while (this.StreamReader.BaseStream.Position < this.StreamReader.BaseStream.Length)
            {
                bh.id     = (RecordType)this.StreamReader.ReadUInt16();
                bh.length = this.StreamReader.ReadUInt16();
                // Debugging output
                TraceLogger.DebugInternal("BIFF {0}\t{1}\t", bh.id, bh.length);

                switch (bh.id)
                {
                case RecordType.BoundSheet8:
                {
                    // Extracts the Boundsheet data
                    BoundSheet8 bs = new BoundSheet8(this.StreamReader, bh.id, bh.length);
                    TraceLogger.DebugInternal(bs.ToString());

                    SheetData sheetData = null;

                    switch (bs.dt)
                    {
                    case BoundSheet8.SheetType.Worksheet:
                        sheetData      = new WorkSheetData();
                        this.oldOffset = this.StreamReader.BaseStream.Position;
                        this.StreamReader.BaseStream.Seek(bs.lbPlyPos, SeekOrigin.Begin);
                        WorksheetExtractor se = new WorksheetExtractor(this.StreamReader, sheetData as WorkSheetData);
                        this.StreamReader.BaseStream.Seek(oldOffset, SeekOrigin.Begin);
                        break;

                    case BoundSheet8.SheetType.Chartsheet:
                        ChartSheetData chartSheetData = new ChartSheetData();

                        this.oldOffset = this.StreamReader.BaseStream.Position;
                        this.StreamReader.BaseStream.Seek(bs.lbPlyPos, SeekOrigin.Begin);
                        chartSheetData.ChartSheetSequence = new ChartSheetSequence(this.StreamReader);
                        this.StreamReader.BaseStream.Seek(oldOffset, SeekOrigin.Begin);

                        sheetData = chartSheetData;
                        break;

                    default:
                        TraceLogger.Info("Unsupported sheet type: {0}", bs.dt);
                        break;
                    }

                    if (sheetData != null)
                    {
                        // add general sheet info
                        sheetData.boundsheetRecord = bs;
                        this.workBookData.addBoundSheetData(sheetData);
                    }
                }
                break;

                case RecordType.Template:
                {
                    this.workBookData.Template = true;
                }
                break;

                case RecordType.SST:
                {
                    /* reads the shared string table biff record and following continue records
                     * creates an array of bytes and then puts that into a memory stream
                     * this all is used to create a longer biffrecord then 8224 bytes. If theres a string
                     * beginning in the SST that is then longer then the 8224 bytes, it continues in the
                     * CONTINUE BiffRecord, so the parser has to read over the SST border.
                     * The problem here is, that the parser has to overread the continue biff record header
                     */
                    //SST sst;
                    //UInt16 length = bh.length;

                    //// save the old offset from this record begin
                    //this.oldOffset = this.StreamReader.BaseStream.Position;
                    //// create a list of bytearrays to store the following continue records
                    //// List<byte[]> byteArrayList = new List<byte[]>();
                    //byte[] buffer = new byte[length];
                    //LinkedList<VirtualStreamReader> vsrList = new LinkedList<VirtualStreamReader>();
                    //buffer = this.StreamReader.ReadBytes((int)length);
                    //// byteArrayList.Add(buffer);

                    //// create a new memory stream and a new virtualstreamreader
                    //MemoryStream bufferstream = new MemoryStream(buffer);
                    //VirtualStreamReader binreader = new VirtualStreamReader(bufferstream);
                    //BiffHeader bh2;
                    //bh2.id = (RecordType)this.StreamReader.ReadUInt16();

                    //while (bh2.id == RecordType.Continue)
                    //{
                    //    bh2.length = (UInt16)(this.StreamReader.ReadUInt16());

                    //    buffer = new byte[bh2.length];

                    //    // create a buffer with the bytes from the records and put that array into the
                    //    // list
                    //    buffer = this.StreamReader.ReadBytes((int)bh2.length);
                    //    // byteArrayList.Add(buffer);

                    //    // create for each continue record a new streamreader !!
                    //    MemoryStream contbufferstream = new MemoryStream(buffer);
                    //    VirtualStreamReader contreader = new VirtualStreamReader(contbufferstream);
                    //    vsrList.AddLast(contreader);


                    //    // take next Biffrecord ID
                    //    bh2.id = (RecordType)this.StreamReader.ReadUInt16();
                    //}
                    //// set the old position of the stream
                    //this.StreamReader.BaseStream.Position = this.oldOffset;

                    SST sst = new SST(this.StreamReader, bh.id, bh.length);
                    //this.StreamReader.BaseStream.Position = this.oldOffset + bh.length;
                    this.workBookData.SstData = sst;
                }
                break;

                case RecordType.EOF:
                {
                    // Reads the end of the internal file !!!
                    this.StreamReader.BaseStream.Seek(0, SeekOrigin.End);
                }
                break;

                case RecordType.ExternSheet:
                {
                    ExternSheet extsheet = new ExternSheet(this.StreamReader, bh.id, bh.length);
                    this.externSheets.Add(extsheet);
                    this.workBookData.addExternSheetData(extsheet);
                }
                break;

                case RecordType.SupBook:
                {
                    SupBook supbook = new SupBook(this.StreamReader, bh.id, bh.length);
                    this.supBooks.Add(supbook);
                    this.workBookData.addSupBookData(supbook);
                }
                break;

                case RecordType.XCT:
                {
                    XCT xct = new XCT(this.StreamReader, bh.id, bh.length);
                    this.XCTList.Add(xct);
                    this.workBookData.addXCT(xct);
                }
                break;

                case RecordType.CRN:
                {
                    CRN crn = new CRN(this.StreamReader, bh.id, bh.length);
                    this.CRNList.Add(crn);
                    this.workBookData.addCRN(crn);
                }
                break;

                case RecordType.ExternName:
                {
                    ExternName externname = new ExternName(this.StreamReader, bh.id, bh.length);
                    this.workBookData.addEXTERNNAME(externname);
                }
                break;

                case RecordType.Format:
                {
                    Format format = new Format(this.StreamReader, bh.id, bh.length);
                    this.workBookData.styleData.addFormatValue(format);
                }
                break;

                case RecordType.XF:
                {
                    XF xf = new XF(this.StreamReader, bh.id, bh.length);
                    this.workBookData.styleData.addXFDataValue(xf);
                }
                break;

                case RecordType.Style:
                {
                    Style style = new Style(this.StreamReader, bh.id, bh.length);
                    this.workBookData.styleData.addStyleValue(style);
                }
                break;

                case RecordType.Font:
                {
                    Font font = new Font(this.StreamReader, bh.id, bh.length);
                    this.workBookData.styleData.addFontData(font);
                }
                break;

                case RecordType.NAME:
                case RecordType.Lbl:
                {
                    Lbl name = new Lbl(this.StreamReader, bh.id, bh.length);
                    this.workBookData.addDefinedName(name);
                }
                break;

                case RecordType.BOF:
                {
                    this.workBookData.BOF = new BOF(this.StreamReader, bh.id, bh.length);
                }
                break;

                case RecordType.CodeName:
                {
                    this.workBookData.CodeName = new CodeName(this.StreamReader, bh.id, bh.length);
                }
                break;

                case RecordType.FilePass:
                {
                    throw new ExtractorException(ExtractorException.FILEENCRYPTED);
                }
                break;

                case RecordType.Palette:
                {
                    Palette palette = new Palette(this.StreamReader, bh.id, bh.length);
                    workBookData.styleData.setColorList(palette.rgbColorList);
                }
                break;

                default:
                {
                    // this else statement is used to read BiffRecords which aren't implemented
                    byte[] buffer = new byte[bh.length];
                    buffer = this.StreamReader.ReadBytes(bh.length);
                    TraceLogger.Debug("Unknown record found. ID {0}", bh.id);
                }
                break;
                }
            }
            //}
            //catch (Exception ex)
            //{
            //    TraceLogger.Error(ex.Message);
            //    TraceLogger.Debug(ex.ToString());
            //}
        }