
    XfV                     V   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZ d d	lmZ d d
l m!Z! d dl"m#Z#  ej$        e%          Z& G d dej'        j(                  Z) G d dej*        j+                  Z,dS )    N)PureWindowsPath)AnyDict	GeneratorListOptionalTupleUnion)parserequest)symbols)	constantscontexts
exceptions
interfaces)symbol_cache)requirements)SymbolTableRequirement)intermed)pdbconvc                   d   e Zd ZdZdZdZe	 	 	 d$dej        j	        de
ded	e
d
e
dej        dee
         fd            Ze	 	 d%dej        j	        de
dede
d	e
d
e
dej        fd            Zedej        j	        de
dedeee
ee
f                  fd            Ze	 d&dej        j	        de
dede
dej        ddfd            Ze	 	 	 	 d'dej        j	        de
dedee         dej        dee         dee         dedeee
eeee
ef                  f         ddf         fd            Ze	 	 d(dej        j	        d
e
de
de
dedede
fd            Ze	 	 	 d)dej        j	        d
e
de
de
deded!edeee
         ee
         f         fd"            Ze	 	 d(dej        j	        d
e
de
de
dedede
fd#            ZdS )*
PDBUtilityzAClass to handle and manage all getting symbols based on MZ header)   r   r   )   r   r   >volatility3.framework.symbols.intermed.IntermediateSymbolTableNcontext
layer_nameoffsetsymbol_table_classconfig_pathprogress_callbackreturnc           	      :   |                      |||          }|,t                              dt          |                      dS |\  }}	}
|4t          j                            d|
                    dd                    }|                     |||	|
|||          S )a  Produces the name of a symbol table loaded from the offset for an MZ header

        Args:
            context: The context on which to operate
            layer_name: The name of the (contiguous) layer within the context that contains the MZ file
            offset: The offset in the layer at which the MZ file begins
            symbol_table_class: The class to use when constructing the SymbolTable
            config_path: New path for the produced symbol table configuration with the config tree
            progress_callback: Callable called to update ongoing progress

        Returns:
            None if no pdb information can be determined, else returned the name of the loaded symbols for the MZ
        NzCould not get GUID for 
pdbutility._)	get_guid_from_mzvollogdebughexr   configuration	path_joinreplaceload_windows_symbol_table)clsr   r   r   r   r    r!   resultguidagepdb_names              _/home/panchajanya/Development/work/volatility3/volatility3/framework/symbols/windows/pdbutil.pysymbol_table_from_offsetz#PDBUtility.symbol_table_from_offset    s    . %%gz6BB>LL@3v;;@@AAA4$c8$2<<h..sC88 K ,,
 
 	
    r$   r1   r2   r3   c           	         t           j                            |                    d          |                                dz   t          |          z             }d}	t          j                            dt          j
        j                  st                              d           dS t           j                            t          j        t          j                  }
t          j
        |
                              t          j                            |                    d          |                                |          d          }|r|}	nP|                     ||                                |||           t*          j                            d|          D ]}|}	 |	st                              d|            t                              d                    |                    d          |                                t          |          z                        dS t                              d	|            t4          j        j        }||j         ||d
          <   |	|j         ||d          <   t4          j                            |          }t4          j                            |          }tA          |d          }|!                    ||           |j        |         S )z7Loads (downloading if necessary) a windows symbol table -N)r   r   r   z)Required version of SQLiteCache not foundwindowsz(Required symbol library path not found: z@The symbols can be downloaded later using pdbconv.py -p {} -g {}zUsing symbol library: classisf_urlz!PDBUtility generated symbol table)namedescription)"ospathjoinstripupperstrr   VersionRequirementmatches_requiredr   SqliteCacheversionr(   r)   r   
CACHE_PATHIDENTIFIERS_FILENAMEfind_locationWindowsIdentifiergeneratedownload_pdb_isfr   IntermediateSymbolTablefile_symbol_urlinfoformatr   r+   r,   configparent_path	path_headr   	construct)r/   r   r1   r2   r3   r   r    r!   filter_stringisf_pathidentifiers_pathvaluerA   parent_config_pathrequirement_namerequirements                   r4   r.   z$PDBUtility.load_windows_symbol_tableK   s    NN6""DJJLL3$6S$A
 
 .??|/7
 
 	 LLEFFF47<< )"@
 
 ()9::HH*33v&&

c  	
 
  	HH   sH6G   "9II=    ! 	LLSMSSTTTKKRYYNN6**DJJLL3s88,C   
 4=m==>>> '15GttK1127?ttK334'5AA+NN%3==kJJ -!/R
 
 
 	g'9:::~k**r6   c                    	 ddl }n+# t          $ r t                              d           Y dS w xY w|j        |         }|                    |d          }|dk    rdS t          j        d|                    |dz   d                    \  }|                    ||z   d          }|d	k    rdS t          j        d
