
    *1f4P                     v   d dl Z d dlZd dlmZmZ d dlmZ d dlmZm	Z	m
Z
mZ d dlmZmZmZmZmZ d dlmZ d dlmZ  ej        e          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          Z G d de          Z G d dej        j                   Z!dS )    N)ABCabstractmethod)Enum)	GeneratorIteratorListTuple)class_subclasses	constants
exceptions
interfaces	renderers)requirements)utilityc                   "    e Zd ZdZdZdZdZdZdS )DescStateEnumr            N)__name__
__module____qualname__	desc_missdesc_reserveddesc_committeddesc_finalizeddesc_reusable     Z/home/panchajanya/Development/work/volatility3/volatility3/framework/plugins/linux/kmsg.pyr   r      s'        IMNNMMMr    r   c                      e Zd ZdZdZdZdej        j        dej	        j
        fdZedej        j        dej	        j
        deeeeeeef                  fd            Zedeeeeeeef                  fd	            Zeed
ej        j        defd                        ZdededefdZdedefdZdefdZd Zd Zdeeeeef         fdZededefd            Zededefd            ZdS )ABCKmsgKernel log buffer reader)emergalertcriterrwarnnoticeinfodebug)kernusermaildaemonauthsysloglprnewsuucpcronauthprivftpcontextconfigc                     || _         || _        |j        | j        d                  | _        | j        j        | _        | j                            d          j        | _        d S )Nkernelzlong unsigned int)_context_configmodulesvmlinux
layer_nameget_typesizelong_unsigned_int_size)selfr9   r:   s      r!   __init__zABCKmsg.__init__<   sU    
  t|H'=>,1&*l&;&;<O&P&P&U###r    returnc              #     K   |j         |d                  }d}t          |           D ]}|                    |          s,t                              t
          j        d|j                   Dt                              t
          j        d|j                    |||          }|                                E d{V   |t          	                    d           dS dS )a3  It calls each subclass symtab_checks() to test the required
        conditions to that specific kernel implementation.

        Args:
            context: The volatility3 context on which to operate
            config: Core configuration

        Yields:
            The kmsg records. Same as run()
        r<   N)r@   z7Kmsg implementation '%s' doesn't match this memory dumpz!Kmsg implementation '%s' matches!r9   r:   z-Unsupported kernel ring buffer implementation)
r?   r
   symtab_checksvolloglogr   LOGLEVEL_VVVVr   runerror)clsr9   r:   r@   	kmsg_instsubclasss         r!   run_allzABCKmsg.run_allG   s        /&"23	(-- 	 	H))'):: 

+M%  
 JJ'3!  
 !@@@I }}&&&&&&& LLHIIIII r    c                     dS )a  Walks through the specific kernel implementation.

        Returns:
            tuple:
                facility [str]: The log facility: kern, user, etc. See FACILITIES
                level [str]: The log level: info, debug, etc. See LEVELS
                timestamp [str]: The message timestamp. See nsec_to_sec_str()
                caller [str]: The caller ID: CPU(1) or Task(1234). See get_caller()
                line [str]: The log message.
        Nr   rE   s    r!   rN   zABCKmsg.runq         r    r@   c                     dS )ap  This method on each sublasss will be called to evaluate if the kernel
        being analyzed fulfill the type & symbols requirements for the implementation.
        The first class returning True will be instantiated and called via the
        run() method.

        Returns:
            bool: True if the kernel being analyzed fulfill the class requirements.
        Nr   rP   r@   s     r!   rJ   zABCKmsg.symtab_checks~   rV   r    addrlengthc                     | j         j        | j                                     ||          }|                    dd          S )Nutf8replace)encodingerrors)r=   layersrA   readdecode)rE   rY   rZ   txts       r!   
