
    *1fb]                         d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	 d dl
mZ d dlmZmZ d dlmZ d dlmZ  e j        e          Z	  G d dej                  Z G d	 d
ej                  ZdS )    N)OptionalDictAnyListIterableTuple)classproperty)
interfaces
exceptions)requirements)linearc                       e Zd ZdS )AArch64ExceptionN)__name__
__module____qualname__     R/home/panchajanya/Development/work/volatility3/volatility3/framework/layers/arm.pyr   r      s        Dr   r   c                       e Zd ZdZ ej        dd iddiej        j        j	                  Z	dZ
e
dz  ZdZeZg dg dg d	d
Z	 d8dej        j        dededeeeef                  ddf
 fdZd9dZededededee         fd            Zedededeee                  fd            Zdedeeeef         fdZdedeeeef         fdZ	 d:dededede eeeeeef                  fd Z!	 d:dededede eeeeeef                  fd!Z"dee         fd"Z#d;dededefd$Z$dedefd%Z%e&d&edefd'            Z'e( e)j*                    defd(                        Z+e( e)j*                    defd)                        Z,e( e)j*                    defd*                        Z-e. e)j*                    defd+                        Z/e. e)j*                    defd,                        Z0e. e)j*                    defd-                        Z1d.edefd/Z2d.edefd0Z3e&	 d8d1ed2ed3ed4ee         def
d5            Z4e(dee         fd6            Z5edeej6        j7                 fd7            Z8 xZ9S )<AArch64zTranslation Layer for the Arm AArch64 memory mapping.

    This layer can be instantiated in two contexts : Low space (user land), High space (kernel land).
    architecturemappedT@      ))3   0   )/   '   )&      )      )      ))r   r   ).   $   )#      )      ))r   *   ))   r"   )      )   r/   r   Ncontextconfig_pathnamemetadatareturnc                 T   t                                          ||||           | j        d         | _        | j                            dd          | _        | j                            dd          | _        | j        d         | _        | j        d         | _        | j        d         | _	        | j        d	         | j        d
         g| _
        | j        d         | j        d         g| _        t          | j        | j        d         k              | _        d| j
        | j                 z
  | _        | j        | j                 | _        	 | j
        | j                 dk     rdnd| _        |                     | j        | j                  | _        |                     | j        | j        | j                  | _        |                                 | j                 | _        |                     d| j        z  dz
  | j        | j                  | _        | j        r|                                  d S d S )N)r1   r2   r3   r4   kernel_endiannesslayer_debugFtranslation_debugmemory_layerpage_map_offsetpage_map_offset_kerneltcr_el1_t0sztcr_el1_t1szpage_size_user_spacepage_size_kernel_spacer   r/   T   )super__init__config_kernel_endiannessget_layer_debug_translation_debug_base_layer_page_map_offset_page_map_offset_kernel
_ttbs_tnsz_ttbs_granulesint_virtual_addr_space_ttb_bitsize_ttb_granule
_is_52bits_determine_ttb_lookup_indexes_ttb_lookup_indexes_determine_ttb_descriptor_bits_ttb_descriptor_bits_get_virtual_addr_range_virtual_addr_range_mask_bits_per_register_canonical_prefix_print_layer_debug_informations)selfr1   r2   r3   r4   	__class__s        r   rC   zAArch64.__init__=   s)    	4( 	 	
 	
 	
 #'+.A"B KOOM5AA"&+//2Eu"M"M;~6 $,= >'+{3K'L$;~6N8STK./K01
 $'!T[1I%JJ$
 $
 
 1I!JJ /0HI	 OD$<=BBDD 	 $(#E#Et0$
 $
  %)$G$Gt7%
 %
! $(#?#?#A#A$$
  "&$))Q.#"
 "

  	30022222	3 	3r   c                 r   t                               d| j                    t                               d| j        rdnd            t                               dt	          d |                                 D                                   t                               d| j                    t                               d| j         d	| j        | j                             t                               d
t          | j	                              t                               d| j
                    d S )NzBase layer : zVirtual address space : kerneluserz Virtual addresses space range : c                 ,    g | ]}t          |          S r   )hex).0xs     r   
