Commit 0fd8f06bfa03126fbdfa80df2f4e092e7f5918c3

Authored by Rodolfo Saccani
Committed by GitHub
1 parent eb330067

Update plugin to latest version

The current version has severe performance issues when analyzing some binary xls files. Updating to the latest plugin version solves the problem.
oletools/thirdparty/oledump/plugin_biff.py
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 2
3 __description__ = 'BIFF plugin for oledump.py' 3 __description__ = 'BIFF plugin for oledump.py'
4 __author__ = 'Didier Stevens' 4 __author__ = 'Didier Stevens'
5 -__version__ = '0.0.5'  
6 -__date__ = '2019/03/06' 5 +__version__ = '0.0.6'
  6 +__date__ = '2019/11/05'
7 7
8 # Slightly modified version by Philippe Lagadec to be imported into olevba 8 # Slightly modified version by Philippe Lagadec to be imported into olevba
9 9
@@ -24,6 +24,7 @@ History: @@ -24,6 +24,7 @@ History:
24 2018/10/26: continue 24 2018/10/26: continue
25 2019/01/05: 0.0.4 added option -x 25 2019/01/05: 0.0.4 added option -x
26 2019/03/06: 0.0.5 enhanced parsing of formula expressions 26 2019/03/06: 0.0.5 enhanced parsing of formula expressions
  27 + 2019/11/05: 0.0.6 Python 3 support
27 28
28 Todo: 29 Todo:
29 """ 30 """
@@ -31,51 +32,68 @@ Todo: @@ -31,51 +32,68 @@ Todo:
31 import struct 32 import struct
32 import re 33 import re
33 import optparse 34 import optparse
34 -import binascii  
35 -import sys  
36 35
37 -# from olevba: 36 +def CombineHexASCII(hexDump, asciiDump, length):
  37 + if hexDump == '':
  38 + return ''
  39 + return hexDump + ' ' + (' ' * (3 * (length - len(asciiDump)))) + asciiDump
  40 +
  41 +def HexASCII(data, length=16):
  42 + result = []
  43 + if len(data) > 0:
  44 + hexDump = ''
  45 + asciiDump = ''
  46 + for i, b in enumerate(data):
  47 + if i % length == 0:
  48 + if hexDump != '':
  49 + result.append(CombineHexASCII(hexDump, asciiDump, length))
  50 + hexDump = '%08X:' % i
  51 + asciiDump = ''
  52 + hexDump += ' %02X' % P23Ord(b)
  53 + asciiDump += IFF(P23Ord(b) >= 32, b, '.')
  54 + result.append(CombineHexASCII(hexDump, asciiDump, length))
  55 + return result
38 56
39 -if sys.version_info[0] <= 2:  
40 - # Python 2.x  
41 - PYTHON2 = True  
42 -else:  
43 - # Python 3.x+  
44 - PYTHON2 = False 57 +def StringsASCII(data):
  58 + return re.findall(b'[^\x00-\x08\x0A-\x1F\x7F-\xFF]{4,}', data)
45 59
46 -def unicode2str(unicode_string):  
47 - """  
48 - convert a unicode string to a native str:  
49 - - on Python 3, it returns the same string  
50 - - on Python 2, the string is encoded with UTF-8 to a bytes str  
51 - :param unicode_string: unicode string to be converted  
52 - :return: the string converted to str  
53 - :rtype: str  
54 - """  
55 - if PYTHON2:  
56 - return unicode_string.encode('utf8', errors='replace')  
57 - else:  
58 - return unicode_string 60 +def StringsUNICODE(data):
  61 + return [foundunicodestring.replace('\x00', '') for foundunicodestring, dummy in re.findall(b'(([^\x00-\x08\x0A-\x1F\x7F-\xFF]\x00){4,})', data)]
59 62
  63 +def Strings(data, encodings='sL'):
  64 + dStrings = {}
  65 + for encoding in encodings:
  66 + if encoding == 's':
  67 + dStrings[encoding] = StringsASCII(data)
  68 + elif encoding == 'L':
  69 + dStrings[encoding] = StringsUNICODE(data)
  70 + return dStrings
60 71
61 -def bytes2str(bytes_string, encoding='utf8'):  
62 - """  
63 - convert a bytes string to a native str:  
64 - - on Python 2, it returns the same string (bytes=str)  
65 - - on Python 3, the string is decoded using the provided encoding  
66 - (UTF-8 by default) to a unicode str  
67 - :param bytes_string: bytes string to be converted  
68 - :param encoding: codec to be used for decoding  
69 - :return: the string converted to str  
70 - :rtype: str  
71 - """  
72 - if PYTHON2:  
73 - return bytes_string  
74 - else:  
75 - return bytes_string.decode(encoding, errors='replace') 72 +def ContainsWP23Ord(word, expression):
  73 + return struct.pack('<H', word) in expression
76 74
  75 +#https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/6e5eed10-5b77-43d6-8dd0-37345f8654ad
  76 +def ParseLoc(expression):
  77 + formatcodes = 'HH'
  78 + formatsize = struct.calcsize(formatcodes)
  79 + row, column = struct.unpack(formatcodes, expression[0:formatsize])
  80 + rowRelative = column & 0x8000
  81 + colRelative = column & 0x4000
  82 + column = column & 0x3FFF
  83 + if rowRelative:
  84 + rowindicator = '~'
  85 + else:
  86 + rowindicator = ''
  87 + row += 1
  88 + if colRelative:
  89 + colindicator = '~'
  90 + else:
  91 + colindicator = ''
  92 + column += 1
  93 + return 'R%s%dC%s%d' % (rowindicator, row, colindicator, column)
