
    Xf^H                        d 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mZmZ ddlmZ ddlmZ  ej        e          Z G d d          Z G d	 d
e          Z G d de          Z G d de          Z G d de          Z G d dej        j                  Z G d dej        j                  Z G d dej        j                  Z dS )a  Module to identify the Directory Table Base and architecture of windows
memory images.

This module contains a PageMapScanner that scans a physical layer to identify self-referential pointers.
All windows versions include a self-referential pointer in their Directory Table Base's top table, in order to
have a single offset that will allow manipulation of the page tables themselves.

In older windows version the self-referential pointer was at a specific fixed index within the table,
which was different for each architecture.  In very recent Windows versions, the self-referential pointer
index has been randomized, so a different heuristic must be used.  In these versions of windows it was found
that the physical offset for the DTB was always within the range of 0x1a0000 to 0x1b0000.  As such, a search
for any self-referential pointer within these pages gives a high probability of being an accurate DTB.

The self-referential indices for older versions of windows are listed below:

    +--------------+-------+
    | Architecture | Index |
    +==============+=======+
    | x86          | 0x300 |
    +--------------+-------+
    | PAE          | 0x3   |
    +--------------+-------+
    | x64          | 0x1ED |
    +--------------+-------+
    N)	GeneratorIterableListOptionalTupleType)	constants
interfaceslayers)requirements)intelc                       e Zd ZdZdeej        j                 dede	de
e	         de	ddfd	Zd
ede	de	deee	e	f                  fdZdS )DtbSelfReferentialzaA generic DTB test which looks for a self-referential pointer at *any*
    index within the page.
layer_type
ptr_structmaskvalid_rangereserved_bitsreturnNc                     || _         || _        t          j        |          | _        || _        |j        | _        || _        || _        d S N)	r   r   structcalcsizeptr_sizer   	page_sizer   r   )selfr   r   r   r   r   s         Y/home/panchajanya/Development/work/volatility3/volatility3/framework/automagic/windows.py__init__zDtbSelfReferential.__init__,   sJ     %$
33	(2&*    datadata_offsetpage_offsetc                    |||| j         z            }|sd S t                      }t          d| j         | j                  D ]v}|||| j        z            }t	          j        | j        |          \  }|| j        z  r|dz  r d S || j        z  ||z   k    r#||z   dk    r|dz  r|	                    |           wt          |          dk    r,|                                }	|	| j        z  | j        v r||z   |	fS d S )Nr      )r   setranger   r   unpackr   r   r   addlenpopr   )
r   r    r!   r"   page	ref_pagesrefptr_dataptrref_pages
             r   __call__zDtbSelfReferential.__call__<   s/    K+">>? 	4EE	DNDM:: 	' 	'CC#"556H]4?H==FS d(( sTz tttykK&?@@k)A-- : 'MM#&&& y>>Q }}HDM)d.>>>#k1H<<tr   )__name__
__module____qualname____doc__r   r   r   Intelstrintr   r   bytesr   r   r1    r   r   r   r   (   s         ++,+ + 	+
 c]+ + 
+ + + + (+:=	%S/	"     r   r   c                        e Zd Z fdZ xZS )DtbSelfRef32bitc                 t    t                                          t          j        j        dddgd           d S )NIl    p i   r   r   r   r   r   r   )superr   r   r   WindowsIntelr   	__class__s    r   r   zDtbSelfRef32bit.__init__[   sD    |0 	 	
 	
 	
 	
 	
r   r2   r3   r4   r   __classcell__rC   s   @r   r<   r<   Z   s8        
 
 
 
 
 
 
 
 
r   r<   c                         e Zd Zd fdZ xZS )DtbSelfRef64bitr   Nc           	          t                                          t          j        j        ddt          dd          d           d S )NQ    p   i     r?   )r@   r   r   r   WindowsIntel32er&   rB   s    r   r   zDtbSelfRef64bit.__init__f   sL    |3!eU++ 	 	
 	
 	
 	
 	
r   r   NrD   rF   s   @r   rH   rH   e   =        
 
 
 
 
 
 
 
 
 
