
    XfT                        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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 d dlmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ  ej<                  e      Z ee!ee"   f   Z# G d	 d
      Z$ G d de$      Z% G d de$      Z& G d de$      Z' G d dejP                  jR                        Z* G d de*      Z+ G d dejX                  jZ                        Z. G d d      Z/y)    N)abstractmethod)Dict	GeneratorIterableListOptionalTuple)	frameworkschemas)	constants
interfaces)requirements)	resources)intermedc                   <    e Zd ZdZd Zeedee   fd              Z	y)IdentifierProcessorNc                      y N selfs    ^/home/panchajanya/Development/work/volatility3/volatility3/framework/automagic/symbol_cache.py__init__zIdentifierProcessor.__init__!   s        returnc                     t        d      )zMethod to extract the identifier from a particular operating system's JSON

        Returns:
            identifier is valid or None if not found
        z4This base class has no get_identifier method defined)NotImplementedError)clsjsons     r   get_identifierz"IdentifierProcessor.get_identifier$   s     "B
 	
r   )
__name__
__module____qualname__operating_systemr   classmethodr   r   bytesr    r   r   r   r   r      s4     
Xe_ 
  
r   r   c            	       R    e Zd ZdZdZedee   fd       Zede	de	de
defd       Zy	)
WindowsIdentifierwindows|r   c                     |j                   di       j                  di       j                  di       }|rO|j                  dd      }|j                  dd      }|j                  dd      }|r|r|r| j                  |||      S y)z7Returns the identifier for the file if one can be foundmetadatar)   pdbGUIDNagedatabase)getgenerate)r   r   windows_metadataguidr/   r0   s         r   r    z WindowsIdentifier.get_identifier5   s     $488J377	2FJJ5RTU#''5D"&&ud3C'++J=H||HdC88r   pdb_namer4   r/   c           	          t        | j                  j                  ||j                         t	        |      g      d      S )Nzlatin-1)r&   	separatorjoinupperstr)r   r5   r4   r/   s       r   r2   zWindowsIdentifier.generateA   s/    S]]''4::<S(JKYWWr   N)r!   r"   r#   r$   r7   r%   r   r&   r    r:   intr2   r   r   r   r(   r(   1   s`     I	Xe_ 	 	 X X3 XS XU X Xr   r(   c                   ,    e Zd ZdZedee   fd       Zy)MacIdentifiermacr   c                      |j                   di       j                  di       j                  dd       }|rt        j                  |      S y )Nsymbolsversionconstant_datar1   base64	b64decode)r   r   
mac_banners      r   r    zMacIdentifier.get_identifierI   sL     DHHY#''	26::?DQ 	 ##J//r   Nr!   r"   r#   r$   r%   r   r&   r    r   r   r   r=   r=   F   s%    Xe_  r   r=   c                   ,    e Zd ZdZedee   fd       Zy)LinuxIdentifierlinuxr   c                      |j                   di       j                  di       j                  dd       }|rt        j                  |      S y )Nr@   linux_bannerrB   rC   )r   r   rL   s      r   r    zLinuxIdentifier.get_identifierV   sM     DHHY#'';??QUV 	 ##L11r   NrG   r   r   r   rI   rI   S   s%    Xe_  r   rI   c            	           e Zd Zdef fdZdededefdZdedee   dee   fdZde	e   fd	Z
d
 Z	 ddee   dedeeef   fdZdedee   fdZdee   dee   fdZdedeeeeeef      fdZdedee   fdZ xZS )CacheManagerInterfacefilenamec                     t         |           || _        i | _        t	        j
                  t              D ]  }|| j                  |j                  <    y r   )superr   	_filename_classifiersr
   class_subclassesr   r$   )r   rO   subclazz	__class__s      r   r   zCacheManagerInterface.__init__d   sP    !!223FG 	DH;CDh778	Dr   locationr$   
identifierc                      y)zAdds an identifier to the storeNr   )r   rW   r$   rX   s       r   add_identifierz$CacheManagerInterface.add_identifierk       r   r   c                      y)aw  Returns the location of the symbol file given the identifier

        Args:
            identifier: string that uniquely identifies a particular symbol table
            operating_system: optional string to restrict identifiers to just those for a particular operating system

        Returns:
            The location of the symbols file that matches the identifier
        Nr   )r   rX   r$   s      r   find_locationz#CacheManagerInterface.find_locationo        	r   c                      y)z)Returns a list of all the local locationsNr   r   s    r   get_local_locationsz)CacheManagerInterface.get_local_locations}   r[   r   c                      y)Locates all files under the symbol directories.  Updates the cache with additions, modifications and removals.
        This also updates remote locations based on a cache timeout.

        Nr   r   s    r   updatezCacheManagerInterface.update   s    
 	r   
