
    Zi                        S r SSKJr  SrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  \R                  R                  \R                  R                  \R                  R!                  \5      5      5      r\R                  R                  \R                  R'                  \S5      5      r\\R                  ;  a  \R                  R+                  S\5        SSKJr  SSKJr  SS	KJrJr  SSKrSS
KJr   " S S\R@                  5      r!\RD                  S-   4S jr#\#" S5      r$Sr%Sr&S\&-   S-   r'Sr(Sr)S\(-   S-   \)-   S-   r*\RV                  " \*5      r,Sr-\RV                  " \-5      r.Sr/\RV                  " \/5      r0S\'-   S-   \--   S-   \*-   S-   r1S\%-   \1-   S-   \%-   S -   r2\RV                  " \25      r3\RV                  " \15      r4\RV                  " S!5      r5\RV                  " S"5      r6S"r7S#r8S$r9S%r:\RV                  " \8\9-   \:-   \7-   5      r;\RV                  " \7\2-   5      r<\RV                  " S&5      r=\>" S'5      r?\R                  S   S(::  a	  S)rAS*rBS+rC\DrEO\F" S)5      rA\F" S*5      rB\F" S+5      rC\GrES,rHS- rI " S. S/\J5      rK " S0 S1\J5      rL " S2 S3\J5      rM " S4 S5\L5      rNS<S6 jrOS=S7 jrPS>S8 jrQS?S9 jrRS: rS\TS;:X  a  \S" 5         gg)@aW  
rtfobj.py

rtfobj is a Python module to extract embedded objects from RTF files, such as
OLE ojects. It can be used as a Python library or a command-line tool.

Usage: rtfobj.py <file.rtf>

rtfobj project website: http://www.decalage.info/python/rtfobj

rtfobj is part of the python-oletools package:
http://www.decalage.info/python/oletools
    )print_functionz0.60.1N)time..)xglob)tablestream)oleobjftguess)clsidc                       \ rS rSrSrS rSrg)NullHandler   a  