get_stringzABCKmsg.get_string   s9    m"4?388vFFzz6)z<<<r    nsecc                 "    d|dz  |dz  dz  fz  S )Nz	%lu.%06lui ʚ;i  r   )rE   re   s     r!   nsec_to_sec_strzABCKmsg.nsec_to_sec_str   s#     dZ/$2Ct1KLLLr    c                 6    |                      |j                  S N)rg   ts_nsecrE   objs     r!   get_timestamp_in_sec_strz ABCKmsg.get_timestamp_in_sec_str   s    ##CK000r    c                     |                     d          r|                     |j                  S t          j                    S )N	caller_id)
has_memberget_caller_textro   r   NotAvailableValuerk   s     r!   
get_callerzABCKmsg.get_caller   s=     >>+&& 	1''666.000r    c                 ,    |dz  rdnd}d||dz  fz  }|S )Nl        CPUTaskz%s(%u)l    r   )rE   ro   caller_namecallers       r!   rq   zABCKmsg.get_caller_text   s.    (:5Aee6[)k*ABBr    c                 n    |j         |j        |                     |          |                     |          fS ri   )facilitylevelrm   rs   rk   s     r!   
get_prefixzABCKmsg.get_prefix   s8     LI))#..OOC  	
 	
r    r{   c                     |t          | j                  k     r| j        |         S t                              d| d           t	          |          S )NzLevel  unknown)lenLEVELSrK   r,   str)rP   r{   s     r!   get_level_textzABCKmsg.get_level_text   sL    3sz??"":e$$LL1%111222u::r    rz   c                     |t          | j                  k     r| j        |         S t                              d| d           t	          |          S )Nz	Facility r~   )r   
FACILITIESrK   r,   r   )rP   rz   s     r!   get_facility_textzABCKmsg.get_facility_text   sN    c#.))))>(++LL7X777888x== r    N)r   r   r   __doc__r   r   r   r9   ContextInterfaceconfigurationHierarchicalDictrF   classmethodr   r	   r   rS   r   rN   ModuleInterfaceboolrJ   intrd   rg   rm   rs   rq   r|   r   r   r   r    r!   r#   r#      sN       ""	FJ	V#4	V (9	V 	V 	V 	V 'J#4'J (9'J 
%S#sC/0	1	'J 'J 'J ['JR 
XeCc3$;<= 
 
 
 ^
 J$6$F 4    ^ [=s =C =C = = = =
MC 
MC 
M 
M 
M 
M1s 1 1 1 11 1 1  

sCc'9!: 
 
 
 
 3 3    [ ! ! ! ! ! [! ! !r    r#   c                   \    e Zd ZdZedefd            Zdeee	e	e	e	e	f                  fdZ
dS )Kmsg_pre_3_5zThe kernel ring buffer (log_buf) is a char array that sequentially stores
    log lines, each separated by newline (LF) characters. i.e:

        <6>[ 9565.250411] line1!\n<6>[ 9565.250412] line2\n...

    rG   c                     |                     d          oS|                     d           o=|                    d          o'|                    d                              d           S )Nlog_endlog_first_idxrL   rj   )
has_symbolhas_typerB   rp   rX   s     r!   rJ   zKmsg_pre_3_5.symtab_checks   su     y)) &&777   '' B$$U++66yAA	
r    c              #   p  K   | j                             d          }| j                             d          }t          j        ||          }| j                             d          }||k    r||z
  }||d          }|d |         }||z   }|                                }|D ]}	t          j        d|	          }
|
s|
                                \  }}}t          |          }|dz  }|dz	  }| 	                    |          }| 
                    |          }t          j                    }|||||fV  d S )	Nlog_buf)symbol_namelog_buf_len)countr   z <(\d+)>\[\s*(\d+\.\d+)\]\s(.*?)$   r   )r@   object_from_symbolr   pointer_to_string