<listcomp>z;AArch64._print_layer_debug_informations.<locals>.<listcomp>{   s    5e5e5ec!ff5e5e5er   zPage size : TzSZ : zPage map offset : zTranslation mappings : )vollogdebugrI   rO   tuplerW   rQ   rL   rc   rJ   rT   r]   s    r   r\   z'AArch64._print_layer_debug_informationsu   s5   7T%577888Y43K'WxxQWYY	
 	
 	
 	hu5e5edFbFbFdFd5e5e5e/f/fhh	
 	
 	
 	7D$577888Z(ZZtt?W/XZZ	
 	
 	
 	F#d.C*D*DFFGGGIt/GIIJJJtr   ttb_granulettb_lookup_indexes	is_52bitsc                 2    |dv r|rdnd|d         d         fS )zReturns the descriptor bits to extract from a descriptor (high and low)

        Example with granule = 4 kB without 52 bits :
            (47,12)
        Example with granule = 16 kB and 52 bits :
            (49,14)
        r0   r/   1   r   rA   r   )clsrl   rm   rn   s       r   rU   z&AArch64._determine_ttb_descriptor_bits   s1     ((Y(BBBr"1%
 	
r   ttb_bitsizec                 f    fd| j         |         D             }dz
  |d         d         f|d<   |S )a  Returns the bits to extract from a translation address (highs and lows)

        Example with bitsize = 47 and granule = 4 kB :
            indexes = [(51, 48), (47, 39), (38, 30), (29, 21), (20, 12)]
            result = [(46, 39), (38, 30), (29, 21), (20, 12)]
        c                 ,    g | ]}|d          k    |S rA   r   )rd   indexrt   s     r   rf   z9AArch64._determine_ttb_lookup_indexes.<locals>.<listcomp>   s2     
 
 
U1X%% %%%r   rA   r   )_granules_indexes)rs   rl   rt   indexess     ` r   rS   z%AArch64._determine_ttb_lookup_indexes   sT    
 
 
 
.{;
 
 

 "Aowqz!}5
r   virtual_offsetc                     |                      |          \  }}}|                     ||dz
  d          }||z   }|d|z  | j        fS )zTranslates a specific offset based on paging tables.

        Returns the translated offset, the contiguous pagesize that the
        translated address lives in and the layer_name that the address
        lives in
        rA   r      )_translate_entryrY   rI   )r]   r{   table_addressposition_offset_within_pagephysical_offsets          r   
_translatezAArch64._translate   sW     &*%:%:>%J%J"x!ZZ1aHH'*<<8T-===r   c                    | j         j        | j                 }|                     |dd          }|| j        k    rt          j        | j        |          | j        r| j	        dv rd}n| j	        dk    rd}| j
        }t          | j                  dz
  }t          | j                  D ]\  }\  }}	|                     |||	          }
t                              |                    ||
| j        z  z   | j                  | j                  }d	}| j        r=|                     ||d	         |d                   }|d
|                                z
  z  }|                     |dd	          }||k     rF|dk    r@||                     || j        d	         | j        d                   | j        d         z  z  }||k     r0|dk    r*||                     || j        d	         |	          |	z  z  } ni||k    rF|dk    r@||                     || j        d	         | j        d                   | j        d         z  z  } nt          j        | j        ||	|          | j        rrt.                              dt3          |           dt3          |           dt3          |                     ||	dz
  d	                     dt3          |                      ||	|fS )zTranslates a virtual offset to a physical one within this segment
        Returns the translated address, the maximum offset within the block and the page
        the translated address lives in
        7   
layer_nameinvalid_addressrp   )	   r   r   )   r%   rA   )	byteorderr   4      )r   r   invalid_bitsentryzVirtual z lives in page frame z at offset z with descriptor )r1   layersrI   rY   rO   r   InvalidAddressExceptionr3   rR   rQ   rJ   lenrT   	enumeraterN   
from_bytesread_register_sizerE   
bit_lengthrV   PagedInvalidAddressExceptionrH   rh   ri   rc   )r]   r{   
base_layerttb_selectorta_51_x_bitsr   	max_levellevelhigh_bitlow_bitrx   
descriptorta_51_xdescriptor_types                 r   r~   zAArch64._translate_entry   s   
 \()9:
 zz."b99 433349 .    ? 	( G++%"b(('-011A5	*3D4L*M*M ;	 ;	&E&HgJJ~xAAE!UT-@%@A4CV  1	 (  J M G** O O 
 !(B1C1C1E1E,E F #jjQ::Oy  _%<%<JJ"1!41!4 
 034 ""$'>'>JJ"1!4 
  )##4(?(?JJ"1!41!4 
 034  !=#y$2!($	    " 	LL v3~..  v  vSEWEW  v  vdghlhrhr  tB  DK  LM  DM  OP  iQ  iQ  eR  eR  v  v  eh  is  et  et  v  v   gz11r   Foffsetlengthignore_errorsc              #     K   dx}x}x}x}}|                      |||          D ]B\  }}	}
}}|||z   |k    s||z   |
k    s||k    r|	|||||fV  |}|
}|	}|}|}8||	z  }||z  }C||||||||||fV  dS dS dS dS dS dS )Returns a sorted iterable of (offset, sublength, mapped_offset, mapped_length, layer)
        mappings.

        This allows translation layers to provide maps of contiguous
        regions in one layer
        N)_mapping)r]   r   r   r   stashed_offsetstashed_mapped_offsetstashed_sizestashed_mapped_sizestashed_map_layersizemapped_offsetmapped_size	map_layers                r   mappingzAArch64.mapping  sL      	 	. 	 	@SCG==FMD
 D
 	3 	3?FD-i &"\1V;;),??=PP%22 "-(,8MObduuuuu!'(5%#&1#$-!! $#{2## &%1(#/!- ,0EGZ\mmmmmmm '&11((//--r   c              #   D  K   |dk    rz	 |                      |          \  }}}| j        j        |                             |          st	          j        ||          n# t          j        $ r |s Y dS w xY w|||||fV  dS |dk    r	 	 |                      |          \  }}}t          |||z  z
  |          }	| j        j        |                             ||	          st	          j        ||          	 ||	||	|fV  ||	z  }||	z  }n# t          j        t          j        f$ rm}
	 |s t          |
t          j                  rd|
j	        z  dz
  }n"d| j
                                        dz
  z  dz
  }|dz   ||z  z
  }||z  }||z  }Y d}
~
nd}
~
ww xY w|dk    dS dS )r   r   r   NrA   )r   _contextr   is_validr   r   minr   
isinstancer   rQ   r   )r]   r   r   r   r   r   r   chunk_offset	page_size
chunk_sizeexcpmasklength_diffs                r   r   zAArch64._mappingB  sS      Q;;	/3v/F/F,q*}+J7@@OO $<#-}    5   $ tt &-CCCC4qjj&%6:oof6M6M3i lY.F!GPP
}+J7@@ *   %<#-|   0 j,
JNNNN*$*$' 72 & & & % dJ$KLL K!22a7DD$"3">">"@"@1"DEJD"Qh&4-8+%+%!&; qjjjjjjs,   AA A54A5A+D F'A#FFc                 ~    | j         dk    rd}d| j        dz
  z  }||dz
  z   }nd}d| j        dz
  z  }||dz
  z
  }||fS )zVReturns the virtual address space range for the current context (user or kernel space)r   rA   l    )rO   rP   )r]   	ttb_startttb_sizettb_ends       r   rW   zAArch64._get_virtual_addr_range  si     #q((IT.23H8a<0GGGT.23H8a<0I7##r   rA   c                      	 t           fd                     ||          D                       S # t          j        $ r Y dS w xY w)zPReturns whether the address offset can be translated to a valid
        address.c                 f    g | ]-\  }}}}}j         j        |                             |          .S r   )r   r   r   )rd   r   r   layerr]   s       r   rf   z$AArch64.is_valid.<locals>.<listcomp>  sK       51mQ M(/88GG  r   F)allr   r   r   )r]   r   r   s   `  r   r   zAArch64.is_valid  su    		   9=ff9U9U     1 	 	 	55	s   .2 AAc                 ^    |                      |                     |          d                   S )z2Returns whether the page at offset is marked dirtyr}   )_page_is_dirtyr~   )r]   r   s     r   is_dirtyzAArch64.is_dirty  s)    ""4#8#8#@#@#CDDDr   r   c                 &    t          | dz            S )a  Returns whether a particular page is dirty based on its entry.
        The bit indicates that its associated block of memory
        has been modified and has not been saved to storage yet

        Hardware management (only > Armv8.1-A) : https://developer.arm.com/documentation/102376/0200/Access-Flag/Dirty-state
        + [1], see D8.4.6, page 5877 and [1], see D8-16, page 5857
        l          )bool)r   s    r   r   zAArch64._page_is_dirty  s     EW%&&&r   c                 :    | j                                         dz
  S )zlPage shift for this layer, which is the page size bit length.
        - Typical values : 12, 14, 16
        rA   )r   r   rk   s    r   
