
    [
#g_G                     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
 d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ  ej0                  e      Ze G d
 d             Ze G d d             Z G d dej:                  ej<                        Z G d dej:                        Z y)    N)	dataclassastuple)ListSetTypeIterable)	renderers
interfaces)format_hints)plugins)requirements)	timeliner)	mountinfoc                       e Zd ZU dZeed<   eed<   eed<   eed<   eed<   eed<   eed<   eed	<   eed
<   eed<   eed<   eed<   eed<   y)	InodeUserzInode user representation, featuring augmented information and formatted fields.
    This is the data the plugin will eventually display.
    superblock_addr
mountpointdevice	inode_num
inode_addrtypeinode_pagescached_pages	file_modeaccess_timemodification_timechange_timepathN)__name__
__module____qualname____doc__int__annotations__str     _/home/panchajanya/Development/work/volatility3/volatility3/framework/plugins/linux/pagecache.pyr   r      sP     OKNO
IN
Ir'   r   c                       e Zd ZU dZej
                  j                  ed<   eed<   ej
                  j                  ed<   eed<   dej                  j                  defdZy	)
InodeInternalzInode internal representation containing only the core objects

    Fields:
        superblock: 'super_block' struct
        mountpoint: Superblock mountpoint path
        inode: 'inode' struct
        path: Dentry full path
    
superblockr   inoder   kernel_layerreturnc                    | j                   j                  j                  }| j                   j                   d| j                   j                   }t        | j                  j                        }| j                  j                  j                  }| j                  j                         xs t        j                         }t        t        j                  | j                  j                  t        |j                        z              }t        | j                  j                   j"                        }| j                  j%                         }	| j                  j'                         }
| j                  j)                         }| j                  j+                         }t-        || j.                  |||||||	|
||| j0                        }|S )zAugment the inode information to be presented to the user

        Args:
            kernel_layer: The kernel layer to obtain the page size

        Returns:
            An InodeUser dataclass
        :)r   r   r   r   r   r   r   r   r   r   r   r   r   )r+   voloffsetmajorminorr#   r,   i_inoget_inode_typer	   UnparsableValuemathceili_sizefloat	page_size	i_mappingnrpagesget_file_modeget_access_timeget_modification_timeget_change_timer   r   r   )selfr-   r   r   r   r   
inode_typer   r   r   access_time_dtmodification_time_strchange_time_str
inode_users                 r(   to_userzInodeInternal.to_user:   sW    //--44OO))*!DOO,A,A+BC

(()	ZZ^^**
ZZ..0OI4M4M4O
$))DJJ$5$5l>T>T8U$UVW4:://778JJ,,.	335 $

 @ @ B**446+!#%&3'

 r'   N)r   r    r!   r"   r
   objectsObjectInterfacer$   r%   layersTranslationLayerInterfacer   rI   r&   r'   r(   r*   r*   *   sX     ""222O---
I)&--GG)	)r'   r*   c                   \   e Zd ZdZdZdZedeej                  j                     fd       Zedej                  j                  dedefd       Zed	ee   d
ej                  j                  defd       Zedej(                  j*                  dedee   fd       Zd Zd Zed        Zd Zy)FileszLists files from memory   r   r      r   r   r.   c                     t        j                  ddddg      t        j                  dt        j                  d      t        j
                  d	d
