
    Xfq                        d 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
Z
ddlmZmZ ddlmZmZmZmZmZmZmZmZmZ ddlmZmZmZ  ej        e          Zedej        j         f         Z!eeee"e#e#f                  e#f         Z$ G d dej%        j&        e	          Z' G d
 dej%        j(        e	          Z) G d de)e	          Z* G d dej        j                  Z+ G d de,          Z-dS )zDefines layers for containing data.

One layer may combine other layers, map data based on the data itself,
or map a procedure (such as decryption) across another layer of data.
    N)ABCMetaabstractmethod)	AnyCallableDictIterableListMappingOptionalTupleUnion)	constants
exceptions
interfacesDummyProgressc                        e Zd ZdZdZdZd fdZeded         fd            Z	e	j
        dd
            Z	edee         fd            Zej
        deddfd            Zedededee         fd            Z xZS )ScannerInterfaceaM  Class for layer scanners that return locations of particular values from
    within the data.

    These are designed to be given a chunk of data and return a generator which yields
    any found items.  They should NOT perform complex/time-consuming tasks, these should
    be carried out by the consumer of the generator on the items returned.

    They will be provided all *available* data (therefore not necessarily contiguous)
    in ascending offset order, in chunks no larger than chunk_size + overlap where
    overlap is the amount of data read twice once at the end of an earlier chunk and
    once at the start of the next chunk.

    It should be noted that the scanner can maintain state if necessary.
    Scanners should balance the size of chunk based on the amount of time
    scanning the chunk will take (ie, do not set an excessively large chunksize
    and try not to take a significant amount of time in the __call__ method).

    Scanners must NOT return results found *after* self.chunk_size (ie, entirely contained
    within the overlap).  It is the responsibility of the scanner not to return such
    duplicate results.

    Scanners can mark themselves as thread_safe, if they do not require state
    in either their own class or the context.  This will allow the scanner to be run
    in parallel against multiple blocks.
    F)   r   r   returnNc                     t                                                       d| _        d| _        d | _        d | _        d S )Ni   i   )super__init__
chunk_sizeoverlap_context_layer_name)self	__class__s    Y/home/panchajanya/Development/work/volatility3/volatility3/framework/interfaces/layers.pyr   zScannerInterface.__init__>   s<    #GK*.    #interfaces.context.ContextInterfacec                     | j         S Nr   r   s    r   contextzScannerInterface.contextE   s
    }r    ctxc                     || _         dS )zQStores the context locally in case the scanner needs to access the
        layer.Nr$   )r   r'   s     r   r&   zScannerInterface.contextI   s     r    c                     | j         S r#   r   r%   s    r   
layer_namezScannerInterface.layer_nameO   s    r    r+   c                     || _         dS )zbStores the layer_name being scanned locally in case the scanner
        needs to access the layer.Nr*   )r   r+   s     r   r+   zScannerInterface.layer_nameS   s     &r    datadata_offsetc                     dS )aC  Searches through a chunk of data for a particular value/pattern/etc
        Always returns an iterator of the same type of object (need not be a
        volatility object)

        data is the chunk of data to search through data_offset is the
        offset within the layer that the data being searched starts at
        N )r   r-   r.   s      r   __call__zScannerInterface.__call__Y         r    r   N)r'   r!   r   N)__name__
__module____qualname____doc__thread_safe_required_framework_versionr   propertyr   r&   setterstrr+   r   bytesintr   r   r1   __classcell__r   s   @r   r   r      s9        4 K"+/ / / / / / "GH    X ^   ^
  HSM       X  &S &T & & & &
 U  #    ^    r    r   )	metaclassc                   t    e Zd ZU dZdddZeed<   	 d,ddded	ed
ee	ee
f                  ddf
 fdZedefd            Zeedefd                        Zeedefd                        Zedefd            Zed-dededefd            Zed.dedededefd            Zedededdfd            Zd/dZedeej        j                 f fd            Zedee         fd            Z	 	 d0dej         j!        de"de#j$        de%e&eef                  de%e
         f