r   rH   c                         e Zd Zd fdZ xZS )DtbSelfRef64bitOldWindowsr   Nc                 t    t                                          t          j        j        dddgd           d S )NrJ   rK   i  rM   r?   )r@   r   r   r   rN   rB   s    r   r   z"DtbSelfRef64bitOldWindows.__init__q   sD    |3! 	 	
 	
 	
 	
 	
r   rO   rD   rF   s   @r   rR   rR   p   rP   r   rR   c                   n     e Zd Zd	 fdZed             Zdedededee	eef                  f fdZ
 xZS )
DtbSelfRefPaer   Nc                 t    t                                          t          j        j        ddgdd           d S )NrJ      rK   r   )r   r   r   r   r   )r@   r   r   r   WindowsIntelPAErB   s    r   r   zDtbSelfRefPae.__init__|   sD    |3! 	 	
 	
 	
 	
 	
r   c           
          t          d t          | d d d         |d d d                   D             d d d                   S )Nc                     g | ]
\  }}||z  S r:   r:   ).0abs      r   
<listcomp>z,DtbSelfRefPae._and_bytes.<locals>.<listcomp>   s     HHH1a!eHHHr   )r9   zip)abytesbbytess     r   
_and_byteszDtbSelfRefPae._and_bytes   sH    HHF44R4L&2,(G(GHHH2NOOOr   r    r!   r"   c                 V   	 t                                          |||          }|r|d         dz
  	d                     	fdt          dd          D                       }d}|	|z
  	|z
  d j        z  z            }                     ||          }||k    r
	|d         fS d S |S )	Nr    @  r   c                 P    g | ]"}t          j        j        |d z  z             #S )   )r   packr   )r[   ir   top_pae_pages     r   r^   z*DtbSelfRefPae.__call__.<locals>.<listcomp>   s@        KV1LMM  r   r$      s           )r@   r1   joinr&   r   rc   )r   r    r!   r"   dtbexpected_tablepage_table_mask