t        d      t        j                  ddd      gS )NkernelLinux kernelIntel32Intel64namedescriptionarchitecturesr   )rS   rQ   r   rZ   pluginversionr   z=List of space-separated file type filters i.e. --type REG DIRT)rZ   r[   element_typeoptionalfindzFilename (full path) to findrZ   r[   ra   )r   ModuleRequirementPluginRequirementr   	MountInfoListRequirementr%   StringRequirementclss    r(   get_requirementszFiles.get_requirementsm   s|     ***()4
 ** )<)<i (([ 	 **:
 	
r'   r,   symlink_pathc                     | r]| j                   rQ| j                  d      r@| j                  r4| j                  j                         j	                  dddd      }| d| }|S )av  Follows (fast) symlinks (kernels >= 4.2.x).
        Fast symlinks are filesystem agnostic.

        Args:
            inode: The inode (or pointer) to dump
            symlink_path: The symlink name

        Returns:
            If it can resolve the symlink, it returns a string "symlink_path -> target_path"
            Otherwise, it returns the same symlink_path
        i_linkstring   zutf-8replace)
max_lengthencodingerrorsz -> )is_link
has_memberrn   dereferencecast)r,   rl   
i_link_strs      r(   _follow_symlinkzFiles._follow_symlink   sc    " U]]u'7'7'Aell11388S79 9 J +^4
|<Lr'   seen_dentriesroot_dentry
parent_dirc              #     K   |j                         D ]  }|j                  j                  }||j                  j                  k(  r3||v r8|j                  |       |j                  }|r|j                         sh|j                  j                  r#|j                  j                         }|dz   |z   }n||f |j                  s| j                  |||      E d{     y7 w)a:  Walks dentries recursively

        Args:
            seen_dentries: A set to ensure each dentry is processed only once
            root_dentry: Root dentry object
            parent_dir: Parent directory path

        Yields:
           file_path: Filename including path
           dentry: Dentry object
        /)r}   N)get_subdirsr1   r2   addd_inodeis_validd_namerZ   name_as_stris_dir_walk_dentry)	rj   r{   r|   r}   dentrydentry_addrr,   basename	file_paths	            r(   r   zFiles._walk_dentry   s     & "--/F **++K koo444m+k*NNEenn. }}!!!==446&,x7	V##||++M6i+XXX7 06 Ys   CC)C)C' C)contextvmlinux_module_namec              #     K   t         j                  j                  ||      }t               }t               }|D ]#  \  }}|dk(  rdn|}|j                  }	|	s|	j                         }
|
j                         s@|
j                  }|sO|j                         }|j                         sp||v ru|j                  |       |}t        ||||      }| | j                  ||
|      D ]s  \  }}|s	|j                  }|s|j                         }|j                         s9||v r>|j                  |       | j                  ||      }t        ||||      }| u & yw)a  Retrieves the inodes from the superblocks

        Args:
            context: The context that the plugin will operate within
            vmlinux_module_name: The name of the kernel module on which to operate

        Yields:
            An InodeInternal object
        r   r   r    )r+   r   r,   r   N)r   rf   get_superblockssets_rootrw   is_rootr   r   r   r*   r   rz   )rj   r   r   superblocks_iterseen_inodesr{   r+   r   r}   root_dentry_ptrr|   root_inode_ptr