77 94
78 -dTokens = { 95 +def ParseExpression(expression):
  96 + dTokens = {
79 0x01: 'ptgExp', 97 0x01: 'ptgExp',
80 0x02: 'ptgTbl', 98 0x02: 'ptgTbl',
81 0x03: 'ptgAdd', 99 0x03: 'ptgAdd',
@@ -174,7 +192,7 @@ dTokens = { @@ -174,7 +192,7 @@ dTokens = {
174 } 192 }
175 193
176 #https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/00b5dd7d-51ca-4938-b7b7-483fe0e5933b 194 #https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/00b5dd7d-51ca-4938-b7b7-483fe0e5933b
177 -dFunctions = { 195 + dFunctions = {
178 0x0000: 'COUNT', 196 0x0000: 'COUNT',
179 0x0001: 'IF', 197 0x0001: 'IF',
180 0x0002: 'ISNA', 198 0x0002: 'ISNA',
@@ -550,436 +568,62 @@ dFunctions = { @@ -550,436 +568,62 @@ dFunctions = {
550 0x017B: 'RTD', 568 0x017B: 'RTD',
551 569
552 0x8076: 'ALERT', 570 0x8076: 'ALERT',
553 -}  
554 -  
555 -dOpcodes = {  
556 - 0x06: 'FORMULA : Cell Formula',  
557 - 0x0A: 'EOF : End of File',  
558 - 0x0C: 'CALCCOUNT : Iteration Count',  
559 - 0x0D: 'CALCMODE : Calculation Mode',  
560 - 0x0E: 'PRECISION : Precision',  
561 - 0x0F: 'REFMODE : Reference Mode',  
562 - 0x10: 'DELTA : Iteration Increment',  
563 - 0x11: 'ITERATION : Iteration Mode',  
564 - 0x12: 'PROTECT : Protection Flag',  
565 - 0x13: 'PASSWORD : Protection Password',  
566 - 0x14: 'HEADER : Print Header on Each Page',  
567 - 0x15: 'FOOTER : Print Footer on Each Page',  
568 - 0x16: 'EXTERNCOUNT : Number of External References',  
569 - 0x17: 'EXTERNSHEET : External Reference',  
570 - 0x18: 'LABEL : Cell Value, String Constant',  
571 - 0x19: 'WINDOWPROTECT : Windows Are Protected',  
572 - 0x1A: 'VERTICALPAGEBREAKS : Explicit Column Page Breaks',  
573 - 0x1B: 'HORIZONTALPAGEBREAKS : Explicit Row Page Breaks',  
574 - 0x1C: 'NOTE : Comment Associated with a Cell',  
575 - 0x1D: 'SELECTION : Current Selection',  
576 - 0x22: '1904 : 1904 Date System',  
577 - 0x26: 'LEFTMARGIN : Left Margin Measurement',  
578 - 0x27: 'RIGHTMARGIN : Right Margin Measurement',  
579 - 0x28: 'TOPMARGIN : Top Margin Measurement',  
580 - 0x29: 'BOTTOMMARGIN : Bottom Margin Measurement',  
581 - 0x2A: 'PRINTHEADERS : Print Row/Column Labels',  
582 - 0x2B: 'PRINTGRIDLINES : Print Gridlines Flag',  
583 - 0x2F: 'FILEPASS : File Is Password-Protected',  
584 - 0x3C: 'CONTINUE : Continues Long Records',  
585 - 0x3D: 'WINDOW1 : Window Information',  
586 - 0x40: 'BACKUP : Save Backup Version of the File',  
587 - 0x41: 'PANE : Number of Panes and Their Position',  
588 - 0x42: 'CODENAME : VBE Object Name',  
589 - 0x42: 'CODEPAGE : Default Code Page',  
590 - 0x4D: 'PLS : Environment-Specific Print Record',  
591 - 0x50: 'DCON : Data Consolidation Information',  
592 - 0x51: 'DCONREF : Data Consolidation References',  
593 - 0x52: 'DCONNAME : Data Consolidation Named References',  
594 - 0x55: 'DEFCOLWIDTH : Default Width for Columns',  
595 - 0x59: 'XCT : CRN Record Count',  
596 - 0x5A: 'CRN : Nonresident Operands',  
597 - 0x5B: 'FILESHARING : File-Sharing Information',  
598 - 0x5C: 'WRITEACCESS : Write Access User Name',  
599 - 0x5D: 'OBJ : Describes a Graphic Object',  
600 - 0x5E: 'UNCALCED : Recalculation Status',  
601 - 0x5F: 'SAVERECALC : Recalculate Before Save',  
602 - 0x60: 'TEMPLATE : Workbook Is a Template',  
603 - 0x63: 'OBJPROTECT : Objects Are Protected',  
604 - 0x7D: 'COLINFO : Column Formatting Information',  
605 - 0x7E: 'RK : Cell Value, RK Number',  
606 - 0x7F: 'IMDATA : Image Data',  
607 - 0x80: 'GUTS : Size of Row and Column Gutters',  
608 - 0x81: 'WSBOOL : Additional Workspace Information',  
609 - 0x82: 'GRIDSET : State Change of Gridlines Option',  
610 - 0x83: 'HCENTER : Center Between Horizontal Margins',  
611 - 0x84: 'VCENTER : Center Between Vertical Margins',  
612 - 0x85: 'BOUNDSHEET : Sheet Information',  
613 - 0x86: 'WRITEPROT : Workbook Is Write-Protected',  
614 - 0x87: 'ADDIN : Workbook Is an Add-in Macro',  
615 - 0x88: 'EDG : Edition Globals',  
616 - 0x89: 'PUB : Publisher',  
617 - 0x8C: 'COUNTRY : Default Country and WIN.INI Country',  
618 - 0x8D: 'HIDEOBJ : Object Display Options',  
619 - 0x90: 'SORT : Sorting Options',  
620 - 0x91: 'SUB : Subscriber',  
621 - 0x92: 'PALETTE : Color Palette Definition',  
622 - 0x94: 'LHRECORD : .WK? File Conversion Information',  
623 - 0x95: 'LHNGRAPH : Named Graph Information',  
624 - 0x96: 'SOUND : Sound Note',  
625 - 0x98: 'LPR : Sheet Was Printed Using LINE.PRINT(',  
626 - 0x99: 'STANDARDWIDTH : Standard Column Width',  
627 - 0x9A: 'FNGROUPNAME : Function Group Name',  
628 - 0x9B: 'FILTERMODE : Sheet Contains Filtered List',  
629 - 0x9C: 'FNGROUPCOUNT : Built-in Function Group Count',  
630 - 0x9D: 'AUTOFILTERINFO : Drop-Down Arrow Count',  
631 - 0x9E: 'AUTOFILTER : AutoFilter Data',  
632 - 0xA0: 'SCL : Window Zoom Magnification',  
633 - 0xA1: 'SETUP : Page Setup',  
634 - 0xA9: 'COORDLIST : Polygon Object Vertex Coordinates',  
635 - 0xAB: 'GCW : Global Column-Width Flags',  
636 - 0xAE: 'SCENMAN : Scenario Output Data',  
637 - 0xAF: 'SCENARIO : Scenario Data',  
638 - 0xB0: 'SXVIEW : View Definition',  
639 - 0xB1: 'SXVD : View Fields',  
640 - 0xB2: 'SXVI : View Item',  
641 - 0xB4: 'SXIVD : Row/Column Field IDs',  
642 - 0xB5: 'SXLI : Line Item Array',  
643 - 0xB6: 'SXPI : Page Item',  
644 - 0xB8: 'DOCROUTE : Routing Slip Information',  
645 - 0xB9: 'RECIPNAME : Recipient Name',  
646 - 0xBC: 'SHRFMLA : Shared Formula',  
647 - 0xBD: 'MULRK : Multiple RK Cells',  
648 - 0xBE: 'MULBLANK : Multiple Blank Cells',  
649 - 0xC1: 'MMS : ADDMENU / DELMENU Record Group Count',  
650 - 0xC2: 'ADDMENU : Menu Addition',  
651 - 0xC3: 'DELMENU : Menu Deletion',  
652 - 0xC5: 'SXDI : Data Item',  
653 - 0xC6: 'SXDB : PivotTable Cache Data',  
654 - 0xCD: 'SXSTRING : String',  
655 - 0xD0: 'SXTBL : Multiple Consolidation Source Info',  
656 - 0xD1: 'SXTBRGIITM : Page Item Name Count',  
657 - 0xD2: 'SXTBPG : Page Item Indexes',  
658 - 0xD3: 'OBPROJ : Visual Basic Project',  
659 - 0xD5: 'SXIDSTM : Stream ID',  
660 - 0xD6: 'RSTRING : Cell with Character Formatting',  
661 - 0xD7: 'DBCELL : Stream Offsets',  
662 - 0xDA: 'BOOKBOOL : Workbook Option Flag',  
663 - 0xDC: 'PARAMQRY : Query Parameters',  
664 - 0xDC: 'SXEXT : External Source Information',  
665 - 0xDD: 'SCENPROTECT : Scenario Protection',  
666 - 0xDE: 'OLESIZE : Size of OLE Object',  
667 - 0xDF: 'UDDESC : Description String for Chart Autoformat',  
668 - 0xE0: 'XF : Extended Format',  
669 - 0xE1: 'INTERFACEHDR : Beginning of User Interface Records',  
670 - 0xE2: 'INTERFACEEND : End of User Interface Records',  
671 - 0xE3: 'SXVS : View Source',  
672 - 0xE5: 'MERGECELLS : Merged Cells',  
673 - 0xEA: 'TABIDCONF : Sheet Tab ID of Conflict History',  
674 - 0xEB: 'MSODRAWINGGROUP : Microsoft Office Drawing Group',  
675 - 0xEC: 'MSODRAWING : Microsoft Office Drawing',  
676 - 0xED: 'MSODRAWINGSELECTION : Microsoft Office Drawing Selection',  
677 - 0xF0: 'SXRULE : PivotTable Rule Data',  
678 - 0xF1: 'SXEX : PivotTable View Extended Information',  
679 - 0xF2: 'SXFILT : PivotTable Rule Filter',  
680 - 0xF4: 'SXDXF : Pivot Table Formatting',  
681 - 0xF5: 'SXITM : Pivot Table Item Indexes',  
682 - 0xF6: 'SXNAME : PivotTable Name',  
683 - 0xF7: 'SXSELECT : PivotTable Selection Information',  
684 - 0xF8: 'SXPAIR : PivotTable Name Pair',  
685 - 0xF9: 'SXFMLA : Pivot Table Parsed Expression',  
686 - 0xFB: 'SXFORMAT : PivotTable Format Record',  
687 - 0xFC: 'SST : Shared String Table',  
688 - 0xFD: 'LABELSST : Cell Value, String Constant/ SST',  
689 - 0xFF: 'EXTSST : Extended Shared String Table',  
690 - 0x100: 'SXVDEX : Extended PivotTable View Fields',  
691 - 0x103: 'SXFORMULA : PivotTable Formula Record',  
692 - 0x122: 'SXDBEX : PivotTable Cache Data',  
693 - 0x13D: 'TABID : Sheet Tab Index Array',  
694 - 0x160: 'USESELFS : Natural Language Formulas Flag',  
695 - 0x161: 'DSF : Double Stream File',  
696 - 0x162: 'XL5MODIFY : Flag for DSF',  
697 - 0x1A5: 'FILESHARING2 : File-Sharing Information for Shared Lists',  
698 - 0x1A9: 'USERBVIEW : Workbook Custom View Settings',  
699 - 0x1AA: 'USERSVIEWBEGIN : Custom View Settings',  
700 - 0x1AB: 'USERSVIEWEND : End of Custom View Records',  
701 - 0x1AD: 'QSI : External Data Range',  
702 - 0x1AE: 'SUPBOOK : Supporting Workbook',  
703 - 0x1AF: 'PROT4REV : Shared Workbook Protection Flag',  
704 - 0x1B0: 'CONDFMT : Conditional Formatting Range Information',  
705 - 0x1B1: 'CF : Conditional Formatting Conditions',  
706 - 0x1B2: 'DVAL : Data Validation Information',  
707 - 0x1B5: 'DCONBIN : Data Consolidation Information',  
708 - 0x1B6: 'TXO : Text Object',  
709 - 0x1B7: 'REFRESHALL : Refresh Flag',  
710 - 0x1B8: 'HLINK : Hyperlink',  
711 - 0x1BB: 'SXFDBTYPE : SQL Datatype Identifier',  
712 - 0x1BC: 'PROT4REVPASS : Shared Workbook Protection Password',  
713 - 0x1BE: 'DV : Data Validation Criteria',  
714 - 0x1C0: 'EXCEL9FILE : Excel 9 File',  
715 - 0x1C1: 'RECALCID : Recalc Information',  
716 - 0x200: 'DIMENSIONS : Cell Table Size',  
717 - 0x201: 'BLANK : Cell Value, Blank Cell',  
718 - 0x203: 'NUMBER : Cell Value, Floating-Point Number',  
719 - 0x204: 'LABEL : Cell Value, String Constant',  
720 - 0x205: 'BOOLERR : Cell Value, Boolean or Error',  
721 - 0x207: 'STRING : String Value of a Formula',  
722 - 0x208: 'ROW : Describes a Row',  
723 - 0x20B: 'INDEX : Index Record',  
724 - 0x218: 'NAME : Defined Name',  
725 - 0x221: 'ARRAY : Array-Entered Formula',  
726 - 0x223: 'EXTERNNAME : Externally Referenced Name',  
727 - 0x225: 'DEFAULTROWHEIGHT : Default Row Height',  
728 - 0x231: 'FONT : Font Description',  
729 - 0x236: 'TABLE : Data Table',  
730 - 0x23E: 'WINDOW2 : Sheet Window Information',  
731 - 0x293: 'STYLE : Style Information',  
732 - 0x406: 'FORMULA : Cell Formula',  
733 - 0x41E: 'FORMAT : Number Format',  
734 - 0x800: 'HLINKTOOLTIP : Hyperlink Tooltip',  
735 - 0x801: 'WEBPUB : Web Publish Item',  
736 - 0x802: 'QSISXTAG : PivotTable and Query Table Extensions',  
737 - 0x803: 'DBQUERYEXT : Database Query Extensions',  
738 - 0x804: 'EXTSTRING : FRT String',  
739 - 0x805: 'TXTQUERY : Text Query Information',  
740 - 0x806: 'QSIR : Query Table Formatting',  
741 - 0x807: 'QSIF : Query Table Field Formatting',  
742 - 0x809: 'BOF : Beginning of File',  
743 - 0x80A: 'OLEDBCONN : OLE Database Connection',  
744 - 0x80B: 'WOPT : Web Options',  
745 - 0x80C: 'SXVIEWEX : Pivot Table OLAP Extensions',  
746 - 0x80D: 'SXTH : PivotTable OLAP Hierarchy',  
747 - 0x80E: 'SXPIEX : OLAP Page Item Extensions',  
748 - 0x80F: 'SXVDTEX : View Dimension OLAP Extensions',  
749 - 0x810: 'SXVIEWEX9 : Pivot Table Extensions',  
750 - 0x812: 'CONTINUEFRT : Continued FRT',  
751 - 0x813: 'REALTIMEDATA : Real-Time Data (RTD)',  
752 - 0x862: 'SHEETEXT : Extra Sheet Info',  
753 - 0x863: 'BOOKEXT : Extra Book Info',  
754 - 0x864: 'SXADDL : Pivot Table Additional Info',  
755 - 0x865: 'CRASHRECERR : Crash Recovery Error',  
756 - 0x866: 'HFPicture : Header / Footer Picture',  
757 - 0x867: 'FEATHEADR : Shared Feature Header',  
758 - 0x868: 'FEAT : Shared Feature Record',  
759 - 0x86A: 'DATALABEXT : Chart Data Label Extension',  
760 - 0x86B: 'DATALABEXTCONTENTS : Chart Data Label Extension Contents',  
761 - 0x86C: 'CELLWATCH : Cell Watch',  
762 - 0x86d: 'FEATINFO : Shared Feature Info Record',  
763 - 0x871: 'FEATHEADR11 : Shared Feature Header 11',  
764 - 0x872: 'FEAT11 : Shared Feature 11 Record',  
765 - 0x873: 'FEATINFO11 : Shared Feature Info 11 Record',  
766 - 0x874: 'DROPDOWNOBJIDS : Drop Down Object',  
767 - 0x875: 'CONTINUEFRT11 : Continue FRT 11',  
768 - 0x876: 'DCONN : Data Connection',  
769 - 0x877: 'LIST12 : Extra Table Data Introduced in Excel 2007',  
770 - 0x878: 'FEAT12 : Shared Feature 12 Record',  
771 - 0x879: 'CONDFMT12 : Conditional Formatting Range Information 12',  
772 - 0x87A: 'CF12 : Conditional Formatting Condition 12',  
773 - 0x87B: 'CFEX : Conditional Formatting Extension',  
774 - 0x87C: 'XFCRC : XF Extensions Checksum',  
775 - 0x87D: 'XFEXT : XF Extension',  
776 - 0x87E: 'EZFILTER12 : AutoFilter Data Introduced in Excel 2007',  
777 - 0x87F: 'CONTINUEFRT12 : Continue FRT 12',  
778 - 0x881: 'SXADDL12 : Additional Workbook Connections Information',  
779 - 0x884: 'MDTINFO : Information about a Metadata Type',  
780 - 0x885: 'MDXSTR : MDX Metadata String',  
781 - 0x886: 'MDXTUPLE : Tuple MDX Metadata',  
782 - 0x887: 'MDXSET : Set MDX Metadata',  
783 - 0x888: 'MDXPROP : Member Property MDX Metadata',  
784 - 0x889: 'MDXKPI : Key Performance Indicator MDX Metadata',  
785 - 0x88A: 'MDTB : Block of Metadata Records',  
786 - 0x88B: 'PLV : Page Layout View Settings in Excel 2007',  
787 - 0x88C: 'COMPAT12 : Compatibility Checker 12',  
788 - 0x88D: 'DXF : Differential XF',  
789 - 0x88E: 'TABLESTYLES : Table Styles',  
790 - 0x88F: 'TABLESTYLE : Table Style',  
791 - 0x890: 'TABLESTYLEELEMENT : Table Style Element',  
792 - 0x892: 'STYLEEXT : Named Cell Style Extension',  
793 - 0x893: 'NAMEPUBLISH : Publish To Excel Server Data for Name',  
794 - 0x894: 'NAMECMT : Name Comment',  
795 - 0x895: 'SORTDATA12 : Sort Data 12',  
796 - 0x896: 'THEME : Theme',  
797 - 0x897: 'GUIDTYPELIB : VB Project Typelib GUID',  
798 - 0x898: 'FNGRP12 : Function Group',  
799 - 0x899: 'NAMEFNGRP12 : Extra Function Group',  
800 - 0x89A: 'MTRSETTINGS : Multi-Threaded Calculation Settings',  
801 - 0x89B: 'COMPRESSPICTURES : Automatic Picture Compression Mode',  
802 - 0x89C: 'HEADERFOOTER : Header Footer',  
803 - 0x8A3: 'FORCEFULLCALCULATION : Force Full Calculation Settings',  
804 - 0x8c1: 'LISTOBJ : List Object',  
805 - 0x8c2: 'LISTFIELD : List Field',  
806 - 0x8c3: 'LISTDV : List Data Validation',  
807 - 0x8c4: 'LISTCONDFMT : List Conditional Formatting',  
808 - 0x8c5: 'LISTCF : List Cell Formatting',  
809 - 0x8c6: 'FMQRY : Filemaker queries',  
810 - 0x8c7: 'FMSQRY : File maker queries',  
811 - 0x8c8: 'PLV : Page Layout View in Mac Excel 11',  
812 - 0x8c9: 'LNEXT : Extension information for borders in Mac Office 11',  
813 - 0x8ca: 'MKREXT : Extension information for markers in Mac Office 11'  
814 -}  
815 -  
816 -  
817 -# CIC: Call If Callable  
818 -def CIC(expression):  
819 - if callable(expression):  
820 - return expression()  
821 - else:  
822 - return expression  
823 -  
824 -  
825 -# IFF: IF Function  
826 -def IFF(expression, valueTrue, valueFalse):  
827 - if expression:  
828 - return CIC(valueTrue)  
829 - else:  
830 - return CIC(valueFalse)  
831 - 571 + }
832 572
833 -def CombineHexASCII(hexDump, asciiDump, length):  
834 - if hexDump == '':  
835 - return ''  
836 - return hexDump + ' ' + (' ' * (3 * (length - len(asciiDump)))) + asciiDump  
837 -  
838 -def HexASCII(data, length=16):  
839 - result = []  
840 - if len(data) > 0:  
841 - hexDump = ''  
842 - asciiDump = ''  
843 - for i, b in enumerate(data):  
844 - if i % length == 0:  
845 - if hexDump != '':  
846 - result.append(CombineHexASCII(hexDump, asciiDump, length))  
847 - hexDump = '%08X:' % i  
848 - asciiDump = ''  
849 - hexDump += ' %02X' % ord(b)  
850 - asciiDump += IFF(ord(b) >= 32, b, '.')  
851 - result.append(CombineHexASCII(hexDump, asciiDump, length))  
852 - return result  
853 -  
854 -def StringsASCII(data):  
855 - """  
856 - Extract a list of plain ASCII strings of 4+ chars found in data.  
857 - :param data: bytearray or bytes  
858 - :return: list of str (converted to unicode on Python 3)  
859 - """  
860 - # list of bytes strings:  
861 - bytes_strings = re.findall(b'[^\x00-\x08\x0A-\x1F\x7F-\xFF]{4,}', bytes(data))  
862 - return [bytes2str(bs) for bs in bytes_strings]  
863 -  
864 -def StringsUNICODE(data):  
865 - """  
866 - Extract a list of Unicode strings (made of 4+ plain ASCII characters only) found in data.  
867 - :param data: bytearray or bytes  
868 - :return: list of str (converted to unicode on Python 3)  
869 - """  
870 - # list of bytes strings:  
871 - # TODO: check if the null byte should be before or after the ascii byte  
872 - bytes_strings = [foundunicodestring.replace(b'\x00', b'') for foundunicodestring, dummy in re.findall(b'(([^\x00-\x08\x0A-\x1F\x7F-\xFF]\x00){4,})', bytes(data))]  
873 - return [bytes2str(bs) for bs in bytes_strings]  
874 -  
875 -def Strings(data, encodings='sL'):  
876 - """  
877 -  
878 - :param data bytearray: bytearray, data to be scanned for strings  
879 - :param encodings:  
880 - :return: dict with key = 's' or 'L', values = list of str  
881 - """  
882 - dStrings = {}  
883 - for encoding in encodings:  
884 - if encoding == 's':  
885 - dStrings[encoding] = StringsASCII(data)  
886 - elif encoding == 'L':  
887 - dStrings[encoding] = StringsUNICODE(data)  
888 - return dStrings  
889 -  
890 -def ContainsWord(word, expression):  
891 - return struct.pack('<H', word) in expression  
892 -  
893 -# https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/6e5eed10-5b77-43d6-8dd0-37345f8654ad  
894 -def ParseLoc(expression):  
895 - """  
896 -  
897 - :param expression bytearray: bytearray, data to be parsed  
898 - :return:  
899 - :rtype: str  
900 - """  
901 - formatcodes = 'HH'  
902 - formatsize = struct.calcsize(formatcodes)  
903 - row, column = struct.unpack(formatcodes, expression[0:formatsize])  
904 - rowRelative = column & 0x8000  
905 - colRelative = column & 0x4000  
906 - column = column & 0x3FFF  
907 - if rowRelative:  
908 - rowindicator = '~'  
909 - else:  
910 - rowindicator = ''  
911 - row += 1  
912 - if colRelative:  
913 - colindicator = '~'  
914 - else:  
915 - colindicator = ''  
916 - column += 1  
917 - return 'R%s%dC%s%d' % (rowindicator, row, colindicator, column)  
918 -  
919 -def ParseExpression(expression):  
920 - '''  
921 - Parse an expression into a human readable string.  
922 -  
923 - :param expression bytearray: bytearray, expression data to be parsed  
924 - :return: str, parsed expression as a string (bytes on Python 2, unicode on python 3)  
925 - :rtype: str  
926 - '''  
927 result = '' 573 result = ''
928 while len(expression) > 0: 574 while len(expression) > 0:
929 - ptgid = expression[0] # int  
930 - expression = expression[1:] # bytearray 575 + ptgid = P23Ord(expression[0])
  576 + expression = expression[1:]
931 if ptgid in dTokens: 577 if ptgid in dTokens:
932 result += dTokens[ptgid] + ' ' 578 result += dTokens[ptgid] + ' '
933 - if ptgid == 0x17: # ptgStr  
934 - length = expression[0] # int 579 + if ptgid == 0x17:
  580 + length = P23Ord(expression[0])
935 expression = expression[1:] 581 expression = expression[1:]
936 - if expression[0] == 0: # probably BIFF8 -> UNICODE (compressed) 582 + if expression[0] == '\x00': # probably BIFF8 -> UNICODE (compressed)
937 expression = expression[1:] 583 expression = expression[1:]
938 - result += '"%s" ' % bytes2str(expression[:length]) 584 + result += '"%s" ' % expression[:length]
939 expression = expression[length:] 585 expression = expression[length:]
940 - elif ptgid == 0x19: # ptgAttr  
941 - grbit = expression[0] # int 586 + elif ptgid == 0x19:
  587 + grbit = P23Ord(expression[0])
942 expression = expression[1:] 588 expression = expression[1:]
943 if grbit & 0x04: 589 if grbit & 0x04:
944 result += 'CHOOSE ' 590 result += 'CHOOSE '
945 break 591 break
946 else: 592 else:
947 expression = expression[2:] 593 expression = expression[2:]
948 - elif ptgid == 0x16 or ptgid == 0x0e: # 0x0E: 'ptgNE', 0x16: 'ptgMissArg' 594 + elif ptgid == 0x16 or ptgid == 0x0e:
949 pass 595 pass
950 - elif ptgid == 0x1e: # ptgInt  
951 - result += '%d ' % (expression[0] + expression[1] * 0x100) 596 + elif ptgid == 0x1e:
  597 + result += '%d ' % (P23Ord(expression[0]) + P23Ord(expression[1]) * 0x100)
952 expression = expression[2:] 598 expression = expression[2:]
953 - elif ptgid == 0x41: # ptgFuncV  
954 - functionid = expression[0] + expression[1] * 0x100 599 + elif ptgid == 0x41:
  600 + functionid = P23Ord(expression[0]) + P23Ord(expression[1]) * 0x100
955 result += '%s (0x%04x) ' % (dFunctions.get(functionid, '*UNKNOWN FUNCTION*'), functionid) 601 result += '%s (0x%04x) ' % (dFunctions.get(functionid, '*UNKNOWN FUNCTION*'), functionid)
956 expression = expression[2:] 602 expression = expression[2:]
957 - elif ptgid == 0x22 or ptgid == 0x42: # 0x22: 'ptgFuncVar', 0x42: 'ptgFuncVarV'  
958 - functionid = expression[1] + expression[2] * 0x100  
959 - result += 'args %d func %s (0x%04x) ' % (expression[0], dFunctions.get(functionid, '*UNKNOWN FUNCTION*'), functionid) 603 + elif ptgid == 0x22 or ptgid == 0x42:
  604 + functionid = P23Ord(expression[1]) + P23Ord(expression[2]) * 0x100
  605 + result += 'args %d func %s (0x%04x) ' % (P23Ord(expression[0]), dFunctions.get(functionid, '*UNKNOWN FUNCTION*'), functionid)
960 expression = expression[3:] 606 expression = expression[3:]
961 - elif ptgid == 0x23: # ptgName  
962 - result += '%04x ' % (expression[0] + expression[1] * 0x100)  
963 - # TODO: looks like we're skipping quite a few bytes 607 + elif ptgid == 0x23:
  608 + result += '%04x ' % (P23Ord(expression[0]) + P23Ord(expression[1]) * 0x100)
964 expression = expression[14:] 609 expression = expression[14:]
965 - elif ptgid == 0x1f: # ptgNum 610 + elif ptgid == 0x1f:
966 result += 'FLOAT ' 611 result += 'FLOAT '
967 - # TODO: looks like we're skipping quite a few bytes  
968 expression = expression[8:] 612 expression = expression[8:]
969 - elif ptgid == 0x26: # ptgMemArea  
970 - expression = expression[4:] # skipping 4 bytes  
971 - expression = expression[expression[0] + expression[1] * 0x100:] 613 + elif ptgid == 0x26:
  614 + expression = expression[4:]
  615 + expression = expression[P23Ord(expression[0]) + P23Ord(expression[1]) * 0x100:]
972 result += 'REFERENCE-EXPRESSION ' 616 result += 'REFERENCE-EXPRESSION '
973 - elif ptgid == 0x01: # ptgExp 617 + elif ptgid == 0x01:
974 formatcodes = 'HH' 618 formatcodes = 'HH'
975 formatsize = struct.calcsize(formatcodes) 619 formatsize = struct.calcsize(formatcodes)
976 row, column = struct.unpack(formatcodes, expression[0:formatsize]) 620 row, column = struct.unpack(formatcodes, expression[0:formatsize])
977 expression = expression[formatsize:] 621 expression = expression[formatsize:]
978 result += 'R%dC%d ' % (row + 1, column + 1) 622 result += 'R%dC%d ' % (row + 1, column + 1)
979 - elif ptgid == 0x24 or ptgid == 0x44: # 0x24: 'ptgRef', 0x44: 'ptgRefV' 623 + elif ptgid == 0x24 or ptgid == 0x44:
980 result += '%s ' % ParseLoc(expression) 624 result += '%s ' % ParseLoc(expression)
981 expression = expression[4:] 625 expression = expression[4:]
982 - elif ptgid == 0x3A or ptgid == 0x5A: # 0x3A: 'ptgRef3d', 0x5A: 'ptgRef3dV' 626 + elif ptgid == 0x3A or ptgid == 0x5A:
983 result += '%s ' % ParseLoc(expression[2:]) 627 result += '%s ' % ParseLoc(expression[2:])
984 expression = expression[6:] 628 expression = expression[6:]
985 else: 629 else:
@@ -987,11 +631,10 @@ def ParseExpression(expression): @@ -987,11 +631,10 @@ def ParseExpression(expression):
987 else: 631 else:
988 result += '*UNKNOWN TOKEN* ' 632 result += '*UNKNOWN TOKEN* '
989 break 633 break
990 - if len(expression) == 0: 634 + if expression == b'':
991 return result 635 return result
992 else: 636 else:
993 - # 0x006E: 'EXEC', 0x0095: 'REGISTER'  
994 - functions = [dFunctions[functionid] for functionid in [0x6E, 0x95] if ContainsWord(functionid, expression)] 637 + functions = [dFunctions[functionid] for functionid in [0x6E, 0x95] if ContainsWP23Ord(functionid, expression)]
995 if functions != []: 638 if functions != []:
996 message = ' Could contain following functions: ' + ','.join(functions) + ' -' 639 message = ' Could contain following functions: ' + ','.join(functions) + ' -'
997 else: 640 else:
@@ -999,7 +642,7 @@ def ParseExpression(expression): @@ -999,7 +642,7 @@ def ParseExpression(expression):
999 return result + ' *INCOMPLETE FORMULA PARSING*' + message + ' Remaining, unparsed expression: ' + repr(expression) 642 return result + ' *INCOMPLETE FORMULA PARSING*' + message + ' Remaining, unparsed expression: ' + repr(expression)
1000 643
1001 644
1002 -class cBIFF(object): # cPluginParent): 645 +class cBIFF(object): # cPluginParent):
1003 macroOnly = False 646 macroOnly = False
1004 name = 'BIFF plugin' 647 name = 'BIFF plugin'
1005 648
@@ -1012,10 +655,270 @@ class cBIFF(object): # cPluginParent): @@ -1012,10 +655,270 @@ class cBIFF(object): # cPluginParent):
1012 def Analyze(self): 655 def Analyze(self):
1013 result = [] 656 result = []
1014 macros4Found = False 657 macros4Found = False
  658 + dOpcodes = {
  659 + 0x06: 'FORMULA : Cell Formula',
  660 + 0x0A: 'EOF : End of File',
  661 + 0x0C: 'CALCCOUNT : Iteration Count',
  662 + 0x0D: 'CALCMODE : Calculation Mode',
  663 + 0x0E: 'PRECISION : Precision',
  664 + 0x0F: 'REFMODE : Reference Mode',
  665 + 0x10: 'DELTA : Iteration Increment',
  666 + 0x11: 'ITERATION : Iteration Mode',
  667 + 0x12: 'PROTECT : Protection Flag',
  668 + 0x13: 'PASSWORD : Protection Password',
  669 + 0x14: 'HEADER : Print Header on Each Page',
  670 + 0x15: 'FOOTER : Print Footer on Each Page',
  671 + 0x16: 'EXTERNCOUNT : Number of External References',
  672 + 0x17: 'EXTERNSHEET : External Reference',
  673 + 0x18: 'LABEL : Cell Value, String Constant',
  674 + 0x19: 'WINDOWPROTECT : Windows Are Protected',
  675 + 0x1A: 'VERTICALPAGEBREAKS : Explicit Column Page Breaks',
  676 + 0x1B: 'HORIZONTALPAGEBREAKS : Explicit Row Page Breaks',
  677 + 0x1C: 'NOTE : Comment Associated with a Cell',
  678 + 0x1D: 'SELECTION : Current Selection',
  679 + 0x22: '1904 : 1904 Date System',
  680 + 0x26: 'LEFTMARGIN : Left Margin Measurement',
  681 + 0x27: 'RIGHTMARGIN : Right Margin Measurement',
  682 + 0x28: 'TOPMARGIN : Top Margin Measurement',
  683 + 0x29: 'BOTTOMMARGIN : Bottom Margin Measurement',
  684 + 0x2A: 'PRINTHEADERS : Print Row/Column Labels',
  685 + 0x2B: 'PRINTGRIDLINES : Print Gridlines Flag',
  686 + 0x2F: 'FILEPASS : File Is Password-Protected',
  687 + 0x3C: 'CONTINUE : Continues Long Records',
  688 + 0x3D: 'WINDOW1 : Window Information',
  689 + 0x40: 'BACKUP : Save Backup Version of the File',
  690 + 0x41: 'PANE : Number of Panes and Their Position',
  691 + 0x42: 'CODENAME : VBE Object Name',
  692 + 0x42: 'CODEPAGE : Default Code Page',
  693 + 0x4D: 'PLS : Environment-Specific Print Record',
  694 + 0x50: 'DCON : Data Consolidation Information',
  695 + 0x51: 'DCONREF : Data Consolidation References',
  696 + 0x52: 'DCONNAME : Data Consolidation Named References',
  697 + 0x55: 'DEFCOLWIDTH : Default Width for Columns',
  698 + 0x59: 'XCT : CRN Record Count',
  699 + 0x5A: 'CRN : Nonresident Operands',
  700 + 0x5B: 'FILESHARING : File-Sharing Information',
  701 + 0x5C: 'WRITEACCESS : Write Access User Name',
  702 + 0x5D: 'OBJ : Describes a Graphic Object',
  703 + 0x5E: 'UNCALCED : Recalculation Status',
  704 + 0x5F: 'SAVERECALC : Recalculate Before Save',
  705 + 0x60: 'TEMPLATE : Workbook Is a Template',
  706 + 0x63: 'OBJPROTECT : Objects Are Protected',
  707 + 0x7D: 'COLINFO : Column Formatting Information',
  708 + 0x7E: 'RK : Cell Value, RK Number',
  709 + 0x7F: 'IMDATA : Image Data',
  710 + 0x80: 'GUTS : Size of Row and Column Gutters',
  711 + 0x81: 'WSBOOL : Additional Workspace Information',
  712 + 0x82: 'GRIDSET : State Change of Gridlines Option',
  713 + 0x83: 'HCENTER : Center Between Horizontal Margins',
  714 + 0x84: 'VCENTER : Center Between Vertical Margins',
  715 + 0x85: 'BOUNDSHEET : Sheet Information',
  716 + 0x86: 'WRITEPROT : Workbook Is Write-Protected',
  717 + 0x87: 'ADDIN : Workbook Is an Add-in Macro',
  718 + 0x88: 'EDG : Edition Globals',
  719 + 0x89: 'PUB : Publisher',
  720 + 0x8C: 'COUNTRY : Default Country and WIN.INI Country',
  721 + 0x8D: 'HIDEOBJ : Object Display Options',
  722 + 0x90: 'SORT : Sorting Options',
  723 + 0x91: 'SUB : Subscriber',
  724 + 0x92: 'PALETTE : Color Palette Definition',
  725 + 0x94: 'LHRECORD : .WK? File Conversion Information',
  726 + 0x95: 'LHNGRAPH : Named Graph Information',
  727 + 0x96: 'SOUND : Sound Note',
  728 + 0x98: 'LPR : Sheet Was Printed Using LINE.PRINT(',
  729 + 0x99: 'STANDARDWIDTH : Standard Column Width',
  730 + 0x9A: 'FNGROUPNAME : Function Group Name',
  731 + 0x9B: 'FILTERMODE : Sheet Contains Filtered List',
  732 + 0x9C: 'FNGROUPCOUNT : Built-in Function Group Count',
  733 + 0x9D: 'AUTOFILTERINFO : Drop-Down Arrow Count',
  734 + 0x9E: 'AUTOFILTER : AutoFilter Data',
  735 + 0xA0: 'SCL : Window Zoom Magnification',
  736 + 0xA1: 'SETUP : Page Setup',
  737 + 0xA9: 'COORDLIST : Polygon Object Vertex Coordinates',
  738 + 0xAB: 'GCW : Global Column-Width Flags',
  739 + 0xAE: 'SCENMAN : Scenario Output Data',
  740 + 0xAF: 'SCENARIO : Scenario Data',
  741 + 0xB0: 'SXVIEW : View Definition',
  742 + 0xB1: 'SXVD : View Fields',
  743 + 0xB2: 'SXVI : View Item',
  744 + 0xB4: 'SXIVD : Row/Column Field IDs',
  745 + 0xB5: 'SXLI : Line Item Array',
  746 + 0xB6: 'SXPI : Page Item',
  747 + 0xB8: 'DOCROUTE : Routing Slip Information',
  748 + 0xB9: 'RECIPNAME : Recipient Name',
  749 + 0xBC: 'SHRFMLA : Shared Formula',
  750 + 0xBD: 'MULRK : Multiple RK Cells',
  751 + 0xBE: 'MULBLANK : Multiple Blank Cells',
  752 + 0xC1: 'MMS : ADDMENU / DELMENU Record Group Count',
  753 + 0xC2: 'ADDMENU : Menu Addition',
  754 + 0xC3: 'DELMENU : Menu Deletion',
  755 + 0xC5: 'SXDI : Data Item',
  756 + 0xC6: 'SXDB : PivotTable Cache Data',
  757 + 0xCD: 'SXSTRING : String',
  758 + 0xD0: 'SXTBL : Multiple Consolidation Source Info',
  759 + 0xD1: 'SXTBRGIITM : Page Item Name Count',
  760 + 0xD2: 'SXTBPG : Page Item Indexes',
  761 + 0xD3: 'OBPROJ : Visual Basic Project',
  762 + 0xD5: 'SXIDSTM : Stream ID',
  763 + 0xD6: 'RSTRING : Cell with Character Formatting',
  764 + 0xD7: 'DBCELL : Stream Offsets',
  765 + 0xDA: 'BOOKBOOL : Workbook Option Flag',
  766 + 0xDC: 'PARAMQRY : Query Parameters',
  767 + 0xDC: 'SXEXT : External Source Information',
  768 + 0xDD: 'SCENPROTECT : Scenario Protection',
  769 + 0xDE: 'OLESIZE : Size of OLE Object',
  770 + 0xDF: 'UDDESC : Description String for Chart Autoformat',
  771 + 0xE0: 'XF : Extended Format',
  772 + 0xE1: 'INTERFACEHDR : Beginning of User Interface Records',
  773 + 0xE2: 'INTERFACEEND : End of User Interface Records',
  774 + 0xE3: 'SXVS : View Source',
  775 + 0xE5: 'MERGECELLS : Merged Cells',
  776 + 0xEA: 'TABIDCONF : Sheet Tab ID of Conflict History',
  777 + 0xEB: 'MSODRAWINGGROUP : Microsoft Office Drawing Group',
  778 + 0xEC: 'MSODRAWING : Microsoft Office Drawing',
  779 + 0xED: 'MSODRAWINGSELECTION : Microsoft Office Drawing Selection',
  780 + 0xF0: 'SXRULE : PivotTable Rule Data',
  781 + 0xF1: 'SXEX : PivotTable View Extended Information',
  782 + 0xF2: 'SXFILT : PivotTable Rule Filter',
  783 + 0xF4: 'SXDXF : Pivot Table Formatting',
  784 + 0xF5: 'SXITM : Pivot Table Item Indexes',
  785 + 0xF6: 'SXNAME : PivotTable Name',
  786 + 0xF7: 'SXSELECT : PivotTable Selection Information',
  787 + 0xF8: 'SXPAIR : PivotTable Name Pair',
  788 + 0xF9: 'SXFMLA : Pivot Table Parsed Expression',
  789 + 0xFB: 'SXFORMAT : PivotTable Format Record',
  790 + 0xFC: 'SST : Shared String Table',
  791 + 0xFD: 'LABELSST : Cell Value, String Constant/ SST',
  792 + 0xFF: 'EXTSST : Extended Shared String Table',
  793 + 0x100: 'SXVDEX : Extended PivotTable View Fields',
  794 + 0x103: 'SXFORMULA : PivotTable Formula Record',
  795 + 0x122: 'SXDBEX : PivotTable Cache Data',
  796 + 0x13D: 'TABID : Sheet Tab Index Array',
  797 + 0x160: 'USESELFS : Natural Language Formulas Flag',
  798 + 0x161: 'DSF : Double Stream File',
  799 + 0x162: 'XL5MODIFY : Flag for DSF',
  800 + 0x1A5: 'FILESHARING2 : File-Sharing Information for Shared Lists',
  801 + 0x1A9: 'USERBVIEW : Workbook Custom View Settings',
  802 + 0x1AA: 'USERSVIEWBEGIN : Custom View Settings',
  803 + 0x1AB: 'USERSVIEWEND : End of Custom View Records',
  804 + 0x1AD: 'QSI : External Data Range',
  805 + 0x1AE: 'SUPBOOK : Supporting Workbook',
  806 + 0x1AF: 'PROT4REV : Shared Workbook Protection Flag',
  807 + 0x1B0: 'CONDFMT : Conditional Formatting Range Information',
  808 + 0x1B1: 'CF : Conditional Formatting Conditions',
  809 + 0x1B2: 'DVAL : Data Validation Information',
  810 + 0x1B5: 'DCONBIN : Data Consolidation Information',
  811 + 0x1B6: 'TXO : Text Object',
  812 + 0x1B7: 'REFRESHALL : Refresh Flag',
  813 + 0x1B8: 'HLINK : Hyperlink',
  814 + 0x1BB: 'SXFDBTYPE : SQL Datatype Identifier',
  815 + 0x1BC: 'PROT4REVPASS : Shared Workbook Protection Password',
  816 + 0x1BE: 'DV : Data Validation Criteria',
  817 + 0x1C0: 'EXCEL9FILE : Excel 9 File',
  818 + 0x1C1: 'RECALCID : Recalc Information',
  819 + 0x200: 'DIMENSIONS : Cell Table Size',
  820 + 0x201: 'BLANK : Cell Value, Blank Cell',
  821 + 0x203: 'NUMBER : Cell Value, Floating-Point Number',
  822 + 0x204: 'LABEL : Cell Value, String Constant',
  823 + 0x205: 'BOOLERR : Cell Value, Boolean or Error',
  824 + 0x207: 'STRING : String Value of a Formula',
  825 + 0x208: 'ROW : Describes a Row',
  826 + 0x20B: 'INDEX : Index Record',
  827 + 0x218: 'NAME : Defined Name',
  828 + 0x221: 'ARRAY : Array-Entered Formula',
  829 + 0x223: 'EXTERNNAME : Externally Referenced Name',
  830 + 0x225: 'DEFAULTROWHEIGHT : Default Row Height',
  831 + 0x231: 'FONT : Font Description',
  832 + 0x236: 'TABLE : Data Table',
  833 + 0x23E: 'WINDOW2 : Sheet Window Information',
  834 + 0x293: 'STYLE : Style Information',
  835 + 0x406: 'FORMULA : Cell Formula',
  836 + 0x41E: 'FORMAT : Number Format',
  837 + 0x800: 'HLINKTOOLTIP : Hyperlink Tooltip',
  838 + 0x801: 'WEBPUB : Web Publish Item',
  839 + 0x802: 'QSISXTAG : PivotTable and Query Table Extensions',
  840 + 0x803: 'DBQUERYEXT : Database Query Extensions',
  841 + 0x804: 'EXTSTRING : FRT String',
  842 + 0x805: 'TXTQUERY : Text Query Information',
  843 + 0x806: 'QSIR : Query Table Formatting',
  844 + 0x807: 'QSIF : Query Table Field Formatting',
  845 + 0x809: 'BOF : Beginning of File',
  846 + 0x80A: 'OLEDBCONN : OLE Database Connection',
  847 + 0x80B: 'WOPT : Web Options',
  848 + 0x80C: 'SXVIEWEX : Pivot Table OLAP Extensions',
  849 + 0x80D: 'SXTH : PivotTable OLAP Hierarchy',
  850 + 0x80E: 'SXPIEX : OLAP Page Item Extensions',
  851 + 0x80F: 'SXVDTEX : View Dimension OLAP Extensions',
  852 + 0x810: 'SXVIEWEX9 : Pivot Table Extensions',
  853 + 0x812: 'CONTINUEFRT : Continued FRT',
  854 + 0x813: 'REALTIMEDATA : Real-Time Data (RTD)',
  855 + 0x862: 'SHEETEXT : Extra Sheet Info',
  856 + 0x863: 'BOOKEXT : Extra Book Info',
  857 + 0x864: 'SXADDL : Pivot Table Additional Info',
  858 + 0x865: 'CRASHRECERR : Crash Recovery Error',
  859 + 0x866: 'HFPicture : Header / Footer Picture',
  860 + 0x867: 'FEATHEADR : Shared Feature Header',
  861 + 0x868: 'FEAT : Shared Feature Record',
  862 + 0x86A: 'DATALABEXT : Chart Data Label Extension',
  863 + 0x86B: 'DATALABEXTCONTENTS : Chart Data Label Extension Contents',
  864 + 0x86C: 'CELLWATCH : Cell Watch',
  865 + 0x86d: 'FEATINFO : Shared Feature Info Record',
  866 + 0x871: 'FEATHEADR11 : Shared Feature Header 11',
  867 + 0x872: 'FEAT11 : Shared Feature 11 Record',
  868 + 0x873: 'FEATINFO11 : Shared Feature Info 11 Record',
  869 + 0x874: 'DROPDOWNOBJIDS : Drop Down Object',
  870 + 0x875: 'CONTINUEFRT11 : Continue FRT 11',
  871 + 0x876: 'DCONN : Data Connection',
  872 + 0x877: 'LIST12 : Extra Table Data Introduced in Excel 2007',
  873 + 0x878: 'FEAT12 : Shared Feature 12 Record',
  874 + 0x879: 'CONDFMT12 : Conditional Formatting Range Information 12',
  875 + 0x87A: 'CF12 : Conditional Formatting Condition 12',
  876 + 0x87B: 'CFEX : Conditional Formatting Extension',
  877 + 0x87C: 'XFCRC : XF Extensions Checksum',
  878 + 0x87D: 'XFEXT : XF Extension',
  879 + 0x87E: 'EZFILTER12 : AutoFilter Data Introduced in Excel 2007',
  880 + 0x87F: 'CONTINUEFRT12 : Continue FRT 12',
  881 + 0x881: 'SXADDL12 : Additional Workbook Connections Information',
  882 + 0x884: 'MDTINFO : Information about a Metadata Type',
  883 + 0x885: 'MDXSTR : MDX Metadata String',
  884 + 0x886: 'MDXTUPLE : Tuple MDX Metadata',
  885 + 0x887: 'MDXSET : Set MDX Metadata',
  886 + 0x888: 'MDXPROP : Member Property MDX Metadata',
  887 + 0x889: 'MDXKPI : Key Performance Indicator MDX Metadata',
  888 + 0x88A: 'MDTB : Block of Metadata Records',
  889 + 0x88B: 'PLV : Page Layout View Settings in Excel 2007',
  890 + 0x88C: 'COMPAT12 : Compatibility Checker 12',
  891 + 0x88D: 'DXF : Differential XF',
  892 + 0x88E: 'TABLESTYLES : Table Styles',
  893 + 0x88F: 'TABLESTYLE : Table Style',
  894 + 0x890: 'TABLESTYLEELEMENT : Table Style Element',
  895 + 0x892: 'STYLEEXT : Named Cell Style Extension',
  896 + 0x893: 'NAMEPUBLISH : Publish To Excel Server Data for Name',
  897 + 0x894: 'NAMECMT : Name Comment',
  898 + 0x895: 'SORTDATA12 : Sort Data 12',
  899 + 0x896: 'THEME : Theme',
  900 + 0x897: 'GUIDTYPELIB : VB Project Typelib GUID',
  901 + 0x898: 'FNGRP12 : Function Group',
  902 + 0x899: 'NAMEFNGRP12 : Extra Function Group',
  903 + 0x89A: 'MTRSETTINGS : Multi-Threaded Calculation Settings',
  904 + 0x89B: 'COMPRESSPICTURES : Automatic Picture Compression Mode',
  905 + 0x89C: 'HEADERFOOTER : Header Footer',
  906 + 0x8A3: 'FORCEFULLCALCULATION : Force Full Calculation Settings',
  907 + 0x8c1: 'LISTOBJ : List Object',
  908 + 0x8c2: 'LISTFIELD : List Field',
  909 + 0x8c3: 'LISTDV : List Data Validation',
  910 + 0x8c4: 'LISTCONDFMT : List Conditional Formatting',
  911 + 0x8c5: 'LISTCF : List Cell Formatting',
  912 + 0x8c6: 'FMQRY : Filemaker queries',
  913 + 0x8c7: 'FMSQRY : File maker queries',
  914 + 0x8c8: 'PLV : Page Layout View in Mac Excel 11',
  915 + 0x8c9: 'LNEXT : Extension information for borders in Mac Office 11',
  916 + 0x8ca: 'MKREXT : Extension information for markers in Mac Office 11'
  917 + }
  918 +
1015 if self.streamname in [['Workbook'], ['Book']]: 919 if self.streamname in [['Workbook'], ['Book']]:
1016 self.ran = True 920 self.ran = True
1017 - # use a bytearray to have Python 2+3 compatibility with the same code (no need for ord())  
1018 - stream = bytearray(self.stream) 921 + stream = self.stream
1019 922
1020 oParser = optparse.OptionParser() 923 oParser = optparse.OptionParser()
1021 oParser.add_option('-s', '--strings', action='store_true', default=False, help='Dump strings') 924 oParser.add_option('-s', '--strings', action='store_true', default=False, help='Dump strings')
@@ -1028,12 +931,10 @@ class cBIFF(object): # cPluginParent): @@ -1028,12 +931,10 @@ class cBIFF(object): # cPluginParent):
1028 if options.find.startswith('0x'): 931 if options.find.startswith('0x'):
1029 options.find = binascii.a2b_hex(options.find[2:]) 932 options.find = binascii.a2b_hex(options.find[2:])
1030 933
1031 - while len(stream)>0: 934 + while len(stream) > 0:
1032 formatcodes = 'HH' 935 formatcodes = 'HH'
1033 formatsize = struct.calcsize(formatcodes) 936 formatsize = struct.calcsize(formatcodes)
1034 - # print('formatsize=%d' % formatsize)  
1035 opcode, length = struct.unpack(formatcodes, stream[0:formatsize]) 937 opcode, length = struct.unpack(formatcodes, stream[0:formatsize])
1036 - # print('opcode=%d length=%d len(stream)=%d' % (opcode, length, len(stream)))  
1037 stream = stream[formatsize:] 938 stream = stream[formatsize:]
1038 data = stream[:length] 939 data = stream[:length]
1039 stream = stream[length:] 940 stream = stream[length:]
@@ -1043,7 +944,6 @@ class cBIFF(object): # cPluginParent): @@ -1043,7 +944,6 @@ class cBIFF(object): # cPluginParent):
1043 else: 944 else:
1044 opcodename = '' 945 opcodename = ''
1045 line = '%04x %6d %s' % (opcode, length, opcodename) 946 line = '%04x %6d %s' % (opcode, length, opcodename)
1046 - # print(line)  
1047 947
1048 # FORMULA record 948 # FORMULA record
1049 if opcode == 0x06 and len(data) >= 21: 949 if opcode == 0x06 and len(data) >= 21:
@@ -1055,42 +955,38 @@ class cBIFF(object): # cPluginParent): @@ -1055,42 +955,38 @@ class cBIFF(object): # cPluginParent):
1055 length = struct.unpack(formatcodes, data[20:20 + formatsize])[0] 955 length = struct.unpack(formatcodes, data[20:20 + formatsize])[0]
1056 expression = data[22:] 956 expression = data[22:]
1057 line += ' - R%dC%d len=%d %s' % (row + 1, column + 1, length, ParseExpression(expression)) 957 line += ' - R%dC%d len=%d %s' % (row + 1, column + 1, length, ParseExpression(expression))
1058 - # print(line)  
1059 958
1060 # FORMULA record #a# difference BIFF4 and BIFF5+ 959 # FORMULA record #a# difference BIFF4 and BIFF5+
1061 if opcode == 0x18 and len(data) >= 16: 960 if opcode == 0x18 and len(data) >= 16:
1062 - if data[0] & 0x20: 961 + if P23Ord(data[0]) & 0x20:
1063 dBuildInNames = {1: 'Auto_Open', 2: 'Auto_Close'} 962 dBuildInNames = {1: 'Auto_Open', 2: 'Auto_Close'}
1064 - code = data[14] 963 + code = P23Ord(data[14])
1065 if code == 0: #a# hack with BIFF8 Unicode 964 if code == 0: #a# hack with BIFF8 Unicode
1066 - code = data[15] 965 + code = P23Ord(data[15])
1067 line += ' - build-in-name %d %s' % (code, dBuildInNames.get(code, '?')) 966 line += ' - build-in-name %d %s' % (code, dBuildInNames.get(code, '?'))
1068 else: 967 else:
1069 pass 968 pass
1070 - line += ' - %s' % bytes2str(data[14:14+data[3]])  
1071 - # print(line) 969 + line += ' - %s' % (data[14:14+P23Ord(data[3])])
1072 970
1073 # BOUNDSHEET record 971 # BOUNDSHEET record
1074 if opcode == 0x85 and len(data) >= 6: 972 if opcode == 0x85 and len(data) >= 6:
1075 dSheetType = {0: 'worksheet or dialog sheet', 1: 'Excel 4.0 macro sheet', 2: 'chart', 6: 'Visual Basic module'} 973 dSheetType = {0: 'worksheet or dialog sheet', 1: 'Excel 4.0 macro sheet', 2: 'chart', 6: 'Visual Basic module'}
1076 - if data[5] == 1: 974 + if P23Ord(data[5]) == 1:
1077 macros4Found = True 975 macros4Found = True
1078 dSheetState = {0: 'visible', 1: 'hidden', 2: 'very hidden'} 976 dSheetState = {0: 'visible', 1: 'hidden', 2: 'very hidden'}
1079 - line += ' - %s, %s' % (dSheetType.get(data[5], '%02x' % data[5]), dSheetState.get(data[4], '%02x' % data[4]))  
1080 - # print(line) 977 + line += ' - %s, %s' % (dSheetType.get(P23Ord(data[5]), '%02x' % P23Ord(data[5])), dSheetState.get(P23Ord(data[4]), '%02x' % P23Ord(data[4])))
1081 978
1082 # STRING record 979 # STRING record
1083 if opcode == 0x207 and len(data) >= 4: 980 if opcode == 0x207 and len(data) >= 4:
1084 values = list(Strings(data[3:]).values()) 981 values = list(Strings(data[3:]).values())
1085 - strings = '' 982 + strings = b''
1086 if values[0] != []: 983 if values[0] != []:
1087 - strings += ' '.join(values[0]) 984 + strings += b' '.join(values[0])
1088 if values[1] != []: 985 if values[1] != []:
1089 - if strings != '':  
1090 - strings += ' '  
1091 - strings += ' '.join(values[1]) 986 + if strings != b'':
  987 + strings += b' '
  988 + strings += b' '.join(values[1])
1092 line += ' - %s' % strings 989 line += ' - %s' % strings
1093 - # print(line)  
1094 990
1095 if options.find == '' and options.opcode == '' and not options.xlm or options.opcode != '' and options.opcode.lower() in line.lower() or options.find != '' and options.find in data or options.xlm and opcode in [0x06, 0x18, 0x85, 0x207]: 991 if options.find == '' and options.opcode == '' and not options.xlm or options.opcode != '' and options.opcode.lower() in line.lower() or options.find != '' and options.find in data or options.xlm and opcode in [0x06, 0x18, 0x85, 0x207]:
1096 result.append(line) 992 result.append(line)