Commit 0fd8f06bfa03126fbdfa80df2f4e092e7f5918c3
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.
Showing
1 changed file
with
362 additions
and
466 deletions
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) | ... | ... |