page_shiftzAArch64.page_shift  s     ~((**Q..r   c                     | j         dz  S )zYPage size of this layer, in bytes.
        - Typical values : 4096, 16384, 65536
        i   )rQ   rk   s    r   r   zAArch64.page_size  s      4''r   c                     | j         dz
   S )zPage mask for this layer.rA   )r   rs   s    r   	page_maskzAArch64.page_mask  s     "##r   c                     | j         S )z[Returns the bits_per_register to determine the range of an
        AArch64TranslationLayer.)rZ   r   s    r   bits_per_registerzAArch64.bits_per_register  s    
 %%r   c                     dS )Nr   r   r   s    r   minimum_addresszAArch64.minimum_address  s	     qr   c                     d| j         z  dz
  S )NrA   )_maxvirtaddrr   s    r   maximum_addresszAArch64.maximum_address  s     S%%**r   addrc                     | j         | j        k    r
|| j        z  S |d| j        dz
  z  k     r|S |                     || j        d          | j        z   S )z[Canonicalizes an address by performing an appropiate sign extension on the higher addressesrA   r   )rZ   rP   address_maskrY   r[   r]   r   s     r   canonicalizezAArch64.canonicalize  s_    "d&777$+++Q$+a//00Kzz$ 11558NNNr   c                 <    |d| j         dz
  z  k     r|S || j        z  S )zRemoves canonicalization to ensure an adress fits within the correct range if it has been canonicalized

        This will produce an address outside the range if the canonicalization is incorrect
        rA   )rP   r[   r   s     r   decanonicalizezAArch64.decanonicalize  s/    
 1)A--..Kd,,,r   valuer   r   shiftc                 J    ||}d|dz   z  dz
  }d|z  dz
  }||z  }| |z  |z	  S )zAReturns the bits of a value between highbit and lowbit inclusive.NrA   r   )r   r   r   r   	high_masklow_maskr   s          r   rY   zAArch64._mask  sH    
 =E8a<(A-	LA%8#&&r   c                     | j         gS )zRReturns a list of the lower layer names that this layer is dependent
        upon.)rI   rk   s    r   dependencieszAArch64.dependencies  s      !!r   c                    t          j        dd          t          j        ddd          t          j        ddd          t          j        d	dd
          t          j        ddd          t          j        ddd          t          j        ddd          t          j        ddgddd          t          j        dddd          t          j        dddd          t          j        ddd          t          j        ddd          gS ) Nr:   F)r3   optionalr;   zJDTB of the target context (either "kernel space" or "user space process").)r3   r   descriptionr<   zDTB of the kernel space, it is primarily used to determine the target context of the layer (page_map_offset == page_map_offset_kernel). Conveniently calculated by LinuxStacker.r=   zeThe size offset of the memory region addressed by TTBR0_EL1. Conveniently calculated by LinuxStacker.r>   zeThe size offset of the memory region addressed by TTBR1_EL1. Conveniently calculated by LinuxStacker.r?   zRPage size used by the user address space. Conveniently calculated by LinuxStacker.r@   zTPage size used by the kernel address space. Conveniently calculated by LinuxStacker.littlebigr7   z!Kernel endianness (little or big))choicesr3   r   r   r8   TzLSpecify if debugging informations about the layer should be printed to user.)r3   r   r   defaultr9   zHSpecify if translation debugging informations should be printed to user.kernel_virtual_offsetzASLR offsetkernel_bannerz\Kernel unique identifier, including compiler name and version, kernel version, compile time.)r   TranslationLayerRequirementIntRequirementChoiceRequirementBooleanRequirementStringRequirementr   s    r   get_requirementszAArch64.get_requirements  s    4#e   '&h  
 '- O  
 '# D  
 '# D  
 '+p  
 '-r  
 *!5)(?	   +"j	   +(f	   ',t   *$z  o<
 <	
r   )N)r5   N)Frw   ):r   r   r   __doc__collectionsChainMapr
   r   TranslationLayerInterface_direct_metadatarZ   r   _maxphyaddrr   ry   r1   ContextInterfacestrr   r   r   rC   r\   classmethodrN   r   r   rU   r   rS   r   r~   r   r   r   rW   r   r   staticmethodr   property	functools	lru_cacher   r   r   r	   r   r   r   r   r   rY   r   configurationRequirementInterfacer   __classcell__)r^   s   @r   r   r   "   s        
 ,{+	#	43D  '1,N KL >==444***  .263 63#463 63 	63
 4S>*63 
63 63 63 63 63 63p   " 

36
CG
	s
 
 
 [
" ,/	eCj	   [$> >sC}1E > > > >\2s \2uS#s]7K \2 \2 \2 \2~ ?D*n *n*n#&*n7;*n	%S#sC/0	1*n *n *n *nZ ?DG% G%G%#&G%7;G%	%S#sC/0	1G% G% G% G%R$	s$ $ $ $" s C     Es Et E E E E 
'c 
'd 
' 
' 
' \
' Y/C / / /  X/ Y(3 ( ( (  X( Y$# $ $ $  X$ Y&# & & &  ]&
 Y     ] Y+ + + +  ]+O O O O O O-3 -3 - - - - HL	' 	'	'!	',/	'8@	'		' 	' 	' \	' "d3i " " " X"
 =
j&>&S!T =
 =
 =
 [=
 =
 =
 =
 =
r   r   )loggingr  r   typingr   r   r   r   r   r   volatility3r	   volatility3.frameworkr
   r   #volatility3.framework.configurationr   volatility3.framework.layersr   	getLoggerr   rh   LayerExceptionr   LinearlyMappedLayerr   r   r   r   <module>r     s+  
          = = = = = = = = = = = = = = = = % % % % % % 8 8 8 8 8 8 8 8 < < < < < < / / / / / /		8	$	$
	 	 	 	 	z0 	 	 	a
 a
 a
 a
 a
f( a
 a
 a
 a
 a
r   