page_tableanded_bytesrj   rC   s   `        @r   r1   zDtbSelfRefPae.__call__   s     ggt[+>> 	q6F?L !XX    "1a[[   N FO ,!t}$!&&J //*oFFKn,,#SV++4
r   rO   )r2   r3   r4   r   staticmethodrc   r9   r8   r   r   r1   rE   rF   s   @r   rU   rU   {   s        
 
 
 
 
 
 P P \P(+:=	%S/	"         r   rU   c            	            e Zd ZdZdZdZ e             e             e            gZ		 de
ee                  ddf fdZded	edeeeef         ddf         fd
Z xZS )PageMapScannerzWScans through all pages using DTB tests to determine a dtb offset and
    architecture.re   Ttestsr   Nc                 ^    t                                                       |r	|| _        d S d S r   )r@   r   rv   )r   rv   rC   s     r   r   zPageMapScanner.__init__   s6     	DJJJ	 	r   r    r!   c              #      K   t          dt          |          d          D ]'}| j        D ]} ||||          }|||d         fV  (d S )Nr   rg   )r&   r)   rv   )r   r    r!   r"   testresults         r   r1   zPageMapScanner.__call__   sx       !CIIv66 	, 	,K
 , ,dK==%++++,	, 	,r   )r2   r3   r4   r5   overlapthread_saferH   rU   r<   rv   r   r   r   r   r9   r8   r   r   r1   rE   rF   s   @r   ru   ru      s          GK_1B1BCE:ht,>'?@ T      
,,(+,	5+S014=	>, , , , , , , ,r   ru   c                       e Zd ZdZddgZd e            gddgfd e             e             e            gdgfgZ	e
	 dd
ej        j        dedej        deej        j                 fd            Zd	S )WindowsIntelStacker(   maclinuxz5Detecting Self-referential pointer for recent windows)   r   )i  e i  
 z6Older windows fixed location self-referential pointers)i   i   Ncontext
layer_nameprogress_callbackr   c                    |j         |         }t          |t          j                  rdS |j                            dd          dvrdS dx}}|j                            dd          dk    r|j                            d          rd|j                            dd          }|dvrdS t          j        }|dk    rt          j        }n'|j                            d	d
          rt          j        }|j         	                    d          }	t          j                            d|	          }||j        t          j                            |d          <   |j        d         |j        t          j                            |d          <    ||||	ddi          }|j        t          j                            |d                   }
t                              dt!          |
                      |S | j        D ]\  }}t                              |           |                    |t'                    ||          }fd}dt(          fd}t+          t-          |          |          }|D ]v\  }}
|                    |
d          }t1          j        |j                  } ||||          }||j        k    rt                              |j        j         dt!          |
                      |j         	                    d          }	t          j                            d|	          }||j        t          j                            |d          <   |
|j        t          j                            |d          <   |                    |||	ddi          } nNt                              d|j        j         dt!          |           dt!          |j                              x||r n|X|rVt                              d                    |j        t          j                            |d                                        |S )ac  Attempts to determine and stack an intel layer on a physical layer
        where possible.

        Where the DTB scan fails, it attempts a heuristic of checking
        for the DTB within a specific range. New versions of windows,
        with randomized self-referential pointers, appear to always load
        their dtb within a small specific range (`0x1a0000` and
        `0x1b0000`), so instead we scan for all self-referential
        pointers in that range, and ignore any that contain multiple
        self-references (since the DTB is very unlikely to point to
        itself more than once).
        Nos)WindowsUnknownr   page_map_offsetarchitecture)Intel32Intel64r   paeF
IntelLayerIntelHelpermemory_layer)config_pathnamemetadataz#DTB was given to us by base layer: )rv   )sectionsr   c                 J                         | d                   | d         fS )zKey used to sort by testsr   r$   )index)xrv   s    r   sort_by_testsz0WindowsIntelStacker.stack.<locals>.sort_by_tests  s"    {{1Q4((!A$..r   r   c                     d}t          dt          |           |          D ]Z}t          j        |j        | |||z                      d         }|dz  r(|dz  s#t          |||dz  z  |j        j        z            }[|S )z&Determines a pointer from a page_tabler   r$   rM   i  )r&   r)   r   r'   r   maxr   maximum_address)rq   ry   r   max_ptrr   pointers         r   get_max_pointerz2WindowsIntelStacker.stack.<locals>.get_max_pointer!  s    "1c*oox@@ 
 
E$mEEH<L4L)M G } Wt^ "%#$%8"o=># #
 r   )keyrg   z test succeeded at zMax pointer for hit with test z
 not met: z > zDTB was found at: 0x{:0x}) r   
isinstancer   r6   r   getrA   rN   rX   free_layer_namer
   configuration	path_joinconfigvollogdebughex	test_setsscanru   r8   sortedlistreadr   r   r   r   rC   r2   r   format)clsr   r   r   
base_layerlayerr   archr   new_layer_namer   descriptionr   hitsr   r   ry   rq   r   max_pointerrv   s                       @r   stackzWindowsIntelStacker.stack   s   & ^J/
j%+.. 	4""4..6LLL4"" ""4..);;
@S@W@WA
 A
; &**>4@@D111t$1Jy  "2

$((66 3"2
$^;;LIIN$2<<~ K
  N(22;OO
 #$56 N(22;@QRR J'#	*	  E &n(22;@QRRO LLUs??S?SUUVVVL -0M C	 C	(KLL%%%??U+++!"3	 #  D/ / / / /C      $t**-888D)-    %o'___fEE
!?4?;;-oj$II*"<<<LL>2]]s?G[G[]]   &-^%C%CL%Q%QN",":"D"D%~# #K
 # N"0::;WW (	 N"0::'): 
 !OO$/+"&	!2	 ,  E ELL S9P  S  S\_`k\l\l  S  Sqtu  vP  rQ  rQ  S  S     [ LL+22N"0::'):     r   r   )r2   r3   r4   stack_orderexclusion_listrH   rU   r<   rR   r   classmethodr
   r   ContextInterfacer7   r	   ProgressCallbackr   r   DataLayerInterfacer   r:   r   r   r~   r~      s        KW%N
 D_!#67	
 E]__oo//1J1J1L1LM!"	
I 
 9=	M M#4M M %5	M
 
*#6	7M M M [M M Mr   r~   c                       e Zd ZdZddgZ	 ddej        j        dedej	        j
        dej        d	df