|                    ||z   dz   d                    \  }	|                    ||dz   |	z             }
|                    |
          }|j	        j
        }|                    ||d          }|                    |          }|j	        j        }|d|         }|j        D ]!}|||j        |j        |j        z            z  }"|                    |          }t          |d          rt!          |j                  sdS d}t%          t!          |j                            D ]}|j        |         j        j        dk    rk|j        |         }|                    |j                            d          |j        j                   |                                 |j        |         j        }|dS |j                            d                              d          }t9          |          j        }|j        }|j        dd         }|||fS )a  Takes the offset to an MZ header, locates any available pdb headers, and extracts the guid, age and pdb_name from them

        Args:
            context: The context on which to operate
            layer_name: The name of the (contiguous) layer within the context that contains the MZ file
            offset: The offset in the layer at which the MZ file begins

        Returns:
            A tuple of the guid, age and pdb_name, or None if no PDB record can be found
        r   Nz=Get_guid_from_mz requires the following python module: pefiler      MZz<I<      s   PEz<H      )dataT)padDIRECTORY_ENTRY_DEBUGAddressOfRawDatautf-8r8       ) pefileImportErrorr(   errorlayersreadstructunpackPEOPTIONAL_HEADERSizeOfImageSizeOfHeaderssectionsVirtualAddressSizeOfRawDatahasattrlenrf   rangeTypeset_dword_at_offsetget_field_absolute_offsetPointerToRawData	full_loadentryPdbFileNamedecoderB   r   r=   AgeSignature_String)r/   r   r   r   rj   layermz_signt_header_startpe_sigoptional_header_size	pe_headerpe_datamax_sizevirtual_data
sizeofHdrsphysical_datasectdebug_entryindex
debug_datar3   r2   r1   s                          r4   r'   zPDBUtility.get_guid_from_mz   s   	MMMM 	 	 	LLO   44		 z*FA&& U??4#]4FTM11M1MNNF_4a88 U??4"(-%**Vo5<a@@#
 #
	 JJv'=@T'TUU	)))++*6 zz&(z==))).. ,:
$[j[1$ 	 	D\#d&9D<N&NN MM )))//w 788 	)A
 A
 	 4 3w<==>> 	I 	IE,U3:?1DD$:5A
++%??@RSS%6   !!###%;EBH4*11'::@@HH #8,,1o+CRC0S(""s    $//c                    t           j                            ||dz   t          |          z             }t          j        D ]}g }t           j                            |d|dz             }	d}
	 t          j        t           j                            |	          d           t          j	        |	d          5 }t          j                                        |t          |          z   ||          }|rt          j        |d	
          }|j        d	k    st!          |j                  dk    rP|                    |           dt%          j        t           j                            |d                             z   }n|}t          j        ||||                                          }|                    t1          t3          j        |dd          d                     d}
nt6                              d           ddd           n# 1 swxY w Y   	 |
s3t           j                            |	          rt          j        |	           |D ]D}	 t          j        |           # t>          $ r  t6                              d|            Y Aw xY w dS # t>          $ r t6                              d                     |	                     Y |
s3t           j                            |	          rt          j        |	           |D ]D}	 t          j        |           # t>          $ r  t6                              d|            Y Aw xY ww xY w# |
s3t           j                            |	          rt          j        |	           |D ]D}	 t          j        |           # t>          $ r  t6                              d|            Y Aw xY ww xY wt6                              d           dS )zpAttempts to download the PDB file, convert it to an ISF file and
        save it to one of the symbol locations.r9   r:   z.json.xzFT)exist_okw)	file_namer!   file)schemer   zfile:r   )indent	sort_keysrh   zSymbol file could not be downloaded from remote server                                                                                                    Nz%Temporary file could not be removed: zBCannot write necessary symbol file, please check permissions on {}zvCannot write downloaded symbols, please add the appropriate symbols or add/modify a symbols directory that is writable)!r?   r@   rA   rD   r   __path__makedirsdirnamelzmaopenr   PdbRetreiverretreive_pdbr   urlparser   ry   appendr   pathname2urlabspath	PdbReaderget_jsonwritebytesjsondumpsr(   warningexistsremovePermissionErrorrR   )r/   r   r1   r2   r3   r!   rW   r@   	tmp_filespotential_output_filenamedata_writtenoffilenameurllocationjson_outputs                   r4   rN   zPDBUtility.download_pdb_isf   s    XtczCHH/DEE$ A	 A	DI(*i!;) )% !L5BGOO,EFFQUVVVVY8#>> "&355BBs3xx"**;  C    H
   #nXfEEE://3sz??a3G3G%,,X666'.1E "	" > >2 2 (HH (0H&-&7#Xx9J' '"(** $ ! $