root_inode	root_pathinode_inr   file_dentryfile_inode_ptr
file_inodes                      r(   
get_inodeszFiles.get_inodes   s      %..>> 3 ? 

 e&6"J
)S0jJ )//O")557K &&( )00N!'335J&&( ,OON+"I$%% 	H N +.*:*:{J+&	; #!,!4!4%+779
!**, "[0///	J	())$"	 3+M '7s   E E"c              #   "  K   | j                   d   }| j                  j                  |   }| j                  j                  |j                     }| j                  | j                  |      }| j                   d   }|D ]  }|r|j                  j                         |vr"| j                   d   r?|j                  | j                   d   k(  sN|j                  |      }dt        |      f  y |j                  |      }dt        |      f  y w)NrU   r   r   rb   r   )configr   modulesrL   
layer_namer   r,   r6   r   rI   r   )rC   r   vmlinuxvmlinux_layerinodes_itertypes_filterr   	inode_outs           r(   
_generatorzFiles._generator&  s     "kk(3,,&&':;++G,>,>?ooLL 3 & 

 {{6*#H = = ?| S{{6"==DKK$77 ( 0 0 ?Igi011$,,];	'),-- $s   CD
ADc              #      K   | j                   d   }| j                  j                  |   }| j                  j                  |j                     }| j                  | j                  |      }|D ]  }|j                  |      }d|j                   }|t        j                  j                  |j                  f |t        j                  j                  |j                  f |t        j                  j                  |j                  f  yw)zGenerates tuples of (description, timestamp_type, timestamp)

        These need not be generated in any particular order, sorting
        will be done later
        rU   r   zCached Inode for N)r   r   r   rL   r   r   rI   r   r   TimeLinerTypeACCESSEDr   MODIFIEDr   CHANGEr   )rC   r   r   r   r   r   r   r[   s           r(   generate_timelinezFiles.generate_timeline>  s      #kk(3,,&&':;++G,>,>?ooLL 3 & 

 $H ((7I-inn-=>Ky66??AVAVVVy66??A\A\\\y66==y?T?TTT $s   DDc              #      K   |D ]h  \  }}g }t        | |      D ]L  \  }}|d   }t        ||t        j                  j                  f      r|}n ||      }|j                  |       N ||f j yw)zDUses the headers type to cast the fields obtained from the generatorrS   N)zip
isinstancer
   r	   BaseAbsentValueappend)	headers	generatorlevelfieldsformatted_fieldsheaderfieldheader_typeformatted_fields	            r(   format_fields_with_headersz Files.format_fields_with_headersT  s      'ME6!!$Wf!5$QiK)=)=)M)MN ',O&1%&8O ''8 "6 ))) 's   A/A1c                    dt         j                  fdt        fdt        fdt        fdt         j                  fdt        fdt        fdt        fd	t        fd
t        j                  fdt        j                  fdt        j                  fdt        fg}t        j                  || j                  || j                                     S )NSuperblockAddr
MountPointDeviceInodeNum	InodeAddrFileType
InodePagesCachedPagesFileMode
AccessTimeModificationTime
ChangeTimeFilePath)	r   Hexr%   r#   datetimer	   TreeGridr   r   rC   r   s     r(   runz	Files.runf  s    |//03sO,**+3C 8,,-!2!238,,-
  !!T44Wdoo>OP
 	
r'   N)r   r    r!   r"   _required_framework_version_versionclassmethodr   r
   configurationRequirementInterfacerk   staticmethodrJ   rK   r%   rz   r   r#   r   r   ContextInterfacer   r*   r   r   r   r   r   r&   r'   r(   rO   rO   f   s%   !"+H
j&>&>&S&S!T 
 
. !!11 
 0 -Y3x-Y  ''77-Y 	-Y -Y^ U##44U !U 
-	 	U Un.0U, * *"
r'   rO   c                      e Zd ZdZdZdZedeej                  j                     fd       Zedej                  j                  dedeej"                  j$                     d	ej&                  j(                  dd
f
d       Zd Zd Zy
)r   z%Lists and recovers cached inode pagesrP   rR   r.   c           	          t        j                  ddddg      t        j                  dt        d      t        j                  d	d
d      t        j
                  ddd      t        j                  ddd      gS )NrU   rV   rW   rX   rY   filesrR   r]   rb   zFilename (full path) to find Trc   r,   zInode addressdumpzOutput file path)r   rd   re   rO   rh   IntRequirementri   s    r(   rk   zInodePages.get_requirements  s     ***()4
 **UI **;
 ''+
 **.'
 	
r'   r,   filenameopen_methodr   Nc                 :   | j                   st        j                  d       y	  ||      5 }| j                  }|j	                  |       | j                         D ]}  \  }}||j                  z  }||z
  }	|d|	 }
|t        |
      z   |kD  r,t        j                  d| j                  j                  ||       |j                  |       |j                  |
        	 ddd       y# 1 sw Y   yxY w# t        $ r!}t        j                  d||       Y d}~yd}~ww xY w)aE  Extracts the inode's contents from the page cache and saves them to a file

        Args:
            inode: The inode to dump
            filename: Filename for writing the inode content
            open_method: class for constructing output files
            vmlinux_layer: The kernel layer to obtain the page size
        The inode is not a regular fileNzAPage out of file bounds: inode 0x%x, inode size %d, page index %dz Unable to write to file (%s): %s)is_regvollogerrorr:   truncateget_contentsr<   lenr1   objectseekwriteIOError)r,   r   r   r   f