d
Zededej        d	eeeej                 f         fd            Zed	eej	        j
                 fd            ZdS )WinSwapLayersz~Class to read swap_layers filenames from single-swap-layers, create the
    layers and populate the single-layers swap_layers.r   r   Nr   r   requirementr   r   c                    t           j        j        }|                     |||t          j        d          | _        | j        D ]\  }}t          |t          j                  s!|                     ||          \  }}	d}
t           j        	                    |          }|	rB|	
                    ||          r+| j                            dg           D ]}|	j        t          |
          z   } |||          } ||d          } ||d          }|
dz  }
|rk||j        |<   	 t          j                            |          |j        |<   n.# t"          $ r! t$                              d| d	           Y w xY wd
|j        |<   t	          j        |dd          }|	                    |           |
|j         ||d          <   d|j        |<   |	                    ||           dS )z9Finds translation layers that can have swap layers added.F)shortcutr   single_swap_locationslocationclassr$   zVolatility swap_location z- could not be validated - swap layer disabledz/volatility3.framework.layers.physical.FileLayerz
Swap Layer)r   r   optionalnumber_of_elementsTN)r
   r   r   find_requirementsr   TranslationLayerRequirement_translation_requirementr   find_swap_requirementparent_pathunsatisfiedr   r   r   r7   URIRequirementlocation_from_file
ValueErrorr   warningadd_requirement	construct)r   r   r   r   r   r   trans_sub_config	trans_reqswap_sub_configswap_reqcounterswap_configswap_locationcurrent_layer_namecurrent_layer_pathlayer_loc_pathlayer_class_pathnew_reqs                     r   r1   zWinSwapLayers.__call__j  si    ,6	(,(>(>4 )? )
 )
% ,0+H 5	9 5	9'ii)QRR (,(B(B )) )%OX G$2>>OOK *9H00+FF *9 &*[__5Lb%Q%Q  6  6M)1W)E&)2?DV)W)W&%.Y/A:%N%NN'0y1CW'M'M$qLG % =O'9:
% , ; N N$1!" !" $N>::
  * % % %"NN xM x x x   %H	% N  '78
 +F/$0!&  G
 ,,W5555  yy:NOOP 37/""7K888k5	9 5	9s   !'E		(E43E4r   c                     d}|j         D ]7}|j         |         }t          |t           j                  r|j        dk    r|}78t          j                            | d          }||fS )zATakes a Translation layer and returns its swap_layer requirement.Nswap_layers)r   r   LayerListRequirementr   r
   r   r   )r   r   r   req_namereqr   s         r   r   z#WinSwapLayers.find_swap_requirement  sv    
 #0 	 	H*84C3 ABBH-- .88OOH$$r   c                 B    t          j        dt          dddd          gS )z(Returns the requirements of this plugin.r   r      z@Specifies a list of swap layer URIs for use with single-locationT)r   element_typemin_elementsmax_elementsr   r   )r   ListRequirementr7   )r   s    r   get_requirementszWinSwapLayers.get_requirements  s5     (, ^  	
 		
r   r   )r2   r3   r4   r5   r   r
   r   r   r7   r   RequirementInterfacer	   r   r1   rs   r   r   r   r   r   r   r   r   r   r:   r   r   r   r   d  s       : : u%N 9=F9 F9#4F9 F9  -B	F9
 %5F9 
F9 F9 F9 F9P %%"."J%	sH\>??	@% % % \%" 
j&>&S!T 
 
 
 [
 
 
r   r   )!r5   loggingr   typingr   r   r   r   r   r   volatility3.frameworkr	   r
   r   #volatility3.framework.configurationr   volatility3.framework.layersr   	getLoggerr2   r   r   r<   rH   rR   rU   ScannerInterfaceru   	automagicStackerLayerInterfacer~   AutomagicInterfacer   r:   r   r   <module>r      s*   2   C C C C C C C C C C C C C C C C ? ? ? ? ? ? ? ? ? ? < < < < < < . . . . . .		8	$	$/ / / / / / / /d
 
 
 
 
( 
 
 

 
 
 
 
( 
 
 

 
 
 
 
 2 
 
 
+ + + + +& + + +\, , , , ,Z&7 , , ,0` ` ` ` `*.D ` ` `Fl
 l
 l
 l
 l
J(; l
 l
 l
 l
 l
r   