;qD Q Q Q '    (,*  9              @  $ 97P(Q(Q 9I7888 )  H	(++++*   NHNN       #   X__1   
  $ 97P(Q(Q 9I7888 )  H	(++++*   NHNN     $ 97P(Q(Q 9I7888 )  H	(++++*   NHNN     NNF    s   ,AJ4EH9JH			JH		JI  'J
	J
7MM
L'M MMM

:ONO'OOOOd   ctx	page_size	pdb_namesstartendmaximum_invalid_countc	              #     K   d}	||j         |         j        }||j         |         j        }|j         |                             |t	          |          ||||z
  fg          D ]\  }
}}}d}||z  }d}t          ||	d          D ]e}||k    r n\|j         |                             ||z  d          s|dz  }4|j         |                             ||z  d          }|dk    r||z  } nf|}	|
|t          |d          ||d	V  dS )
a  Scans through `layer_name` at `ctx` looking for RSDS headers that
        indicate one of four common pdb kernel names (as listed in
        `self.pdb_names`) and returns the tuple (GUID, age, pdb_name,
        signature_offset, mz_offset)

        .. note:: This is automagical and therefore not guaranteed to provide correct results.

        The UI should always provide the user an opportunity to specify the
        appropriate types and PDB values themselves
        Args:
            layer_name: The layer name to scan
            page_size: Size of page constant
            pdb_names: List of pdb names to scan
            progress_callback: Means of providing the user with feedback during long processes
            start: Start address to start scanning from the pdb_names
            end: Minimum address to scan the pdb_names
            maximum_invalid_count: Amount of pages that can be invalid during scanning before aborting signature search
        r   N)r!   ru   r   r   r   r_   rh   )GUIDr2   r3   signature_offset	mz_offset)	rm   minimum_addressmaximum_addressscanPdbSignatureScannerrz   is_validrn   rD   )r/   r   r   r   r   r!   r   r   r   min_pfnr   r2   r3   r   r   sig_pfncurrent_invalid_counterird   s                      r4   pdbname_scanzPDBUtility.pdbname_scan=  s     < =Jz*:E;*Z(8C58Z
5K5P5P	**/cEk*+	 6Q 6
 6
 	 	1D#x!1 I&)3G&'#7GR00  *-BBBEz*-66q9}aHH +q0+z*-221y=!DD5== !IIE ! G '22$4&     1	 	r6   module_offsetmodule_sizec                 @    |                      ||||||          \  }}|S )a  Creates symbol table for a module in the specified layer_name.

        Searches the memory section of the loaded module for its PDB GUID
        and loads the associated symbol table into the symbol space.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            config_path: The config path where to find symbol files
            layer_name: The name of the layer on which to operate
            module_offset: This memory dump's module image offset
            module_size: The size of the module for this dump

        Returns:
            The name of the constructed and loaded symbol table
        _modtable_from_pdb)	r/   r   r    r   r3   r   r   r&   symbol_table_names	            r4   symbol_table_from_pdbz PDBUtility.symbol_table_from_pdb  s4    2  #55[*h{ 
  
 ! r6   Fcreate_modulec                    ||j         |         j        }||j         |         j        |z
  }t          |                     |||j         |         j        t          |d          g|||z                       }|st          j        d| d|dd          |d         }	t          
                    d|	d	          d
|	d          d|	d                     |	d	                             dd          }
|                     ||	d         |	d         |	d	         d|          }d }|r1t          j                            ||
||	d         |          }|j        }||fS )Nzlatin-1)r   r   zDid not find GUID of z in module @ 0xx!r   zFound r3   z: r   r9   r2   z.pdb r   )r    r   )r   r   )rm   r   r   listr   r   r   r   VolatilityExceptionr(   r)   r-   r.   r   Modulecreater=   )r/   r   r    r   r3   r   r   r   guidsr1   module_namer   new_module_name
new_modules                 r4   r   zPDBUtility._modtable_from_pdb  s     #N:6FM!.4D}TKz*4x++,#!K/   	
 	
  	0SSSSSSS   QxNd:.NN$v,NNeNNOOO:&..vr::99LKL# : 
 
  	.!//K("3 0  J )oO 111r6   c           	      D    |                      ||||||d          \  }}|S )a  Creates a module in the specified layer_name based on a pdb name.

        Searches the memory section of the loaded module for its PDB GUID
        and loads the associated symbol table into the symbol space.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            config_path: The config path where to find symbol files
            layer_name: The name of the layer on which to operate
            module_offset: This memory dump's module image offset
            module_size: The size of the module for this dump

        Returns:
            The name of the constructed and loaded symbol table
        T)r   r   )	r/   r   r    r   r3   r   r   r   r&   s	            r4   module_from_pdbzPDBUtility.module_from_pdb  s?    4 // 0 
 