splitlinesrematchgroupsr   r   r   r   rr   )rE   log_buf_ptrr   r   r   start
first_halfsecond_halflog_buf_lineslog_buf_linemlevel_facility_strtimestamp_strlinelevel_facilityr{   rz   	level_txtfacility_txtrx   s                       r!   rN   zKmsg_pre_3_5.run   sn     l55)5LLl55-5PP+K{KKK,11i1HH[  k)E J!&5&/K ;.G**,,) 	G 	GL<lKKA  67hhjj3t !344N"Q&E%*H++E22I11(;;L022F	=&$FFFFF!	G 	Gr    N)r   r   r   r   r   r   rJ   r   r	   r   rN   r   r    r!   r   r      s|          
t 
 
 
 [
GXeCc3$;<= G G G G G Gr    r   c                       e Zd ZdZedefd            Zd ZdefdZ	de
eddf         fdZde
eddf         fdZdeeeeeeef                  fd	ZdS )
Kmsg_3_5_to_3_11zWhile 'log_buf' is declared as a pointer and '__log_buf' as a char array,
    it essentially holds an array of 'log' structs.
    rG   c                     |                     d          o<|                    d                              d          o|                    d          S )NrL   rj   r   )r   rB   rp   r   rX   s     r!   rJ   zKmsg_3_5_to_3_11.symtab_checks   sT     U## 4  ''229==4""?33	
r    c                     dS )NrL   r   rU   s    r!   _get_log_struct_namez%Kmsg_3_5_to_3_11._get_log_struct_name  s    ur    c                     |                                  }| j                            |          j        }|j        j        |z   }|                     ||j                  S ri   )r   r@   rB   rC   voloffsetrd   text_len)rE   msglog_struct_namelog_struct_size
msg_offsets        r!   get_text_from_logz"Kmsg_3_5_to_3_11.get_text_from_log
  sO    3355,//@@EW^o5