local_onlyc                      y)a#  Returns a dictionary of identifiers and locations

        Args:
            operating_system: If set, limits responses to a specific operating system
            local_only: Returns only local locations

        Returns:
            A dictionary of identifiers mapped to a location
        Nr   )r   r$   rd   s      r   get_identifier_dictionaryz/CacheManagerInterface.get_identifier_dictionary   r^   r   c                      y)z:Returns an identifier based on a specific location or NoneNr   r   rW   s     r   r    z$CacheManagerInterface.get_identifier   r[   r   c                      y)z9Returns all identifiers for a particular operating systemNr   )r   r$   s     r   get_identifiersz%CacheManagerInterface.get_identifiers   r[   r   c                      y)zReturns ISF statistics based on the location

        Returns:
            A tuple of base_types, types, enums, symbols, or None is location not found
        Nr   rh   s     r   get_location_statisticsz-CacheManagerInterface.get_location_statistics       r   c                      y)z7Returns the hash of the JSON from within a location ISFNr   rh   s     r   get_hashzCacheManagerInterface.get_hash   rm   r   NF)r!   r"   r#   r:   r   rZ   r&   r   r]   r   r`   rc   boolr   rf   r    r   rj   r	   r;   rl   ro   __classcell__rV   s   @r   rN   rN   c   s
   D Ds c s 3;C=	#Xc]  JO (BF	eSj	s x  $u+ 	%S#s*+	,F F# Fr   rN   c            	       4    e Zd ZdZdZdef fdZdedej                  fdZ	de
d	ee   dee   fd
Zdeeddf   fdZdedefdZdedee
   fdZdedeeeeeef      fdZdedee   fdZddZ	 dd	ee   dedee
ef   fdZd	ee   dee
   fdZ xZS )SqliteCache)   r   r      r   r   rO   c                    t         |   |       t        j                  | _        	 | j                  |      | _        y # t        j                  $ r. t        j                  |       | j                  |      | _        Y y w xY wr   )rQ   r   r   SQLITE_CACHE_PERIODcache_period_connect_storage	_databasesqlite3DatabaseErrorosunlink)r   rO   rV   s     r   r   zSqliteCache.__init__   sh    "%99	=!228<DN$$ 	=IIh!228<DN	=s   > >A?>A?pathr   c                    t        j                  |      }t         j                  |_        |j	                         j                  dt        j                   d       |j	                         j                  d      j                         }|s2|j	                         j                  dt        j                   d       nh|d   t        j                  k(  rnQt        j                  d|d           |j                          t        j                  |       | j                  |      S |j	                         j                  d       |j                          |S )NzECREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT )z(SELECT schema_version FROM database_infoz"INSERT INTO database_info VALUES (schema_versionz%Previous cache schema version found: a  CREATE TABLE IF NOT EXISTS cache (location TEXT UNIQUE NOT NULL, identifier TEXT, operating_system TEXT, hash TEXT,stats_base_types INT DEFAULT 0, stats_types INT DEFAULT 0, stats_enums INT DEFAULT 0, stats_symbols INT DEFAULT 0, local BOOL, cached DATETIME))r~   connectRowrow_factorycursorexecuter   CACHE_SQLITE_SCHEMA_VERSIONfetchonevolloginfocloser   r   r|   commit)r   r   r0   r   s       r   r|   zSqliteCache._connect_storage   s!   ??4(&{{!!ST]TyTySzz{|	
 OOW?@XZ 	
 OO%%4Y5Z5Z4[[\] ,-1V1VVKK7GW8X7YZ
 NNIIdO((..!!^	
 	r   rX   r$   c                     d}|f}|d}||f}| j                   j                         j                  ||      j                         }d}|D ]  }|d   }	 |S )a  Returns the location of the symbol file given the identifier.
        If multiple locations exist for an identifier, the last found is returned

        Args:
            identifier: string that uniquely identifies a particular symbol table
            operating_system: optional string to restrict identifiers to just those for a particular operating system

        Returns:
            The location of the symbols file that matches the identifier or None
        z/SELECT location FROM cache WHERE identifier = ?NzHSELECT location FROM cache WHERE identifier = ? AND operating_system = ?rW   r}   r   r   fetchall)r   rX   r$   	statement