Log Handler without output, to avoid printing messages if logging is not
configured by the main application.
Python 2.7 has logging.NullHandler, but this is necessary for 2.6:
see https://docs.python.org/2.6/library/logging.html#configuring-logging-for-a-library
c                     g N )selfrecords     i/var/www/eduai.edurigo.com/question_generate/ques_gen_env/lib/python3.13/site-packages/oletools/rtfobj.pyemitNullHandler.emit           r   N)__name__
__module____qualname____firstlineno____doc__r   __static_attributes__r   r   r   r   r      s    r   r      c                 (   U [         R                  R                  R                  ;   a)  [         R                  " U 5      nUR                  U5        U$ [         R                  " U 5      nUR                  [        5       5        UR                  U5        U$ )aR  
Create a suitable logger object for this module.
The goal is not to change settings of the root logger, to avoid getting
other modules' logs on the screen.
If a logger exists with same name, reuse it. (Else it would have duplicate
handlers and messages would be doubled.)
The level is set to CRITICAL+1 by default, to avoid any logging.
)loggingLoggermanager
loggerDict	getLoggersetLevel
addHandlerr   )namelevelloggers      r   
get_loggerr*      sr     w~~%%000 ""4(t$F km$
OOEMr   rtfobjs   [0-9A-Fa-f]s   [{](?:\\.|[^{}\\])*[}]s   [{](?:\\.|[^{}\\]|s   )*[}]s   ([a-zA-Z]{1,250})s   (-?\d+)s   (?:\\s   (?:s   (?=[^0-9])|(?=[^a-zA-Z0-9])|$))s   (?:\\[^a-zA-Z])s   [^{}\\]+s   (?:\s|   |s   )*s   \b(?:s   ){7,}s   \bs   \d+s   [ \t\r\n\f\v]s   [ \t\r\n\f\v]*s   \\bins   (\d{1,250})z(?i)\.(BAT|CLASS|CMD|CPL|DLL|EXE|COM|GADGET|HTA|INF|JAR|JS|JSE|LNK|MSC|MSI|MSP|PIF|PS1|PS1XML|PS2|PS2XML|PSC1|PSC2|REG|SCF|SCR|SCT|VB|VBE|VBS|WS|WSC|WSF|WSH)\b(  s   aftncns   aftnseps   aftnsepcs
   annotations	   atnauthors   atndates   atnids	   atnparents   atnrefs   atrfends	   atrfstarts   authors
   backgrounds   bkmkends	   bkmkstarts   blipuids   buptims   categorys   colorschememappings   colortbls   comments   companys   creatims	   datafields	   datastores   defchps   defpaps   dos   doccomms   docvars
   dptxbxtexts   ebcends   ebcstarts   factoidnames   falts   fcharss	   ffdeftexts
   ffentrymcrs	   ffexitmcrs   ffformats
   ffhelptexts   ffls   ffnames
   ffstattexts   fields   files   filetbls   fldinsts   fldrslts   fldtypes   fontembs   fonttbls   footers   footerfs   footerls   footerrs   footnotes	   formfields   ftncns   ftnseps   ftnsepc   gs	   generators   gridtbls   headers   headerfs   headerls   headerrs   hls   hlfrs	   hlinkbases   hllocs   hlsrcs   hsvs   infos   keywordss   latentstyless   lcharss   levelnumberss	   leveltexts   lfolevels   linkvals   lists	   listlevels   listnames   listoverrides   listoverridetables   listpictures   liststylenames	   listtables   listtexts   lsdlockedexcepts   maccs   maccPrs	   mailmerges   malnScrs   managers   margPrs   mbars   mbarPrs   mbaseJcs   mbegChrs
   mborderBoxs   mborderBoxPrs   mboxs   mboxPrs   mchrs   mcounts   mctrlPrs   mds   mdegs   mdegHides   mdens   mdiffs   mdPrs   mes   mendChrs   meqArrs   meqArrPrs   mfs   mfNames   mfPrs   mfuncs   mfuncPrs	   mgroupChrs   mgroupChrPrs   mgrows   mhideBots	   mhideLefts
   mhideRights   mhideTops   mlims   mlimLocs   mlimLows	   mlimLowPrs   mlimUpps	   mlimUppPrs   mms   mmaddfieldnames	   mmathPicts   mmaxDists   mmcs   mmcJcs   mmconnectstrs   mmconnectstrdatas   mmcPrs   mmcss   mmdatasources   mmheadersources   mmmailsubjects   mmodsos   mmodsofilters   mmodsofldmpdatas   mmodsomappednames
   mmodsonames   mmodsorecipdatas
   mmodsosorts	   mmodsosrcs   mmodsotables	   mmodsoudls   mmodsoudldatas   mmodsouniquetags   mmPrs   mmquerys   mmrs   mnarys   mnaryPrs   mnoBreaks   mnums   mobjDists   moMaths
   moMathParas   moMathParaPrs   mopEmus   mphants   mphantPrs   mplcHides   mposs   mrs   mrads   mradPrs   mrPrs   msepChrs   mshows   mshps   msPres   msPrePrs   msSubs   msSubPrs   msSubSups
   msSubSupPrs   msSups   msSupPrs   mstrikeBLTRs   mstrikeHs   mstrikeTLBRs   mstrikeVs   msubs   msubHides   msups   msupHides   mtransps   mtypes   mvertJcs   mvfmfs   mvfmls   mvtofs   mvtols   mzeroAscs	   mzeroDescs   mzeroWids   nesttablepropss   nonesttabless   objaliass   objclass   objdatas   objects   objnames   objsects	   oldcpropss	   oldppropss	   oldspropss	   oldtpropss   oleclsids   operators   panoses   passwords   passwordhashs   pgps   pgptbls   picprops   picts   pns   pnseclvls   pntexts   pntxtas   pntxtbs   printims   propnames   protends	   protstarts   protusertbls   results   revtbls   revtims   rxes   shps   shpgrps   shpinsts   shppicts   shprslts   shptxts   sns   sps	   staticvals
   stylesheets   subjects   svs   svbs   tcs   templates	   themedatas   titles   txes   uds   uprs	   userpropss   wgrffmtfilters   windowcaptions   writereservations   writereservhashs   xes   xforms   xmlattrnames   xmlattrvalues   xmlcloses   xmlnames   xmlnstbls   xmlopens   margSzs   pnaius   pnaiud   \{}s   {\rtc                 z    U nSnUS:  a!  US-  nSnUS:  a  US-  nSnUS:  a  US-  nSnS	R                  X5      $ )
z>create a human-readable string representation of duration [s] sZ   g      N@minhH   g      8@daysz
{0:.1f}{1})format)durationvalueunits      r   duration_strr>   _  s\    EDrz2:SLEDrzu++r   c                   "    \ rS rSrSrSS jrSrg)Destinationiq  z<
Stores the data associated with a destination control word
Nc                 H    Xl         SU l        S U l        S U l        SU l        g )Nr   r   )cworddatastartendgroup_level)r   rB   s     r   __init__Destination.__init__u  s$    
	