inode_sizepage_idxpage_content
current_fprr   
page_byteses               r(   write_inode_content_to_filez&InodePages.write_inode_content_to_file  s    ||LL:;	JX& (!"\\


:&.3.@.@.B*Hl!)M,C,C!CJ!+j!8J!-kz!:J!C
O3j@_!II,,&$	 FF:&GGJ' /C	( ( ($  	JLL;XqII	Js5   C0 B.C$C0 $C-)C0 -C0 0	D9DDc           
   #   t  K   | j                   d   }| j                  j                  |   }| j                  j                  |j                     }| j                   d   r%| j                   d   rt
        j                  d       y | j                   d   rSt        j                  | j                  |      }|D ],  }|j                  | j                   d   k(  s |j                  } nI nG| j                   d   r"|j                  d| j                   d   d      }nt
        j                  d       y j                  st
        j                  d	       y |j                  }|j                         s$t
        j                  d
| j                   d          y |j                         D ]  }|j                   j"                  }	|j%                         }
|j&                  }t)        |j*                        }||j,                  z  }||k  }|j/                         }dj1                  |D cg c]  }|j3                  dd       c}      }|	|
||||f}d|f  | j                   d   rY| j                   d   }t
        j5                  d|j                   j"                  |       | j7                  ||| j8                  |       y y c c}w w)NrU   r,   rb   z,Cannot use --inode and --find simultaneouslyr   T)absolutez%You must use either --inode or --findr   zInvalid inode at 0x%x,PG_r   r   r   z![*] Writing inode at 0x%x to '%s')r   r   r   rL   r   r   r   rO   r   r   r,   r   r   r:   r   	get_pagesr1   r2   to_paddrmappingr#   indexr<   get_flags_listjoinrq   infor   open)rC   r   r   r   r   r   r,   r   page_obj
page_vaddr
page_paddrpage_mapping_addr
page_indexpage_file_offset	dump_safepage_flags_listx
page_flagsr   r   s                       r(   r   zInodePages._generator  sV    "kk(3,,&&':;++G,>,>?;;wDKK$7LLGH;;v**$7 + K (==DKK$77$NNE (
 [[!NN7DKK,@4NPELL@A||LL:;\\
~~LL0$++g2FG)H!,,J!**,J ( 0 0X^^,J)M,C,CC(:5I&557O"QA199UB#7"QRJ!F V)O% *( ;;v{{6*HKK;UYY=M=MxX,,UHdiiW  #Rs   CJ8EJ8J3
3BJ8c                    dt         j                  fdt         j                  fdt         j                  fdt        fdt        fdt        fg}t        j                  |t        j                  || j                                     S )N	PageVAddr	PagePAddrMappingAddrIndexDumpSafeFlags)
r   r   r#   boolr%   r	   r   rO   r   r   r   s     r(   r   zInodePages.run  sw    ,**+,**+L,,-cNcN
 !!U55gt?PQ
 	
r'   )r   r    r!   r"   r   r   r   r   r
   r   r   rk   r   rJ   rK   r%   r   r   FileHandlerInterfacerL   rM   r   r   r   r&   r'   r(   r   r   |  s    /"+H
j&>&>&S&S!T 
 
6 *J!!11*J*J *,,AAB*J "((BB	*J
 
*J *JX9Xv
r'   r   )!r8   loggingr   dataclassesr   r   typingr   r   r   r   volatility3.frameworkr	   r
   volatility3.framework.renderersr    volatility3.framework.interfacesr   #volatility3.framework.configurationr   volatility3.pluginsr   volatility3.plugins.linuxr   	getLoggerr   r   r   r*   PluginInterfaceTimeLinerInterfacerO   r   r&   r'   r(   <module>r     s   
    * , , 7 8 4 < ) /			8	$   ( 8 8 8vS
G##Y%A%A S
lW
(( W
r'   