d Z'de%e&eef                  de%e&eef                  fd!Z(dd"de%e&eef                  de%e)         fd#Z*dd"d$d%d&e)dee
         fd'Z+d(d"dee&eef                  de,ege-f         fd)Z.dej        j/        f fd*Z0edefd+            Z1 xZ2S )1DataLayerInterfacezA Layer that directly holds data (and does not translate it).

    This is effectively a leaf node in a layer tree. It directly
    accesses a data source and exposes it within volatility.
    Unknown)architectureos_direct_metadataNr&   r!   config_pathnamemetadatar   c                 l    t                                          ||           || _        |pi | _        d S r#   )r   r   _name	_metadata)r   r&   rH   rI   rJ   r   s        r   r   zDataLayerInterface.__init__o   s5     	+...
!Rr    c                     | j         S )zReturns the layer name.)rL   r%   s    r   rI   zDataLayerInterface.name|   s     zr    c                     dS )z/Returns the maximum valid address of the space.Nr0   r%   s    r   maximum_addressz"DataLayerInterface.maximum_address   r2   r    c                     dS )z/Returns the minimum valid address of the space.Nr0   r%   s    r   minimum_addressz"DataLayerInterface.minimum_address   r2   r    c                 ~    dt          t          j        t          j        | j                                      z  dz
  S )z[Returns a mask which encapsulates all the active bits of an address
        for this layer.   )r>   mathceillog2rP   r%   s    r   address_maskzDataLayerInterface.address_mask   s3     S49T-A#B#BCCDDDIIr    rT   offsetlengthc                     dS )av  Returns a boolean based on whether the entire chunk of data (from
        offset to length) is valid or not.

        Args:
            offset: The address to start determining whether bytes are readable/valid
            length: The number of bytes from offset of which to test the validity

        Returns:
             Whether the bytes are valid and accessible
        Nr0   )r   rY   rZ   s      r   is_validzDataLayerInterface.is_valid   r2   r    Fpadc                     dS )a  Reads an offset for length bytes and returns 'bytes' (not 'str') of
        length size.

        If there is a fault of any kind (such as a page fault), an exception will be thrown
        unless pad is set, in which case the read errors will be replaced by null characters.

        Args:
            offset: The offset at which to being reading within the layer
            length: The number of bytes to read within the layer
            pad: A boolean indicating whether exceptions should be raised or bad bytes replaced with null characters

        Returns:
            The bytes read from the layer, starting at offset for length bytes
        Nr0   )r   rY   rZ   r]   s       r   readzDataLayerInterface.read   r2   r    r-   c                     dS )a  Writes a chunk of data at offset.

        Any unavailable sections in the underlying bases will cause an exception to be thrown.
        Note: Writes are not guaranteed atomic, therefore some data may have been written, even if an exception is thrown.
        Nr0   )r   rY   r-   s      r   writezDataLayerInterface.write   r2   r    c                     dS )a/  Causes a DataLayer to close any open handles, etc.

        Systems that make use of Data Layers should call destroy when
        they are done with them. This will close all handles, and make
        the object unreadable (exceptions will be thrown using a
        DataLayer after destruction)
        Nr0   r%   s    r   destroyzDataLayerInterface.destroy   s	     	r    c                 D    t                                                      S )z=Returns a list of Requirement objects for this type of layer.)r   get_requirements)clsr   s    r   re   z#DataLayerInterface.get_requirements   s     ww'')))r    c                     g S )zA list of other layer names required by this layer.

        Note:
            DataLayers must never define other layers
        r0   r%   s    r   dependencieszDataLayerInterface.dependencies   s	     	r    scannerprogress_callbacksectionsc           	   #     K   |t          |          st          d          ||_        | j        |_        || j        | j        | j        z
  fg}t          |                     |                    }	 t                      }t          j        | j        ||          }|                     ||          }|j        rt          j        t          j        j        k    rzt                      }t          j        | j        ||          } |            D ]D}	|r/ | ||j                  d| j         d|j        j                     ||	          E d{V  EdS t/          j                                        dd          }t.          }