z3<888r    Nc              #      K   |j         dk    r1|                     |          }|                                E d {V  d S d S )Nr   )r   r   r   )rE   r   texts      r!   get_log_lineszKmsg_3_5_to_3_11.get_log_lines  sV      <!))#..D((((((((((( r    c              #   z  K   |j         dk    rd S |                                 }| j                            |          j        }|j        j        |z   |j        z   }| j        j	        | j
                                     ||j                   }|                    d          D ]}d|                                z   V  d S )Nr        )dict_lenr   r@   rB   rC   r   r   r   r=   r`   rA   ra   splitrb   )rE   r   r   r   dict_offset	dict_datachunks          r!   get_dict_lineszKmsg_3_5_to_3_11.get_dict_lines  s      <143355,//@@Egn6EM(9>>
 
	 __W-- 	' 	'E&&&&&	' 	'r    c              #     K   | j                             d          }| j                             d          }t          | j                             d                    }t          | j                             d                    }|                                 }|}||k     r|}n|}||k     r||z   }| j                             ||          }	|	j        dk    rd}|}n|                     |	          \  }
}}}|                     |          }|                     |
          }| 	                    |	          D ]}|||||fV  | 
                    |	          D ]}|||||fV  ||	j        z  }||k     d S d S )Nr   r   r   log_next_idx)object_typer   r   )r@   r   r   r   objectr   r|   r   r   r   r   )rE   r   r   r   r   r   cur_idxend_idxr   r   rz   r{   	timestamprx   r   r   r   s                    r!   rN   zKmsg_3_5_to_3_11.run"  s      l55i@@l55mDDDL;;OLLMM4<::>JJKK3355<''"GG!G$w.J,%%/*%UUCw!|| &59__S5I5I2%F //66	#55h?? ..s33 K KD&	9fdJJJJJ //44 K KD&	9fdJJJJJ37"' r    )r   r   r   r   r   r   rJ   r   r   r   r   r   r   r   r	   rN   r   r    r!   r   r      s          
t 
 
 
 [
  9 9 9 9 9)Ic4o$> ) ) ) )
'YsD$%? ' ' ' '.#XeCc3$;<= .# .# .# .# .# .#r    r   c                   4    e Zd ZdZedefd            Zd ZdS )Kmsg_3_11_to_5_10zStarting from version 3.11, the struct 'log' was renamed to 'printk_log'.
    While 'log_buf' is declared as a pointer and '__log_buf' as a char array,
    it essentially holds an array of 'printk_log' structs.
    rG   c                 ,    |                     d          S N
printk_log)r   rX   s     r!   rJ   zKmsg_3_11_to_5_10.symtab_checksY  s    ---r    c                     dS r   r   rU   s    r!   r   z&Kmsg_3_11_to_5_10._get_log_struct_name]  s    |r    N)r   r   r   r   r   r   rJ   r   r   r    r!   r   r   S  sT         
 .t . . . [.    r    r   c                       e Zd ZdZedefd            ZdefdZde	eddf         fdZ
de	eddf         fdZdeeeeeeef                  fdZdS )	Kmsg_5_10_to_a\  In 5.10 the kernel ring buffer implementation changed.
    Previously only one process should read /proc/kmsg and it is permanently
    open and periodically read by the syslog daemon.
    A high level structure 'printk_ringbuffer' was added to represent the printk
    ring buffer which actually contains two ring buffers. The descriptor ring
    'desc_ring' contains the records' metadata, text offsets and states.
    The data block ring 'text_data_ring' contains the records' text strings.
    A pointer to the high level structure is kept in the prb pointer which is
    initialized to a static ring buffer.

    .. code-block:: c

        static struct printk_ringbuffer *prb = &printk_rb_static;

    In SMP systems with more than 64 CPUs this ring buffer size is dynamically
    allocated according the number of CPUs based on the value of
    CONFIG_LOG_CPU_MAX_BUF_SHIFT. The prb pointer is updated consequently to
    this dynamic ring buffer in setup_log_buf().

    .. code-block:: c

        prb = &printk_rb_dynamic;

    Behind scenes, 'log_buf' is still used as external buffer.
    When the static 'printk_ringbuffer' struct is initialized, _DEFINE_PRINTKRB
    sets text_data_ring.data pointer to the address in 'log_buf' which points
    to the static buffer '__log_buf'.
    If a dynamic ring buffer takes place, setup_log_buf() sets
    text_data_ring.data of 'printk_rb_dynamic' to the new allocated external
    buffer via the 'prb_init' function.
    In that case, the original external static buffer in '__log_buf' and
    'printk_rb_static' are unused.

    .. code-block:: c

        new_log_buf = memblock_alloc(new_log_buf_len, LOG_ALIGN);
        prb_init(&printk_rb_dynamic, new_log_buf, ...);
        log_buf = new_log_buf;
        prb = &printk_rb_dynamic;

    See printk.c and printk_ringbuffer.c in kernel/printk/ folder for more
    details.
    rG   c                 ,    |                     d          S )Nprb)r   rX   s     r!   rJ   zKmsg_5_10_to_.symtab_checks  s    !!%(((r    c                     |j         }d|z  }|j        j        |z  }|j        j        |z  }|dz  rdS ||k    rd}| j        }||z   }	|j        |	z   }
t          |j        ||z
            }|                     |
|          S )Nr    r   )		size_bitstext_blk_lposbeginnextrD   dataminr   rd   )rE   text_data_ringdescr+   text_data_sztext_data_maskr   enddesc_id_size
text_startr   r   s               r!   get_text_from_data_ringz%Kmsg_5_10_to_.get_text_from_data_ring  s    %/l*"(>9 %6 19 	2 3;;E 2\)
$z1 t}cEk22vx000r    Nc              #   l   K   |                      |||          }|                                E d {V  d S ri   )r   r   )rE   r   r   r+   r   s        r!   r   zKmsg_5_10_to_.get_log_lines  sE      ++ND$GG??$$$$$$$$$$$r    c              #      K   t          j        |j        j                  }|rd| V  t          j        |j        j                  }|r	d| V  d S d S )Nz SUBSYSTEM=z DEVICE=)r   array_to_stringdev_info	subsystemdevice)rE   r+   	dict_texts      r!   r   zKmsg_5_10_to_.get_dict_lines  sx      +DM,CDD	 	,+	++++++DM,@AA	 	)(Y(((((((	) 	)r    c              #     K   | j                             d                                          }|j        }|j        }d|j        z  }| j         j        t          j        z   dz   }| j	        
                    ||j        | j                             d          || j                  }| j	        
                    ||j        | j                             d          || j                  }| j        }|dz  }	|	dz
  }
d	|
z  }| }|j        j        }d }||k    r|j        j        }|||z           }|||z           }t'          |j        j        |
z	  d	z            }|t&          j        t&          j        fv r|                     |          \  }}}}|                     |          }|                     |          }|                     |||          D ]}|||||fV  |                     |          D ]}|||||fV  |dz  }||z  }||k    d S d S )
Nr   r   arrayprb_desc)r   subtyper   rA   printk_info   r   r   )r@   r   dereference	desc_ringr   
count_bitssymbol_table_namer   BANGr=   r   descsrB   rA   infosrD   tail_idcounterhead_idr   	state_varr   r   r|   r   r   r   r   )rE   ringbuffersr   r   
desc_count
array_typedesc_arrinfo_arrdesc_state_var_bytes_szdesc_state_var_bits_szdesc_flags_shiftdesc_flags_maskdesc_id_maskcur_idend_idr   r+   
desc_staterz   r{   r   rx   r   r   r   s                            r!   rN   zKmsg_5_10_to_.run  sr     l55e<<HHJJ)	$3)..
\3inDwN
=''?L))*55 ( 
 
 =''?L))-88 ( 
 
 #'"=!81!<1A5//''"*&.FFZ/0DFZ/0D&(>BR(RVW'WXXJ,,   6:__T5J5J2%F //66	#55h?? ..~tTJJ K KD&	9fdJJJJJ //55 K KD&	9fdJJJJJaKFl"F' r    )r   r   r   r   r   r   rJ   r   r   r   r   r   r   r	   rN   r   r    r!   r   r   a  s        * *X )t ) ) ) [)1S 1 1 1 14%9S$PT_;U % % % %)iT4&@ ) ) ) )6#XeCc3$;<= 6# 6# 6# 6# 6# 6#r    r   c            
           e Zd ZdZdZdZedeej	        j
                 fd            Zdeeeeeeeeef         f                  fdZd ZdS )	Kmsgr$   )r      r   )r   r   r   rG   c                 6    t          j        ddg d          gS )Nr<   zLinux kernel)Intel32Intel64AArch64)namedescriptionarchitectures)r   ModuleRequirement)rP   s    r!   get_requirementszKmsg.get_requirements  s2     **???  
 	
r    c              #   h   K   t                               | j        | j                  D ]}d|fV  	d S )NrI   r   )r#   rS   r9   r:   )rE   valuess     r!   
_generatorzKmsg._generator  sF      oodl4;oOO 	 	Ff+	 	r    c                 
   | j         j                            dd           st          j        d          t          j        dt          fdt          fdt          fdt          fdt          fg|                                           S )	N
dwarf2jsonc                     |  p| dk    S )N)r      r   r   )version_s     r!   <lambda>zKmsg.run.<locals>.<lambda>	  s    'k-Qg	>Q r    zmInvalid symbol table, please ensure the ISF table produced by dwarf2json was produced using a version > 0.4.1rz   r{   r   rx   r   )	r9   symbol_spaceverify_table_versionsr   SymbolSpaceErrorr   TreeGridr   r  rU   s    r!   rN   zKmsg.run  s    |(>>QQ
 
 	 -   !S!#c"3 OO	
 	
 		
r    N)r   r   r   r   _required_framework_version_versionr   r   r   r   RequirementInterfacer  r   r	   r   r   r  rN   r   r    r!   r  r    s        """+H
j&>&S!T 
 
 
 [
HU3c3S#6M0N+N%OP    
 
 
 
 
r    r  )"r   loggingabcr   r   enumr   typingr   r   r   r	   volatility3.frameworkr
   r   r   r   r   #volatility3.framework.configurationr   volatility3.framework.objectsr   	getLoggerr   rK   r   r#   r   r   r   r   pluginsPluginInterfacer  r   r    r!   <module>r5     s@   
			  # # # # # # # #       3 3 3 3 3 3 3 3 3 3 3 3              = < < < < < 1 1 1 1 1 1		8	$	$    D   d! d! d! d! d!c d! d! d!N1G 1G 1G 1G 1G7 1G 1G 1GhV# V# V# V# V#w V# V# V#r    (   N# N# N# N# N#G N# N# N#b&
 &
 &
 &
 &
:- &
 &
 &
 &
 &
r    