r   )rB   rC   rE   rF   rD   r   r   r   r   r   r   rG   r   r   r   r   r@   r@   q  s    r   r@   c                       \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rSrg)	RtfParseri  zg
Very simple but robust generic RTF parser, designed to handle
malformed malicious RTF as MS Word does
c                 |    Xl         SU l        [        U5      U l        SU l        [        5       nU/U l        X l        g)zY
RtfParser constructor.

:param data: bytes object containing the RTF data to be parsed 
r   N)rC   indexlensizerF   r@   destinationscurrent_destination)r   rC   document_destinations      r   rG   RtfParser.__init__  s<     	
I	*}12#7 r   c           
         [        [        5       5      nX!:X  d  U R                  S:X  a  gSU R                  -  U R                  -  nX!-
  [        U R                  5      -  n[        U R                  U R                  -
  5      U-  n[        R                  SR                  [        X!-
  5      UU R                  [        U5      5      5        g)z0report progress on parsing at regular intervals r   Ng      Y@zSAfter {0} finished {1:4.1f}% of current file ({2} bytes); will finish in approx {3})floatr   rO   rM   logdebugr:   r>   )r   
start_timenowpercent_donetime_per_indexfinish_estims         r   _report_progressRtfParser._report_progress  s    DFm		Qdjj(4994*eDJJ.??TYY34~E		 .6,s~6))\,%?A	Br   c                    SU l         [        5       nUnU R                   U R                  :  Ga  [        5       U-
  S:  a  U R                  U5        [        5       nU R                  U R                      [
        :X  a'  U R                  5         U =R                   S-  sl         M  U R                  U R                      [        :X  a'  U R                  5         U =R                   S-  sl         M  U R                  U R                      [        :X  GaQ  U R                  U R                   U R                   S-    nUS-  n[        R                  U5      nU(       a  UR                  S5      nSn[        UR                  5       5      S:  a  UR                  S5      nU R                  XEU5        U =R                   [        UR                  5       5      -  sl         US:X  a  U R!                  XF5        GM  ["        R                  U R                  U R                   5      nU(       a@  U R%                  U5        U =R                   [        UR                  5       5      -  sl         GMJ  [&        R                  U R                  U R                   5      nU(       a@  U R)                  U5        U =R                   [        UR                  5       5      -  sl         GM  [+        S	U R                   -  5      eU R-                  5         g)
z&
Parse the RTF data

:return: nothing
r      r          Nr/   s   binz.Should not have reached this point - index=%Xh)rM   r   rO   r]   rC   
BRACE_OPEN_open_groupBRACE_CLOSE_close_group	BACKSLASHre_control_wordmatchgrouprN   groups_control_word_binre_control_symbolcontrol_symbolre_text_textRuntimeError_end_of_file)r   rX   last_reportdata_croppedmrB   params          r   parseRtfParser.parse  s    
V
 jj499$v#b(%%j1"fyy$
2  "

a
yy$3!!#

a
yy$	1  $yyDJJsNC$#)),7GGAJE E188:* !
&&q7JJ#aggi.0J		!+%++DIItzzB''*JJ#aggi.0J dii4A

1

c!'')n,
ORVR\R\\]]r   c                 N    U =R                   S-  sl         U R                  5         g Nr   )rF   
open_groupr   s    r   rd   RtfParser._open_group  s    A 	r   c                     g r   r   r}   s    r   r|   RtfParser.open_group      r   c                     U R                  5         U R                  U R                  R                  :X  a  U R                  5         O U =R                  S-  sl        g r{   )close_grouprF   rQ   _close_destinationr}   s    r   rf   RtfParser._close_group  sN     	t77CCC ##% Ar   c                     g r   r   r}   s    r   r   RtfParser.close_group  r   r   c                 r   U R                   R                  U R                  :X  a  U R                  5         [        U5      nU R                  Ul        U R                  R                  U5        X0l         U R                  [        UR                  5       5      -   Ul	        U R                  U R                   5        g r   )rQ   rF   r   r@   rP   appendrM   rN   rj   rD   open_destination)r   matchobjectrB   new_dests       r   _open_destinationRtfParser._open_destination  s    ##//43C3CC##%u%#//  *#+ c+*;*;*=&>> 	d667r   c                     g r   r   r   destinations     r   r   RtfParser.open_destination  r   r   c                 2   U R                   U R                  l        U R                  U R                  5        [	        U R
                  5      S:  a  U R
                  R                  5         [	        U R
                  5      S:  a  U R
                  S   U l        g g )Nr   )rM   rQ   rE   close_destinationrN   rP   popr}   s    r   r   RtfParser._close_destination  sz     (,zz  $t778t  !!#!!#t  !A%'+'8'8'<D$ r   c                     g r   r   r   s     r   r   RtfParser.close_destination+  r   r   c                     U[         ;   a4  [        R                  SX R                  4-  5        U R	                  X5        U R                  XU5        g )NzI%r is a destination control word: starting a new destination at index %Xh)DESTINATION_CONTROL_WORDSrV   rW   rM   r   control_wordr   r   rB   rw   s       r   rl   RtfParser._control_word.  sG     --IIaejlvlvdwwx"";6+e4r   c                     g r   r   r   s       r   r   RtfParser.control_word8  r   r   c                     g r   r   )r   r   s     r   ro   RtfParser.control_symbol;  r   r   c                     UR                  5       nU R                  =R                  U-  sl        U R                  X5        g r   )rj   rQ   rC   textr   r   r   s      r   rq   RtfParser._text?  s3      "  %%-%		+$r   c                     g r   r   r   s      r   r   RtfParser.textD  r   r   c                 R   Uc%  [         R                  SU R                  -  5        SnO[        U5      nUS:  a$  [         R                  SU R                  -  5        Sn[	        U R
                  U R                  U R                  S-    5      [	        S5      :X  a*  [         R                  S5        U =R                  S-  sl        [         R                  SU-  5        U R
                  U R                  U R                  U-    nU =R                  U-  sl        U R                  U5        g )NzDDetected anti-analysis trick: \bin object without length at index %Xr   zJDetected anti-analysis trick: \bin object with negative length at index %Xr    z%\bin: ignoring whitespace before dataz%\bin: reading %d bytes of binary data)rV   inforM   intordrC   rW   bin)r   r   rw   binlenbindatas        r   rm   RtfParser._binH  s    =HH\_c_i_iijFZFA:HHbeieoeoop FtyyDJJN34C@II>?JJ!OJ		:VCD))DJJtzzF':;

f
r   c                     g r   r   r   r   s     r   r   RtfParser.bin_  r   r   c                     U R                   S:  aD  [        R                  SU R                   -  5        U R                  5         U R                   S:  a  MD  U R	                  5         g )Nr   zGroup Level = %d, closing group)rF   rV   rW   rf   end_of_filer}   s    r   rs   RtfParser._end_of_fileb  sT     "II7$:J:JJK " 	r   c                     g r   r   r}   s    r   r   RtfParser.end_of_filej  r   r   )rQ   rC   rP   rF   rM   rO   N)r   r   r   r   r   rG   r]   rx   rd   r|   rf   r   r   r   r   r   rl   r   ro   rq   r   rm   r   rs   r   r   r   r   r   rK   rK     sm    
8B?D 85%
.r   rK   c                       \ rS rSrSrS rSrg)	RtfObjectin  zA
An object or a file (OLE Package) embedded into an RTF document
c                     SU l         SU l        SU l        SU l        SU l        SU l        SU l        SU l        SU l        SU l	        SU l
        SU l        SU l        SU l        SU l        SU l        SU l        g)z