t          j        t          j        j        k    rt                      }t6          }
t          j        | j        ||          }|
                                5 }|                    | |                      }|                                sZ|r/ | ||j                  d| j         d|j        j                    |                    d           |                                Z|                                 D ]
}|E d{V  	 ddd           dS # 1 swxY w Y   dS # tB          $ r}tD          #                    dtI          |                      tD          %                    t          j&        d	'                    tP          j)        *                    |          +                    d
                               Y d}~dS d}~ww xY w)a0  Scans a Translation layer by chunk.

        Note: this will skip missing/unmappable chunks of memory

        Args:
             context: The context containing the data layer
             scanner: The constructed Scanner object to be applied
             progress_callback: Method that is called periodically during scanning to update progress
             sections: A list of (start, size) tuples defining the portions of the layer to scan

        Returns:
             The output iterable from the scanner object having been run against the layer
        Nz!Progress_callback is not callablez	Scanning z using Qr   g?zScan Failure: 
T)chain),callable	TypeErrorr&   rI   r+   rR   rP   list_coalesce_sectionsr   	functoolspartial_scan_iterator_scan_metricr8   r   PARALLELISMParallelismOff_scan_chunkvaluer   r4   multiprocessingManagerValue	Threading	threadingPool	map_asyncreadywaitget	Exceptionvollogdebugr<   logLOGLEVEL_VVVjoin	tracebackTracebackExceptionfrom_exceptionformat)r   r&   ri   rj   rk   progressscan_iteratorscan_metric
scan_chunkr|   parallel_modulepoolresultresult_valuees                  r   scanzDataLayerInterface.scan   s     ( (:K1L1L(?@@@!!Y%t';d>R'RSH //99::.	&3ooH%-d.A7HUUM++GX>>K'!0(I,A,EEE(??&.t/?(SS
*]__ 1 1E( ))'K77V	VV':K:TVV    *z%00000000001 1 +244::3BB4C(I,A,KKK,H&/O&.t/?(SS
$))++ 0t!^^JHHF$llnn 	), -- +HN ; ; ZDI Z Zg>O>X Z Z   C((( %llnn 	) )/

 0 0#/////////00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  	 	 	LL2#a&&22333JJ&		0??BBIIPTIUU         	sF   2CJ) BJ) "B,JJ) J  J) #J $J) )
M3BMMc                    g }d}t          |          D ]^\  }}|r;||k    r5|                                \  }}|                    |||z   |z
  f           n|                    ||f           ||z   }_|rn|d         | j        dfk     r[|d         \  }}	||	z   | j        k     r|dd         }n"|| j        k     r| j        ||	z   | j        z
  f|d<   |r|d         | j        dfk     [|rp|d         | j        dfk    r]|d         \  }
}|
| j        k    r|                                 n|
|z   | j        k    r|
| j        |
z
  f|d<   |r|d         | j        dfk    ]|S )zSTake a list of (start, length) sections and coalesce any adjacent
        sections.r   rT   N)sortedpopappendrR   rP   )r   rk   r   positionstartrZ   initial_start_first_startfirst_length
last_startlast_lengths               r   rs   z%DataLayerInterface._coalesce_sections"  s   
 )+#H-- 	& 	&ME6 /%8++#)::<< q}uv~.NOPPPPufo...v~HH 	d&:A%>>>(.q	%K\)D,@@@t333( </43GGq	  	d&:A%>>>  	Lt';Q&???&,Rj#JD000