parametersresultsresultrows           r   r]   zSqliteCache.find_location   sq     F	 ]
'bI$&67J..'')11)ZHQQS 	%C_F	%r   Nc              #      K   | j                   j                         j                  d      j                         }|D ]	  }|d     y w)Nz3SELECT DISTINCT location FROM cache WHERE local = 1rW   r   )r   r   r   s      r   r`   zSqliteCache.get_local_locations   sH     NN!!#WJKXZ 	
  	"Cj/!	"s   AA	urlc                 \    t         j                  j                  |      }|j                  dv S )z)Determines whether an url is local or not)filejar)urllibparseurlparsescheme)r   r   parseds      r   is_url_localzSqliteCache.is_url_local   s%    &&s+}}//r   rW   c                     | j                   j                         j                  d|f      j                         }|D ]  }|d   c S  y )Nz/SELECT identifier FROM cache WHERE location = ?rX   r   r   rW   r   r   s       r   r    zSqliteCache.get_identifier  sL    NN!!#WFTXZ 	
  	%C|$$	%r   c                     | j                   j                         j                  d|f      j                         }|D ]  }|d   |d   |d   |d   fc S  y )Nz^SELECT stats_base_types, stats_types, stats_enums, stats_symbols FROM cache WHERE location = ?stats_base_typesstats_typesstats_enumsstats_symbolsr   r   s       r   rl   z#SqliteCache.get_location_statistics  su     NN!!#Wp XZ 	  	C&'M"M"O$	 	 r   c                     | j                   j                         j                  d|f      j                         }|D ]  }|d   c S  y )Nz)SELECT hash FROM cache WHERE location = ?hashr   r   s       r   ro   zSqliteCache.get_hash  sK    NN!!#W@8+NXZ 	
  	Cv;	r   c                    t        t        j                  j                  d      D cg c]  }| c}      }t        | j	                               }|j                  |      }|j                  |      }|rr| j                  j                         j                  ddj                  dgt        |      z         d|D cg c]  }| c}       | j                  j                          t               }|j                  |      }	|	r| j                  j                         j                  d| j                   d      }
|
D ]  }|d   }t        j                  j                  |d	         }|}t         j"                  j%                  |      }d
}|j&                  dk(  r)t         j(                  j+                  |j,                        }|j&                  dk(  rVt         j"                  j%                  |j,                        }|j&                  dk(  r|j,                  j/                  d      d   }|r\t0        j,                  j3                  |      r=t        j                  j5                  t1        j6                  |      j8                        }n$t:        j=                  t>        j@                  d       |d   |	v sv||k  s}|jC                  |d           tE        tG        jH                  tJ                    }|jM                  |      }t        |      }| j                  j                         }	 tO        |      D ]  \  }} ||dz  |z  d| d       	 tQ        jR                         jU                  |      5 }tW        jX                  |      }t[        j\                  |      }d
}t        |j_                  di             }t        |j_                  di             }t        |j_                  di             }t        |j_                  di             }d
}|D ]#  } | ja                  |      }|| jb                  } n |j                  d||||||||| je                  |      f	       |+t:        j=                  t>        jf                  d| d|        n't:        j=                  t>        j@                  d|        d
d
d
        	 | j                  j                          t>        jj                  s	t>        jl                  r |dd       | j                  j                         }|j                  d| j                   d       to        t>        jl                        }" |dd       t>        jp                  D ]]  }|"js                  i |      }#|#D ]C  \  }}|ju                         }|jw                  d       r|d