Q r6   )r   NN)r$   NN)NNNr   )NN)NNF)__name__
__module____qualname____doc___version_required_framework_versionclassmethodr   r   ContextInterfacerD   intr   ProgressCallbackr   r5   r.   r	   r'   rN   r   r   r   r   r
   r   r   boolr   r    r6   r4   r   r      s_       KKH"+ #c8<(
 (
#4(
 (
 	(

  (
 (
 %5(
 
#(
 (
 (
 [(
T  (8<G+ G+#4G+ G+ 	G+
 G+  G+ G+ %5G+ G+ G+ [G+R U# (9U#GJU#TWU#	%S#&	'U# U# U# [U#n  9=M M#4M M 	M
 M %5M 
M M M [M^  9=#!%(B B0B B 	B
 ;B %5B }B c]B  #B 
4XeE3O&<==>dJ	KB B B [BH  "! !#4! ! 	!
 ! ! ! 
! ! ! [!:  "#92 92#492 92 	92
 92 92 92 92 
x}hsm+	,92 92 92 [92v  "# ##4# # 	#
 # # # 
# # # [# # #r6   r   c                        e Zd ZdZdZ	 dZ	  ej        d          Zde	e
         ddf fdZd	e
d
edeeeee
ef         ddf         fdZ xZS )r   an  A :class:`~volatility3.framework.interfaces.layers.ScannerInterface`
    based scanner use to identify Windows PDB records.

    Args:
        pdb_names: A list of bytestrings, used to match pdb signatures against the pdb names within the records.

    .. note:: The pdb_names must be a list of byte strings, unicode strs will not match against the data scanned
    i @  Tz<16BIr   r"   Nc                 V    t                                                       || _        d S r   )super__init__
_pdb_names)selfr   	__class__s     r4   r   zPdbSignatureScanner.__init__  s$    #r6   rd   data_offsetc              #   F  K   dd| j         j        z  z   dz   d                    d | j        D                       z   dz   }t	          j        ||t          j                  D ]>}||                    d          d	z   | j         j        z   |                    d          t          |	                                          z   d
z
           }|| j        v r| j         
                    ||                    d          d	z   |                    d          d	z   | j         j        z                      \  }}}}	}
}}}}}}}}}}}}d                    |	|||||
||||||||||          }|                    d          | j        k     r|||||                    d          z   fV  @d S )Ns   RSDS   .   (   |c                 6    g | ]}t          j        |          S r   )reescape).0r   s     r4   
<listcomp>z0PdbSignatureScanner.__call__.<locals>.<listcomp>  s     ???!1???r6   s   ) )flagsr   ra   r   z`{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X})_RSDS_formatsizerA   r   r   finditerDOTALLr   ry   grouprp   rR   
chunk_size)r   rd   r   patternmatchr3   g3g2g1g0g5g4g7g6g8g9gagbgcgdgegfar1   s                           r4   __call__zPdbSignatureScanner.__call__  s      d',,. ii??t???@@A 	 	 [$bi@@@ &	L &	LEA#()+0;;q>>ekkmm$$,%,H 4?**( %,,A*U[[^^a-?$BSBX-XX % &--BBBBBBBPR  ;;q>>DO33HkEKKNN.JKKKKM&	L &	Lr6   )r   r   r   r   overlapthread_safero   Structr  r   r   r   r   r   r	   rD   r   r  __classcell__)r   s   @r4   r   r     s          GlK A 6=))L$$u+ $$ $ $ $ $ $ $0L0L(+0L	5c5#-.d:	;0L 0L 0L 0L 0L 0L 0L 0Lr6   r   )-r   loggingr   r?   r   ro   pathlibr   typingr   r   r   r   r   r	   r
   urllibr   r   volatility3r   volatility3.frameworkr   r   r   r   volatility3.framework.automagicr   #volatility3.framework.configurationr   0volatility3.framework.configuration.requirementsr   volatility3.framework.symbolsr   %volatility3.framework.symbols.windowsr   	getLoggerr   r(   r+   VersionableInterfacer   rm   ScannerInterfacer   r   r6   r4   <module>r0     s  
    				 				  # # # # # # E E E E E E E E E E E E E E E E E E ! ! ! ! ! ! ! !       M M M M M M M M M M M M 8 8 8 8 8 8 < < < < < < S S S S S S 2 2 2 2 2 2 9 9 9 9 9 9		8	$	$f f f f f)> f f fREL EL EL EL EL*+< EL EL EL EL ELr6   