k)D,@@@')=
)JKq	  	Lt';Q&??? r    r   c              #      K   |D ]o\  }}|||| j         f\  }}}}|dk    rTt          ||j        |j        z             }	|||	fg||	z   fV  |	|j        k    r
|	|j        z  }	||	z  }||	z  }||	z  }|dk    TpdS )Y  Iterator that indicates which blocks in the layer are to be read by
        for the scanning.

        Returns a list of blocks (potentially in lower layers) that make
        up this chunk contiguously. Chunks can be no bigger than
        scanner.chunk_size + scanner.overlap DataLayers by default are
        assumed to have no holes
        r   N)rI   minr   r   )
r   ri   rk   section_startsection_lengthrY   mapped_offsetrZ   r+   r   s
             r   rv   z!DataLayerInterface._scan_iteratorB  s       .6 	% 	%)M>		95FM6: 1** );go)MNN
"M:>?*ATTTTT 222'/1J*$+*$ 1**	% 	%r    r   ProgressValueiterator_valuec           	         |\  }}d}|D ]y\  }}}		 || j         j        |                             ||	          z  }1# t          j        $ r7 t
                              d                    || j        |                     Y vw xY wt          |          |j
        |j        z   k    r7t
                              dt          t          |                                ||_        t           |||t          |          z
                      S )Nr    z=Invalid address in layer {} found scanning {} at address {:x}zScan chunk too large: )r&   layersr_   r   InvalidAddressExceptionr   r   r   rI   lenr   r   hexr|   rr   )
r   ri   r   r   data_to_scan	chunk_endr-   r+   addressr   s
             r   r{   zDataLayerInterface._scan_chunk_  s    #1i/; 	 	+J+J7<<WjQQQ5   SZZ"DIw      t99w)GO;;;LLB#c$ii..BBCCC"GGD)c$ii"788999s   );AB B_scannerc                     |st          d          |d         \  }}|d         \  }||z   dt          dt          ffd}|S )Nz&Sections have no size, nothing to scanr   r   r|   r   c                 <    t          d| z
  dz  z
  z            S )Nr   d   )max)r|   max_addressmin_addresss    r   _actual_scan_metricz<DataLayerInterface._scan_metric.<locals>._actual_scan_metric  s'    qEK/36;;TUVVVr    )