d! n|}|j                  d"|||d#f       E _  |dd       | j                  j                          y
y
y
c c}w c c}w # 1 sw Y   MxY w# th        $ r/}!t:        j=                  t>        j@                  |!       Y d
}!~!
d
}!~!ww xY w# | j                  j                          w xY w)$rb    z%DELETE FROM cache WHERE location IN (,?r   zMSELECT location, cached FROM cache WHERE local = 1 AND cached < date('now', 'z');rW   cachedNr   r   !r   z?File location in database classed as local but not file/jar URLd   zUpdating caches for z	 files...
base_types
user_typesenumsr@   zINSERT OR REPLACE INTO cache (location, identifier, operating_system, hash,stats_base_types, stats_types, stats_enums, stats_symbols, local, cached) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))zIdentified z as zNo identifier found for zReading remote ISF listzGSELECT cached FROM cache WHERE local = 0 and cached < datetime('now', 'z')2   )r$       zxINSERT OR REPLACE INTO cache(identifier, location, operating_system, local, cached) VALUES (?, ?, ?, ?, datetime('now'))F)<setr   IntermediateSymbolTablefile_symbol_urlr`   
differencer}   r   r   r8   lenr   intersectionr{   datetimefromisoformatr   r   r   r   requesturl2pathnamer   splitr   existsfromtimestampstatst_mtimer   logr   LOGLEVEL_VVVVaddlistr
   rT   r   union	enumerater   ResourceAccessoropenr   loadr   create_json_hashr1   r    r$   r   LOGLEVEL_VV	ExceptionOFFLINEREMOTE_ISF_URLRemoteIdentifierFormatOS_CATEGORIESprocessrstripendswith)$r   progress_callbackrO   on_disk_locationscached_locationsnew_locationsmissing_locationsxcache_updatefiles_to_timestampr   r   rW   stored_timestamp	timestampr   pathname	inner_urlidextractorsfiles_to_processnumber_files_to_processr   counterfpjson_objr   rX   r   r   r   r   r$   idextractorexcpremote_identifiersidentifierss$                                       r   rc   zSqliteCache.update)  s   
   !) @ @ P PQS T 
 t779:)445EF,778IJ NN!!#++7#M^I_A_8`7aabc-.q. NN!!#u.;;<LM^^**,44--1->->,?sDF  6z?#+#4#4#B#B3x=#Q ,	  ..x8==F*%~~::6;;GH==E) & 5 5fkk BI ''61#,>>#7#7#<Q#?x 8 ( 1 1 ? ?)22!I JJ!//Y 
O'99(94 $$S_5=6@ I667JKL )..|<"%&6"7&&(9	$%./?%@ 6>!!cM$;;*+B*C9M0>"335::8D -#'99R=&77A%)
 ,/x||L"/M+N(&)(,,|R*H&I&)(,,w*C&D(+HLLB,G(H+/(+7 &K)4)C)CH)MJ)53>3O3O 0 %	& a !) * 0 $ 0 + + - $ 1 1( ;
	  &1"JJ ) 5 5"-hZtJ< H
 #JJ ) 7 7":8* EU-6>p NN!!#   Y%=%=a!:;^^**,FNNYZ^ZkZkYllno "8	8P8P!Qb";<$-$;$;  088)9 9  -8 (J!+!2!2!4J+5+>+>w+G
3BZ  NN S#X/?G	 c#<=NN!!#- &> { /t- -\ ! >JJy66==> NN!!#sa   	W5<	W:
*%Y #X3B3W?'BW?4X<Y ?X		X	Y$X?9Y ?YY Y#rd   c                    i }g }d}|r|j                  d       |r|j                  d| d       |r|ddj                  |       z  }| j                  j                         j	                  |      }|D ]H  }|d   |v r4|d   r/|d   r*t
        j                  d	|d    d
|d    d||d              |d   ||d   <   J |S )Nz&SELECT location, identifier FROM cachez	local = 1zoperating_system = ''z WHERE z AND rX   rW   zDuplicate entry for identifier z: z and )appendr8   r}   r   r   r   debug)r   r$   rd   output	additionsr   r   r   s           r   rf   z%SqliteCache.get_identifier_dictionary  s     	<	[)34D3EQGH77<<	#:";<<I..'')11)< 	8C< F*s</@S_5c,6G5H3z?J[[`aghklxhyaz`{| ),JF3|$%	8 r   c                 &   |r:| j                   j                         j                  d|f      j                         }n7| j                   j                         j                  d      j                         }g }|D ]  }|j	                  |d           |S )Nz7SELECT identifier FROM cache WHERE operating_system = ?zSELECT identifier FROM cacherX   )r}   r   r   r   r   )r   r$   r   r   r   s        r   rj   zSqliteCache.get_identifiers  s    %%'M%'   %%'78 
  	-CMM#l+,	-r   r   rp   )r!   r"   r#   _required_framework_version_versionr:   r   r~   
