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 2  
3 3 __description__ = 'BIFF plugin for oledump.py'
4 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 8 # Slightly modified version by Philippe Lagadec to be imported into olevba
9 9  
... ... @@ -24,6 +24,7 @@ History:
24 24 2018/10/26: continue
25 25 2019/01/05: 0.0.4 added option -x
26 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 29 Todo:
29 30 """
... ... @@ -31,51 +32,68 @@ Todo:
31 32 import struct
32 33 import re
33 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 97 0x01: 'ptgExp',
80 98 0x02: 'ptgTbl',
81 99 0x03: 'ptgAdd',
... ... @@ -174,7 +192,7 @@ dTokens = {
174 192 }
175 193  
176 194 #https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/00b5dd7d-51ca-4938-b7b7-483fe0e5933b
177   -dFunctions = {
  195 + dFunctions = {
178 196 0x0000: 'COUNT',
179 197 0x0001: 'IF',
180 198 0x0002: 'ISNA',
... ... @@ -550,436 +568,62 @@ dFunctions = {
550 568 0x017B: 'RTD',
551 569  
552 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 573 result = ''
928 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 577 if ptgid in dTokens:
932 578 result += dTokens[ptgid] + ' '
933   - if ptgid == 0x17: # ptgStr
934   - length = expression[0] # int
  579 + if ptgid == 0x17:
  580 + length = P23Ord(expression[0])
935 581 expression = expression[1:]
936   - if expression[0] == 0: # probably BIFF8 -> UNICODE (compressed)
  582 + if expression[0] == '\x00': # probably BIFF8 -> UNICODE (compressed)
937 583 expression = expression[1:]
938   - result += '"%s" ' % bytes2str(expression[:length])
  584 + result += '"%s" ' % expression[:length]
939 585 expression = expression[length:]
940   - elif ptgid == 0x19: # ptgAttr
941   - grbit = expression[0] # int
  586 + elif ptgid == 0x19:
  587 + grbit = P23Ord(expression[0])
942 588 expression = expression[1:]
943 589 if grbit & 0x04:
944 590 result += 'CHOOSE '
945 591 break
946 592 else:
947 593 expression = expression[2:]
948   - elif ptgid == 0x16 or ptgid == 0x0e: # 0x0E: 'ptgNE', 0x16: 'ptgMissArg'
  594 + elif ptgid == 0x16 or ptgid == 0x0e:
949 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 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 601 result += '%s (0x%04x) ' % (dFunctions.get(functionid, '*UNKNOWN FUNCTION*'), functionid)
956 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 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 609 expression = expression[14:]
965   - elif ptgid == 0x1f: # ptgNum
  610 + elif ptgid == 0x1f:
966 611 result += 'FLOAT '
967   - # TODO: looks like we're skipping quite a few bytes
968 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 616 result += 'REFERENCE-EXPRESSION '
973   - elif ptgid == 0x01: # ptgExp
  617 + elif ptgid == 0x01:
974 618 formatcodes = 'HH'
975 619 formatsize = struct.calcsize(formatcodes)
976 620 row, column = struct.unpack(formatcodes, expression[0:formatsize])
977 621 expression = expression[formatsize:]
978 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 624 result += '%s ' % ParseLoc(expression)
981 625 expression = expression[4:]
982   - elif ptgid == 0x3A or ptgid == 0x5A: # 0x3A: 'ptgRef3d', 0x5A: 'ptgRef3dV'
  626 + elif ptgid == 0x3A or ptgid == 0x5A:
983 627 result += '%s ' % ParseLoc(expression[2:])
984 628 expression = expression[6:]
985 629 else:
... ... @@ -987,11 +631,10 @@ def ParseExpression(expression):
987 631 else:
988 632 result += '*UNKNOWN TOKEN* '
989 633 break
990   - if len(expression) == 0:
  634 + if expression == b'':
991 635 return result
992 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 638 if functions != []:
996 639 message = ' Could contain following functions: ' + ','.join(functions) + ' -'
997 640 else:
... ... @@ -999,7 +642,7 @@ def ParseExpression(expression):
999 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 646 macroOnly = False
1004 647 name = 'BIFF plugin'
1005 648  
... ... @@ -1012,10 +655,270 @@ class cBIFF(object): # cPluginParent):
1012 655 def Analyze(self):
1013 656 result = []
1014 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 919 if self.streamname in [['Workbook'], ['Book']]:
1016 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 923 oParser = optparse.OptionParser()
1021 924 oParser.add_option('-s', '--strings', action='store_true', default=False, help='Dump strings')
... ... @@ -1028,12 +931,10 @@ class cBIFF(object): # cPluginParent):
1028 931 if options.find.startswith('0x'):
1029 932 options.find = binascii.a2b_hex(options.find[2:])
1030 933  
1031   - while len(stream)>0:
  934 + while len(stream) > 0:
1032 935 formatcodes = 'HH'
1033 936 formatsize = struct.calcsize(formatcodes)
1034   - # print('formatsize=%d' % formatsize)
1035 937 opcode, length = struct.unpack(formatcodes, stream[0:formatsize])
1036   - # print('opcode=%d length=%d len(stream)=%d' % (opcode, length, len(stream)))
1037 938 stream = stream[formatsize:]
1038 939 data = stream[:length]
1039 940 stream = stream[length:]
... ... @@ -1043,7 +944,6 @@ class cBIFF(object): # cPluginParent):
1043 944 else:
1044 945 opcodename = ''
1045 946 line = '%04x %6d %s' % (opcode, length, opcodename)
1046   - # print(line)
1047 947  
1048 948 # FORMULA record
1049 949 if opcode == 0x06 and len(data) >= 21:
... ... @@ -1055,42 +955,38 @@ class cBIFF(object): # cPluginParent):
1055 955 length = struct.unpack(formatcodes, data[20:20 + formatsize])[0]
1056 956 expression = data[22:]
1057 957 line += ' - R%dC%d len=%d %s' % (row + 1, column + 1, length, ParseExpression(expression))
1058   - # print(line)
1059 958  
1060 959 # FORMULA record #a# difference BIFF4 and BIFF5+
1061 960 if opcode == 0x18 and len(data) >= 16:
1062   - if data[0] & 0x20:
  961 + if P23Ord(data[0]) & 0x20:
1063 962 dBuildInNames = {1: 'Auto_Open', 2: 'Auto_Close'}
1064   - code = data[14]
  963 + code = P23Ord(data[14])
1065 964 if code == 0: #a# hack with BIFF8 Unicode
1066   - code = data[15]
  965 + code = P23Ord(data[15])
1067 966 line += ' - build-in-name %d %s' % (code, dBuildInNames.get(code, '?'))
1068 967 else:
1069 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 971 # BOUNDSHEET record
1074 972 if opcode == 0x85 and len(data) >= 6:
1075 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 975 macros4Found = True
1078 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 979 # STRING record
1083 980 if opcode == 0x207 and len(data) >= 4:
1084 981 values = list(Strings(data[3:]).values())
1085   - strings = ''
  982 + strings = b''
1086 983 if values[0] != []:
1087   - strings += ' '.join(values[0])
  984 + strings += b' '.join(values[0])
1088 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 989 line += ' - %s' % strings
1093   - # print(line)
1094 990  
1095 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 992 result.append(line)
... ...