ValueErrorr>   float)	r   r   rk   last_sectionr   r   r   r   r   s	          @@r   rw   zDataLayerInterface._scan_metricw  s      	GEFFF$,RL!k!!Q"[0	Ws 	Wu 	W 	W 	W 	W 	W 	W 	W #"r    c                     t                                                      }| j        j        dz   | j        j        z   |d<   |S )N.class)r   build_configurationr   r5   r4   )r   configr   s     r   r   z&DataLayerInterface.build_configuration  s<    ,,.. .3c9DN<SSwr    c                       fd j         D             }t          j                            t	          j         j         j        g|R            S )z@Returns a ReadOnly copy of the metadata published by this layer.c                 >    g | ]}j         j        |         j        S r0   )r&   r   rJ   ).0r+   r   s     r   
<listcomp>z/DataLayerInterface.metadata.<locals>.<listcomp>  s3     
 
 
9CDL
+4
 
 
r    )rh   r   objectsReadOnlyMappingcollectionsChainMaprM   rG   )r   mapss   ` r   rJ   zDataLayerInterface.metadata  sh    
 
 
 
GKGX
 
 
 !11 1FNNNN
 
 	
r    r#   )rT   Fr3   )NN)3r4   r5   r6   r7   rG   r
   __annotations__r<   r   r   r   r   r:   rI   r   r>   rP   rR   rX   boolr\   r=   r_   ra   rc   classmethodr	   r   configurationRequirementInterfacere   rh   r&   ContextInterfacer   r   ProgressCallbackr   r   r   rs   IteratorValuerv   r{   r   r   rw   HierarchicalDictr   rJ   r?   r@   s   @r   rC   rC   d   sR          2;) L LgLLL .2	( 	(6	( 	( 		(
 4S>*	( 
	( 	( 	( 	( 	( 	( c    X > > > > ^ X> > > > > ^ X> Jc J J J XJ
 
 
s 
C 
 
 
 
 ^
  3  $ 5    ^  C u     ^    *j&>&S!T * * * * * [* d3i    X 9=.2O O#4O "O %5	O
 5c?+O 
#O O O Ob sCx1	%S/	"   @%)%5=eCHo5N%	-	 % % % %::#: ": &	:
 
c: : : :0#*#6:5c?6K#	3%,	# # # #Z%=%N       
' 
 
 
 X
 
 
 
 
r    rC   c                   p   e Zd ZdZe	 ddedededeeeeeee	f                  fd            Z
eedee	         fd                        Zd	ed
edededef
dZde	d
edededef
dZ ej        d          ddedededefd            ZdededdfdZ	 ddddeeeef                  dedee         fdZdS )TranslationLayerInterfacezProvides a layer that translates or transforms another layer or layers.

    Translation layers always depend on another layer (typically
    translating offsets in a virtual offset space into a smaller
    physical offset space).
    FrY   rZ   ignore_errorsr   c                     g S )aZ  Returns a sorted iterable of (offset, sublength, mapped_offset, mapped_length, layer)
        mappings.

        ignore_errors will provide all available maps with gaps, but
        their total length may not add up to the requested length This
        allows translation layers to provide maps of contiguous regions
        in one layer
        r0   )r   rY   rZ   r   s       r   mappingz!TranslationLayerInterface.mapping  s	     	r    c                     g S )z>Returns a list of layer names that this layer translates onto.r0   r%   s    r   rh   z&TranslationLayerInterface.dependencies  s	     	r    r-   r   output_lengthc                     |S )ar  Decodes any necessary data.  Note, additional data may need to be read from the lower layer, such as lookup
        tables or similar.  The data provided to this layer is purely that data which encompasses the requested data
        range.

        Args:
            data: The bytes of data necessary for decoding
            mapped_offset: The offset in the underlying layer where the data would begin
            offset: The offset in the higher-layer where the data would begin
            output_length: The expected length of the returned data

        Returns:
             The data to be read from the underlying layer.r0   )r   r-   r   rY   r   s        r   _decode_dataz&TranslationLayerInterface._decode_data  s	     r    r+   r|   c                     |S )a~  Encodes any necessary data.

        Args:
            layer_name: The layer to write data back to
            mapped_offset: The offset in the underlying layer where the data would begin
            offset: The offset in the higher-layer where the data would begin
            value: The new value to encode

        Returns:
             The data to be rewritten at mapped_offset.r0   )r   r+   r   rY   r|   s        r   _encode_dataz&TranslationLayerInterface._encode_data  s	     r    i   )maxsizer]   c           	         |}d}|                      |||          D ]\  }}}}	}
|s,||k    r&t          j        | j        |d| j         d|           ||k    r|d||z
  z  z  }|}|	dk    rf| j        j                            |
||	|          }|                     ||||          }t          |          |k    rt          d          ||z  }||z  }|d|t          |          z
  z  z   S )zXReads an offset for length bytes and returns 'bytes' (not 'str') of
        length size.r    r   Layer  cannot map offset:     r   z<ProcessedData length does not match expected length of chunk)
r   r   r   rI   r   r   r_   r   r   r   )r   rY   rZ   r]   current_offsetoutputlayer_offset	sublengthr   mapped_lengthlayerunprocessed_dataprocessed_datas                r   r_   zTranslationLayerInterface.read  sZ      \\&&\<<	, 	, 
 .<.88 8I"LTYLLNLL  
 ..'\N%BCC!- q  #'=#7#<#<=-$ $  "&!2!2$m\9" " ~&&)33$V   .()+FS[[$89::r    Nc           	      z   |}t          |          }|                     ||          D ]\  }}}}}	||k    r&t          j        | j        |d| j         d|           |||z
  ||z
  |z            }
|                     |	|||
          }| j        j                            |	||           |t          |          z  }dS )zYWrites a value at offset, distributing the writing across any
        underlying mapping.r   r   N)	r   r   r   r   rI   r   r   r   ra   )r   rY   r|   r   rZ   r   r   r   r   r   value_chunknew_datas               r   ra   zTranslationLayerInterface.write  s      U \\&&))	, 	, 
n,, 8I"LTYLLNLL    v%v(=	(IIK ((}lK H M &&umXFFFc(mm+NN-	, 	,r    ri   r   rk   linearc           	   #     K   |D ]\  }}g }dx}}|                      ||d          D ]}	|	\  }
}}}}|
}|
|z   }|r||
z
  nd}|r|n| j        }||k     r||fV  g }|x}}||k    r3t          ||z
  |j        |j        z             }||||z   |fgz  }||z   }|}t          |||j                  D ]G}|r
||fV  g }|}t          ||z
  |j        |j        z   ||z
  z
            }||||z   |fgz  }||z   }|}H|r||fV  dS )r   r   Tr   N)r   rI   r   r   r   range)r   ri   rk   r   r   r   r   chunk_startchunk_positionmappedrY   r   r   r   r+   block_start	block_end
conversionreturn_namer   s                       r   rv   z(TranslationLayerInterface._scan_iterator  s      .6 >	- >	-)M>13F ,-,K.
 ,,~T '   11 11 OUK	=- %"Y.	 8>D]V331
,2Ajj	 "K// .0000F3>>K. "[00!$&4*W_<" "J ^j-H*UVVF"0:"=K%0N $)GDV#W#W 1 1K 5$n4444!#)4 "%!N2*!/*)K79" "J ^j-H*UVVF"0:"=K%0NN1$  -n,,,,}>	- >	-r    r   )r4   r5   r6   r7   r   r>   r   r   r   r<   r   r:   r	   rh   r=   r   r   rt   	lru_cacher_   ra   r   rv   r0   r    r   r   r     s         >C #&7;	%S#sC/0	1   ^ d3i    ^ X*-7:KN	   ".1;>GL	   " Y%%%$; $;3 $; $;$ $;5 $; $; $; &%$;L,C , ,$ , , , ,B 	L- L-#L- 5c?+L- 	L-
 
-	 L- L- L- L- L- L-r    r   c                       e Zd ZdZddZddededed	edef
d
Z	d Z
dedededdfdZdeddfdZdeddfdZddedefdZdedefdZdefdZd ZddZdS )LayerContainerz&Container for multiple layers of data.r   Nc                     i | _         d S r#   _layersr%   s    r   r   zLayerContainer.__init__m  s    68r    Fr   rY   rZ   r]   c                 <    | |                              |||          S )a  Reads from a particular layer at offset for length bytes.

        Returns 'bytes' not 'str'

        Args:
            layer: The name of the layer to read from
            offset: Where to begin reading within the layer
            length: How many bytes to read from the layer
            pad: Whether to raise exceptions or return null bytes when errors occur

        Returns:
            The result of reading from the requested layer
        )r_   )r   r   rY   rZ   r]   s        r   r_   zLayerContainer.readp  s      E{444r    c                 B    t          |           t          |          k    S r#   )dict)r   others     r   __eq__zLayerContainer.__eq__  s    DzzT%[[((r    r-   c                 >    | |                              ||           dS )z8Writes to a particular layer at offset for length bytes.N)ra   )r   r   rY   r-   s       r   ra   zLayerContainer.write  s"    U&$'''''r    c           	      J    |j          j        v r"t          j        |j         d|j                    t	          |t
                    rM fd|j        D             }|r8t          j        |j         d|j          dd                    |                     | j        |j         <   dS )zAdds a layer to memory model.

        This will throw an exception if the required dependencies are not met

        Args:
            layer: the layer to add to the list of layers (based on layer.name)
        zLayer already exists: c                 &    g | ]}|j         v|S r0   r  )r   sublayerr   s     r   r   z,LayerContainer.add_layer.<locals>.<listcomp>  s0       4<// ///r    r   z has unmet dependencies: z, N)rI   r  r   LayerException
isinstancer   rh   r   )r   r   missing_lists   `  r   	add_layerzLayerContainer.add_layer  s     :%%+
AUZAA   e677 
	    % 2  L
   /J[UZ[[$))LBYBY[[   $)UZ   r    rI   c                    | j         D ]Q}|| j         |         j        v r;t          j        | j         |         j        d| j         |         j         d|           R| j         |                                          | j         |= dS )zRemoves the layer called name.

        This will throw an exception if other layers depend upon this layer

        Args:
            name: The name of the layer to delete
        r   z is depended upon by N)r  rh   r   r  rI   rc   )r   rI   r   s      r   	del_layerzLayerContainer.del_layer  s     \ 	 	Et|E*777 /L',ST\%05SSESS   8 	T""$$$Lr    prefixc                 N    || vr|S d}| d| | v r|dz  }| d| | v | d| S )a>  Returns an unused layer name to ensure no collision occurs when
        inserting a layer.

        Args:
            prefix: A descriptive string with which to prefix the layer name

        Returns:
            A string containing a name, prefixed with prefix, not currently in use within the LayerContainer
        rT   r   r0   )r   r  counts      r   free_layer_namezLayerContainer.free_layer_name  sj     M!!%!!T))QJE !!%!!T))""5"""r    c                     | j         |         S )z$Returns the layer of specified name.r  )r   rI   s     r   __getitem__zLayerContainer.__getitem__  s    |D!!r    c                 *    t          | j                  S r#   )r   r  r%   s    r   __len__zLayerContainer.__len__  s    4<   r    c                 *    t          | j                  S r#   )iterr  r%   s    r   __iter__zLayerContainer.__iter__  s    DL!!!r    c                      t          d          )zXRuns through the available layers and identifies if there are cycles
        in the DAG.z+Cycle checking has not yet been implemented)NotImplementedErrorr%   s    r   check_cycleszLayerContainer.check_cycles  s     ""OPPPr    r3   r   )r   )r4   r5   r6   r7   r   r<   r>   r   r=   r_   r  ra   rC   r  r  r  r  r  r   r#  r0   r    r   r  r  j  s|       009 9 9 95 5# 5s 5C 5d 5u 5 5 5 5 ) ) )(3 ( (5 (T ( ( ( ()1 )d ) ) ) )2c d    $# #c # # # # #"" "(: " " " "! ! ! ! !" " "Q Q Q Q Q Qr    r  c                       e Zd ZdZddZdS )r   z;A class to emulate Multiprocessing/threading Value objects.r   Nc                     d| _         d S )Nr   )r|   r%   s    r   r   zDummyProgress.__init__  s    


r    r3   )r4   r5   r6   r7   r   r0   r    r   r   r     s.        EE     r    ).r7   collections.abcr   rt   loggingrU   r}   multiprocessing.managersr   r   typesabcr   r   typingr   r   r   r   r	   r
   r   r   r   volatility3.frameworkr   r   r   	getLoggerr4   r   managers
ValueProxyr   r<   r>   r   r   VersionableInterfacer   ConfigurableInterfacerC   r   r  objectr   r0   r    r   <module>r3     sf   
                            ' ' ' ' ' ' ' ' W W W W W W W W W W W W W W W W W W W W W W C C C C C C C C C C		8	$	$o'?'JJKd5c3/0#56D D D D D1WD D D DNr
 r
 r
 r
 r
2gr
 r
 r
 r
j	N- N- N- N- N- 2g N- N- N- N-bgQ gQ gQ gQ gQ[_, gQ gQ gQT    F     r    