RtfObject constructor
NF)rD   rE   hexdatarawdatais_oleoledata	format_id
class_nameoledata_size
is_package
olepkgdatafilenamesrc_path	temp_pathftgr
   
clsid_descr}   s    r   rG   RtfObject.__init__r  s|    
 
 
r   )r   r
   r   rE   r   r   r   r   r   r   r   r   r   r   r   rD   r   NrI   r   r   r   r   r   n  s    r   r   c                   J   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	rU =r$ )
RtfObjParseri  z/
Specialized RTF parser to extract OLE objects
c                 :   > [         [        U ]  U5        / U l        g r   )superr   rG   objects)r   rC   	__class__s     r   rG   RtfObjParser.__init__  s    lD*40r   c                 j    UR                   S:X  a#  [        R                  SUR                  -  5        g g )Nr.   z"*** Start object data at index %Xh)rB   rV   rW   rD   r   s     r   r   RtfObjParser.open_destination  s-    
*II:[=N=NNO +r   c                 ~   UR                   S:X  Ga  [        R                  SU R                  -  5        [	        5       nU R
                  R                  U5        UR                  Ul        UR                  Ul        UR                  R                  S S5      n[        R                  " SSU5      n[        U5      [        U5      :  a0  [        R                  " SSU5      n[        R                  SU-  5        [        U5      S-  (       a  [        R                  S	5        US S
 nXBl        [        R                   " U5      nXbl        [$        R&                  " U5      R)                  5       Ul        [,        R.                  " 5       n UR1                  U5        UR2                  Ul        UR4                  Ul        UR6                  Ul        UR                  Ul        [$        R&                  " UR                  5      R)                  5       Ul        SUl        UR4                  RA                  5       RC                  S5      S:X  a  [,        RD                  " UR                  SS9nURF                  Ul#        URH                  Ul$        URJ                  Ul%        UR                  Ul&        [$        R&                  " UR                  5      R)                  5       Ul'        [P        RR                  " URL                  S9Ul*        SUl+        g [X        RZ                  " UR                  5      (       ay  [X        R\                  " UR                  5      n	U	R^                  R`                  Ul0        [`        Rb                  Re                  UR`                  Rg                  5       S5      Ul4        g g g !    [        R                  S5         g = f)Nr.   z"*** Close object data at index %Xhs    	
   [^a-fA-F0-9]r   s   [a-fA-F0-9]z"Found non-hex chars in hexdata: %rr   zOdd length, trimmed last byte.r   T       package)r   package)rC   zMunknown CLSID (please report at https://github.com/decalage2/oletools/issues)z*** Not an OLE 1.0 Object)5rB   rV   rW   rM   r   r   r   rD   rE   rC   	translateresubrN   r   binascii	unhexlifyr   hashlibmd5	hexdigestrawdata_md5r   	OleObjectrx   r   r   	data_sizer   r   oledata_md5r   lowerrstripOleNativeStreamr   r   r   r   olepkgdata_md5r	   FileTypeGuesserr   r   olefile	isOleFile	OleFileIOrootr
   KNOWN_CLSIDSgetupperr   )
r   r   r+   hexdata1r   nonhexobject_dataobjopkgoles
             r   r   RtfObjParser.close_destination  s   
*II:TZZGH[FLL'&,,FL$FJ"''11$GHff_c8<G7|c(m+X>		>GH7|a		:;!#2,$N",,W5K(N!([!9!C!C!EF ""$C7		+&#&== $'NN!&)mm#!$%,[[%:%D%D%F" $>>'')007:E!11#((:>@D&*mmFO&*mmFO'+~~F$(,		F%,3KK		,B,L,L,NF)!(!8!8f>O>O!PFJ(,F%((22%//9'*xx~~,1,>,>,B,B6<<CUCUCWk-m) 3[ +d7		56s   E<N" BN" "N<c                     U R                   R                  S:X  a4  U R                   =R                  [        R                  " U5      -  sl        g g )Nr.   )rQ   rB   rC   r   hexlifyr   s     r   r   RtfObjParser.bin  s?    ##))Z7 $$))X-=-=g-FF) 8r   c                     g r   r   r   s       r   r   RtfObjParser.control_word  s    
 	r   c                    UR                  5       SS nUS:X  a  U R                  U R                  S-   U R                  S-    nU =R                  S-  sl        U R                  R                  S:X  a  [
        R                  " SSU R                  R                  5      U R                  l        [        U R                  R                  5      S-  S:X  a)  U R                  R                  S S U R                  l        g g g g )	Nr   r/      '   r.   r   r   r   )rj   rC   rM   rQ   rB   r   r   rN   )r   r   symbol	hexdigitss       r   ro   RtfObjParser.control_symbol  s    ""$Qq)T> 		$**Q,tzz!|<I JJ!OJ''--; 13TMeMeMjMj0k((-t//4459Q>484L4L4Q4QRUSU4VD,,1 ? < r   )r   )r   r   r   r   r   rG   r   r   r   r   ro   r   __classcell__)r   s   @r   r   r     s0    
P
57nGW Wr   r   c              #     #    [        U S5      R                  5       n[        U5      nUR                  5         UR                   H6  nUR
                  UR                  -
  nUR                  XTR                  4v   M8     g7f)a  
[DEPRECATED] Backward-compatible API, for applications using the old rtfobj:
Open a RTF file, extract each embedded object encoded in hexadecimal of
size > min_size, yield the index of the object in the RTF file, the original
length in the RTF file, and the decoded object data in binary format.
This is an iterator.

:param filename: str, RTF file name/path to open on disk
:param min_size: ignored, kept for backward compatibility
:returns: iterator, yielding tuples (start index, original length, binary data)
rbN)openreadr   rx   r   rE   rD   r   )r   min_sizerC   rtfpr   orig_lens         r   rtf_iter_objectsr    sb      $$$&DDJJL||77SYY&ii;;.. s   A=A?c                    [        [        5      n[        U [        5      (       a;  [	        U S5       nUR                  [        [        5      5      [        :H  sSSS5        $ [        U [        5      (       a!  [        U [        5      (       d  U SU [        :H  $ [        U [        5      (       a  U SU [        :H  $ [        U [        5      (       a]  U(       a   U SU R                  SSS9[        :H  $ [	        U S5       nUR                  [        [        5      5      [        :H  sSSS5        $ [        U S5      (       a%  U R                  [        [        5      5      [        :H  $ [        U [        [        45      (       a  [        U 5      nOU n[        [        5       H  n [!        U5      U;  a    gM     g! , (       d  f       GN`= f! [         a     gf = f! , (       d  f       N= f! ["         a       gf = f)	aU  determine whether given file / stream / array represents an rtf file

arg can be either a file name, a byte stream (located at start), a
list/tuple or a an iterable that contains bytes.

For str it is not clear whether data is a file name or the data read from
it (at least for py2-str which is bytes). Argument treat_str_as_data
clarifies.
r  Nasciistrict)errorsFr  T)rN   	RTF_MAGIC
isinstanceUNICODE_TYPEr  r  bytesstr	bytearrayencodeUnicodeErrorhasattrlisttupleiterzipnextStopIteration)argtreat_str_as_data	magic_lenreaderiter_arg
magic_bytes         r   is_rtfr&    s    II#|$$#t_;;s9~.); _#ujc&:&::I)++#y!!:I)++#s:I--gh-G ! !
 c4F{{3y>2i? !sFxxI'944#e}%%9 )n
	H~Z/ 0 % ? _    !  		s;   %F1G :%GG$1
G 
GG
G!$
G21G2c                 J   [         R                  R                  U 5      R                  5       n[        R
                  " SX5      nSU;   a  UR                  SS5      nSU;   a  M  SU;   a  UR                  SS5      nSU;   a  M  [        U 5      (       d  SnU(       a  USU nU$ )z~compute basename of filename. Replaces all non-whitelisted characters.
The returned filename is always a basename of the file.z
[^\w\.\- ]r   .z  r   NONAMEN)ospathbasenamestripr   r   replacerN   )r   replacement
max_lengthbasepath
sane_fnames        r   sanitize_filenamer3  ?  s     ww)//1H{=J
*
''c2
 *
 *
''c2
 *
 x==
 ,
r   c                    U(       a|  [         R                  R                  U5      (       d.  [        R	                  SU-  5        [         R
                  " U5        [         R                  R                  U[        U5      5      nOI[         R                  R                  U5      n[        U5      n[         R                  R                  Xg5      nUc  [        US5      R                  5       n[        S5        [        SU[        U5      4-  5        [        R                  " SS[        R                  S9n[!        U5      n	U	R#                  5         U	R$                   GH  n
S nU
R&                  (       GaO  SU
R(                  -  nU
R(                  [*        R,                  R.                  :X  a  US	-  nO3U
R(                  [*        R,                  R0                  :X  a  US
-  nOUS-  nUSU
R2                  -  -  nU
R4                  c  US-  nOUSU
R4                  -  -  nU
R6                  (       GaM  US-  nUSU
R8                  -  -  nUSU
R:                  -  -  nUSU
R<                  -  -  nUSU
R>                  -  -  nSn[         R                  RA                  U
R<                  5      u  p[        RC                  SU-  5        [         R                  RA                  U
R8                  5      u  p[        RC                  SU-  5        X:w  a  US-  n[D        RG                  U5      (       d  [D        RG                  U5      (       a  SnUS-  nUSRI                  U
RJ                  RL                  RN                  5      -  nOUSU
RP                  -  -  nU
RR                  b6  USU
RR                  -  -  nUSU
RT                  -  -  nSU
RT                  ;   a  SnU
R2                  S:X  a  SnUS-  n/ n[V        RX                  " S 5      nUR[                  U
R\                  5       Vs/ s H  nUR_                  S!5      PM     nnU H  nS"U;   d  M  URa                  U5        M     [c        [e        U5      5      nU(       a  US#S$R                  U5      -   -  nO8U
R2                  Rg                  5       Ri                  S%5      (       a  SnUS&-  nOS'nURk                  U	R$                  Rm                  U
5      S(U
Rn                  -  U4S S U4S)9  URq                  5         GM     U(       Ga  US*:X  a  U	R$                  nO [s        U5      nU	R$                  U   /nU GH  n
URm                  U
5      nU
R6                  (       a  [        S,U-  5        [        S-U
R8                  -  5        [        S.U
R:                  -  5        [        S/U
R<                  -  5        U
R8                  (       a  U< S0[        U
R8                  5      < 3nOS1XZRn                  4-  n[        S2U-  5        [        S3U
R>                  -  5        [        US45      Rw                  U
Rx                  5        GM  U
R&                  (       Ga  U
R4                  Gb  [        S5U-  5        [        S6U
R(                  -  5        [        S7U
R2                  -  5        [        S8U
R4                  -  5        U
R2                  Rg                  5       nURi                  S95      (       a  S:nOURi                  S;5      (       a  S<nOS=nS>XZRn                  U4-  n[        S2U-  5        [        S3U
RP                  -  5        [        US45      Rw                  U
R\                  5        GM+  [        S?U-  5        S@XZRn                  4-  n[        SAU-  5        [        S3U
Rz                  -  5        [        US45      Rw                  U
R|                  5        GM     g g s  snf !   [        Ru                  S+5         g = f)BNzcreating output directory %sr  zO===============================================================================zFile: %r - size: %d bytes)   
   ?   )idrM   z
OLE Object)column_width
header_rowstylezformat_id: %d z(Embedded)
z	(Linked)
z
(Unknown)
zclass name: %r
zdata size: N/Azdata size: %dz
OLE Package object:z
Filename: %rz
Source path: %rz
Temp path = %rz	
MD5 = %ryellowzTemp path extension: %rzFile extension: %rz
MODIFIED FILE EXTENSIONredz
EXECUTABLE FILEz
File Type: {}z

CLSID: %sz
%sCVEs   OLE2LinkzO
Possibly an exploit for the OLE2Link vulnerability (VU#921560, CVE-2017-0199)
s   (?:[\x20-\x7E][\x00]){3,}zutf-16lehttpzURL extracted: z, s
   equation.3zV
Possibly an exploit for the Equation Editor vulnerability (VU#421280, CVE-2017-11882)zNot a well-formed OLE objectz%08Xh)colorsallzTThe -s option must be followed by an object index or all, such as "-s 2" or "-s all"z+Saving file from OLE Package in object #%d:z  Filename = %rz  Source path = %rz  Temp path = %r_z%s_object_%08X.nonamez  saving to file %sz  md5 %swbz'Saving file embedded in OLE object #%d:z  format_id  = %dz  class name = %rz  data size  = %ds   worddocr   r   r   z%s_object_%08X.%szSaving raw data in object #%d:z%s_object_%08X.rawz  saving object to file %s)?r*  r+  isdirrV   r   mkdirjoinr3  dirnamer  r  printrN   r   TableStreamTableStyleSlimr   rx   r   r   r   r   r   TYPE_EMBEDDEDTYPE_LINKEDr   r   r   r   r   r   r   splitextrW   re_executable_extensionsri   r:   r   ftyper'   r   r
   r   r   compilefindallr   decoder   sortedsetr   
startswith	write_rowrM   rD   	write_sepr   errorwriter   r   r   )	containerr   rC   
output_dirsave_objectfname_prefixbase_dirr2  tstreamr
  r+   	ole_color
ole_columnrB  temp_extfile_exturlspatwwordsr   ifnamer   exts                            r   process_filerl  U  s   ww}}Z((HH3j@AHHZ ww||J$5h$?A 77??8,&x0
ww||H9 |Hd#((*	&M	
%3t9(=
=>%% 0((G
 DJJL,,	===)F,<,<<J6#3#3#A#AAn,
!!V%5%5%A%AAl*
m+
,v/@/@@@J""*..
o0C0CCC
   55
.@@
1FOOCC
063C3CCC
lV-B-BBB
$	 !gg..v/?/?@		3h>? gg..v?		.9:'"==J+11(;;?W?]?]^f?g?g %I"55J/66vzz7G7G7L7LMM
lV-?-???
||'mfll::
fv'8'888
F--- %I   K/!	qq
 jj!@A7:{{6>>7RS7R!*-7RSA{A  c$i("3diio"EEJ ""((*55mDD!	ww
7JLLv&fll"	
 T9- 	 	
 	[ \ %llG$ LLO- Ff%A  CaGH'&//9:*V__<=(6+;+;;<??'3'8'IKE 4|\\6RRE+e34j6#8#889UD!''(9(9:6#6#6#B?!CD)F,<,<<=)F,=,==>)F,?,??@#..446
((11C**:66#CC+|\\3.OO+e34j6#5#556UD!''76:;,ll/KK2U:;j6#5#556UD!''7M  / T<		pqs   _'/_, ,`c            	         S[         R                  SS -  n [        S[        < SU < S35        [        S5        [        S5        [        S	5        S
n[        R
                  [        R                  [        R                  [        R                  [        R                  S.nSn[        R                  " US9nUR                  SSSSS9  UR                  SSSSS SS9  UR                  SSSSSSS9  UR                  SSS S!US"S#9  UR                  S$S%S&SS S'S9  UR                  S(SS)S*S S+9  UR                  5       u  pV[        U5      S:X  a4  [        [        5        UR!                  5         [         R"                  " 5         [        R$                  " X%R&                     [         R(                  S,S-9  [*        R-                  [        R.                  5        [0        R2                  " 5         [4        R6                  " XeR8                  UR:                  UR<                  S.9 HD  u  pxn	U(       a  UR?                  S/5      (       a  M%  [A        XxXRB                  URD                  S09  MF     g )1Nz%d.%d.%dr   r5  zrtfobj z on Python z' - http://decalage.info/python/oletoolsz3THIS IS WORK IN PROGRESS - Check updates regularly!zGPlease report any issue at https://github.com/decalage2/oletools/issues warning)rW   r   ro  rY  criticalz1usage: %prog [options] <filename> [filename2 ...])usagez-r
store_true	recursivez)find files recursively in subdirectories.)actiondesthelpz-zz--zipzip_passwordr  ziif the file is a zip archive, open first file from it, using the provided password (requires Python 2.6+))ru  typedefaultrv  z-fz
--zipfname	zip_fname*zoif the file is a zip archive, file(s) to be opened within the zip. Wildcards * and ? are supported. (default:*)z-lz
--loglevelloglevelstorezBlogging level debug/info/warning/error/critical (default=%default))ru  rt  ry  rv  z-sz--saver]  z}Save the object corresponding to the provided number to a file, for example "-s 2". Use "-s all" to save all objects at once.z-dr\  z-use specified directory to save output files.)rx  ru  rv  ry  z%(levelname)-8s %(message)s)r(   streamr:   )rs  rw  rz  /)r\  r]  )#sysversion_inforI  __version__r    DEBUGINFOWARNINGERRORCRITICALoptparseOptionParser
add_option
parse_argsrN   r   
print_helpexitbasicConfigr|  stdoutrV   r%   NOTSETr   enable_loggingr   
iter_filesrs  rw  rz  endswithrl  r\  r]  )
python_versionDEFAULT_LOG_LEVEL
LOG_LEVELSrq  parseroptionsargsr[  r   rC   s
             r   mainr    s;   #"2"21Q"77N	) *	@A	TU	2J!MMLLOOMM$$
J @E""/F
 d<k8  :
dG.udx  z
dL{PS~  @
dLz'Sd!e  g
dH=ud M  N d\<d  L '')OW 4yA~w

 j)9)9:3::<> LL 
%*%5%5dFWFW))W5F5F&H!	T **3//Y$;M;M!(!4!4	6&Hr   __main__)    )F)rB     )NF)Ur   
__future__r   r  r   r*  r  r   r    r  r   os.pathr   r+  normpathabspathrH  __file___thismodule_dirrG  _parent_dirinsertoletools.thirdparty.xglobr   oletools.thirdparty.tablestreamr   oletoolsr   r	   r   oletools.commonr
   Handlerr   r  r*   rV   	HEX_DIGITSINGLE_RTF_TAGNESTED_RTF_TAG
ASCII_NAMESIGNED_INTEGERCONTROL_WORDrQ  rh   CONTROL_SYMBOLrn   TEXTrp   IGNOREDPATTERNre_hexblockre_embedded_tags
re_decimalre_delimiter	DELIMITERDELIMITERS_ZeroOrMoreBACKSLASH_BINDECIMAL_GROUPre_delims_bin_decimalre_delim_hexblockrO  	frozensetr   r  rg   rc   re   unicoder  r   r  r  r>   objectr@   rK   r   r   r  r&  r3  rl  r  r   r   r   r   <module>r     s  B & 9 8 8 8   ''""277??277??83L#MNggrww||OTBCchhHHOOA{# + 7 $  !'//  #++A- 6  	 / +>9(B "
  J&/.@Cee**\* &JJ~.  
**T
 ^
#D
(
7
<\
I%
O( i
'
)H
4y
@6
I jj!::g& ZZ 
zz/0!	. 

#8=#H%2$35>$? @ JJy723  :: gh  & /' / h A!IJKL D	ISJc(KL	,$	& 	.c cL FgW9 gWX/(+\,W8xG6T zF r   