Connectionr|   r&   r   r]   r   r`   rq   r   r    r	   r;   rl   ro   rc   r   rf   r   rj   rr   rs   s   @r   ru   ru      s,   "+H= =!S !W-?-? !F3;C=	#0"YsD$%? "0 0 0
s x 	%S#s*+	,( # Y$x JO (BF	eSj	* $u+ r   ru   c                   r     e Zd ZdZdZ fdZddZedee	j                  j                     fd       Z xZS )SymbolCacheMagicz;Runs through all symbol tables and caches their identifiersr   c                     t        |   |i | t        j                  j	                  t
        j                  t
        j                        }t        |      | _	        y r   )
rQ   r   r   r   r8   r   
CACHE_PATHIDENTIFIERS_FILENAMEru   _cache)r   argskwargsidentifiers_pathrV   s       r   r   zSymbolCacheMagic.__init__  sH    $)&)77<<  )"@"@
 ""23r   c                 :    | j                   j                  |       y)z)Runs the automagic over the configurable.N)r  rc   )r   contextconfig_pathconfigurabler   s        r   __call__zSymbolCacheMagic.__call__  s    ,-r   r   c                 <    t        j                  dt        d      gS )zOReturns a list of RequirementInterface objects required by this
        object.SQLiteCacherw   )name	componentrA   )r   VersionRequirementru   )r   s    r   get_requirementsz!SymbolCacheMagic.get_requirements  s#    
 ++"k9
 	
r   r   )r!   r"   r#   __doc__priorityr   r	  r%   r   r   configurationRequirementInterfacer  rr   rs   s   @r   r   r     sA    EH4. 
j&>&>&S&S!T 
 
r   r   c            	           e Zd ZdefdZdefdZdeee	e   f   de
e   deeeef   ddf   fdZde
eee	e   f      de
e   deeeef   ddf   fd	Zy)
r   rW   c                     || _         t        j                         j                  |      5 }t	        j
                  |      | _        d d d        | j                         st        d      y # 1 sw Y   %xY w)N)r   z5Unsupported version for remote identifier list format)		_locationr   r   r   r   r   _data_verify
ValueError)r   rW   r   s      r   r   zRemoteIdentifierFormat.__init__  sc    !'')..8.< 	'2DJ	'||~TUU 	' 	's   A++A4r   c           	      z    | j                   j                  dd      }|dv rt        | dt        | d|              yy)NrA   r   )rx   r   	process_vTF)r  r1   setattrgetattr)r   rA   s     r   r  zRemoteIdentifierFormat._verify  s=    **..A.c>D)WTYwi3H%IJr   r   r$   Nc                     t        d      )Nz$Identifier List version not verified)r  )r   r   r$   s      r   r   zRemoteIdentifierFormat.process  s     ?@@r   c              #     K   || j                   v rF| j                   |   D ]4  }t        j                  |      }| j                   |   |   D ]  }||f 
 6 d| j                   v r:| j                   d   D ](  }	 t        |      }|j	                  ||      E d {    * |S 7 # t
        $ r t        j                  d|        Y Rw xY ww)N
additionalzRemote file not found: )r  rD   rE   r   r   IOErrorr   r   )r   r   r$   rX   binary_identifiervaluerW   subrbfs           r   
process_v1z!RemoteIdentifierFormat.process_v1!  s     
 tzz)"jj)9: 3
$*$4$4Z$@!!ZZ(89*E 3E+U2233 4::% JJ|4 GG3H=F%~~k;KLLLG  M GLL#:8*!EFGs<   A5C
8 B#B!B#C
!B##!CC
CC
)r!   r"   r#   r:   r   rq   r  r   r&   r   r   r   r	   r   r%  r   r   r   r   r     s    V V AtCy 01AEMc]A	5$dD0	1A
d5$s)#345 #3- 
5$dD0	1	r   r   )0rD   r   r   loggingr   r~   r   urllib.parseurllib.requestabcr   typingr   r   r   r   r   r	   volatility3r
   r   volatility3.frameworkr   r   #volatility3.framework.configurationr   volatility3.framework.layersr   volatility3.framework.symbolsr   	getLoggerr!   r   r&   r:   BannersTyper   r(   r=   rI   r  VersionableInterfacerN   ru   	automagicAutomagicInterfacer   r   r   r   r   <module>r5     s        	      C C * 7 < 2 2			8	$5$s)#$
 
&X+ X*
' 

) 
 EFJ44II EFPA' AN

z++>> 
6% %r   