
    vf*P                     b   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!y)    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y)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Mr    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y)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                  j                  d      j                  | _        y )Nkernelpointer)_context_configmodulesvmlinux
layer_nameget_typesizelong_unsigned_int_size)selfr9   r:   s      r!   __init__zABCKmsg.__init__<   sY    
  t||H'=>,,11&*ll&;&;I&F&K&K#r    returnc              #     K   |j                   |d      }d}t        |       D ]  }|j                  |      s0t        j	                  t
        j                  d|j                         Et        j	                  t
        j                  d|j                          |||      }|j                         E d{     n |t        j                  d       yy7  w)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)rA   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:   rA   	kmsg_instsubclasss         r!   run_allzABCKmsg.run_allG   s       //&"23	(- 	H))'):

++M%%
 JJ''3!!
 !@I }}&& %	( LLHI  's   B1C3C4!Cc                      y)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   rF   s    r!   rO   zABCKmsg.runq       r    rA   c                      y)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   rQ   rA   s     r!   rK   zABCKmsg.symtab_checks~   rW   r    addrlengthc                     | j                   j                  | j                     j                  ||      }|j	                  dd      S )Nutf8replace)encodingerrors)r>   layersrB   readdecode)rF   rZ   r[   txts       r!   
get_stringzABCKmsg.get_string   s:    mm""4??388vFzz6)z<<r    nsecc                 "    d|dz  |dz  dz  fz  S )Nz	%lu.%06lui ʚ;i  r   )rF   rf   s     r!   nsec_to_sec_strzABCKmsg.nsec_to_sec_str   s#     dZ/$2Ct1KLLLr    c                 8    | j                  |j                        S N)rh   ts_nsecrF   objs     r!   get_timestamp_in_sec_strz ABCKmsg.get_timestamp_in_sec_str   s    ##CKK00r    c                     |j                  d      r| j                  |j                        S t        j                         S )N	caller_id)
has_memberget_caller_textrp   r   NotAvailableValuerl   s     r!   
get_callerzABCKmsg.get_caller   s4     >>+&''66..00r    c                 ,    |dz  rdnd}d||dz  fz  }|S )Nl        CPUTaskz%s(%u)l    r   )rF   rp   caller_namecallers       r!   rr   zABCKmsg.get_caller_text   s)    (:5e6[)k*ABBr    c                 r    |j                   |j                  | j                  |      | j                  |      fS rj   )facilitylevelrn   rt   rl   s     r!   
get_prefixzABCKmsg.get_prefix   s6     LLII))#.OOC 	
 	
r    r|   c                     |t        | j                        k  r| j                  |   S t        j                  d| d       t	        |      S )NzLevel  unknown)lenLEVELSrL   r,   str)rQ   r|   s     r!   get_level_textzABCKmsg.get_level_text   s@    3szz?"::e$$LL6%12u:r    r{   c                     |t        | j                        k  r| j                  |   S t        j                  d| d       t	        |      S )Nz	Facility r   )r   
FACILITIESrL   r,   r   )rQ   r{   s     r!   get_facility_textzABCKmsg.get_facility_text   sA    c#..))>>(++LL9XJh78x= r    N)r   r   r   __doc__r   r   r   r9   ContextInterfaceconfigurationHierarchicalDictrG   classmethodr   r	   r   rT   r   rO   ModuleInterfaceboolrK   intre   rh   rn   rt   rr   r}   r   r   r   r    r!   r#   r#      s   "	FJ	L##44	L ((99	L 'J##44'J ((99'J 
%S#sC/0	1	'J 'JR 
XeCc3$;<= 
 
 J$6$6$F$F 4   =s =C =C =
MC 
MC 
M1s 11

sCc'9!: 
 3 3   ! ! ! !r    r#   c                   H    e Zd ZdZedefd       Zdeee	e	e	e	e	f      fdZ
y)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...

    rH   c                     |j                  d      xrH |j                  d       xr4 |j                  d      xr  |j                  d      j                  d       S )Nlog_endlog_first_idxrM   rk   )
has_symbolhas_typerC   rq   rY   s     r!   rK   zKmsg_pre_3_5.symtab_checks   sf     y) &&77   ' B$$U+66yA	
r    c              #   D  K   | j                   j                  d      }| j                   j                  d      }t        j                  ||      }| j                   j                  d      }||kD  r||z
  }||d  }|d | }||z   }|j	                         }|D ]  }	t        j                  d|	      }
|
s|
j                         \  }}}t        |      }|dz  }|dz	  }| j                  |      }| j                  |      }t        j                         }|||||f  y w)	Nlog_buf)symbol_namelog_buf_len)countr   z <(\d+)>\[\s*(\d+\.\d+)\]\s(.*?)$   r   )rA   object_from_symbolr   pointer_to_string
splitlinesrematchgroupsr   r   r   r   rs   )rF   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|   r{   	level_txtfacility_txtry   s                       r!   rO   zKmsg_pre_3_5.run   s8    ll55)5Lll55-5P++K{K,,11i1H[ k)E J!&5/K ;.G**,) 	GL<lKA 67hhj3t !34N"Q&E%*H++E2I11(;L002F	=&$FF!	Gs   DD N)r   r   r   r   r   r   rK   r   r	   r   rO   r   r    r!   r   r      sE     
t 
 
GXeCc3$;<= 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y)
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.
    rH   c                     |j                  d      xr3 |j                  d      j                  d      xr |j                  d      S )NrM   rk   r   )r   rC   rq   r   rY   s     r!   rK   zKmsg_3_5_to_3_11.symtab_checks   sH     U# 4  '229=4""?3	
r    c                      y)NrM   r   rV   s    r!   _get_log_struct_namez%Kmsg_3_5_to_3_11._get_log_struct_name  s    r    c                     | j                         }| j                  j                  |      j                  }|j                  j
                  |z   }| j                  ||j                        S rj   )r   rA   rC   rD   voloffsetre   text_len)rF   msglog_struct_namelog_struct_size
msg_offsets        r!   get_text_from_logz"Kmsg_3_5_to_3_11.get_text_from_log
  sQ    335,,//@EEWW^^o5
z3<<88r    Nc              #      K   |j                   dkD  r*| j                  |      }|j                         E d {    y y 7 w)Nr   )r   r   r   )rF   r   texts      r!   get_log_lineszKmsg_3_5_to_3_11.get_log_lines  s:     <<!))#.D((( (s   4?=?c              #     K   |j                   dk(  ry | j                         }| j                  j                  |      j                  }|j
                  j                  |z   |j                  z   }| j                  j                  | j                     j                  ||j                         }|j                  d      D ]  }d|j                         z     y w)Nr        )dict_lenr   rA   rC   rD   r   r   r   r>   ra   rB   rb   splitrc   )rF   r   r   r   dict_offset	dict_datachunks          r!   get_dict_lineszKmsg_3_5_to_3_11.get_dict_lines  s     <<1335,,//@EEggnn6EMM((9>>
	 __W- 	'E&&	's   CCc              #     K   | j                   j                  d      }| j                   j                  d      }t        | j                   j                  d            }t        | j                   j                  d            }| j                         }|}||k  r|}n|}||k  r||z   }| j                   j	                  ||      }	|	j
                  dk(  rd}|}n| j                  |	      \  }
}}}| j                  |      }| j                  |
      }| j                  |	      D ]  }|||||f  | j                  |	      D ]  }|||||f  ||	j
                  z  }||k  ry y w)Nr   r   r   log_next_idx)object_typer   r   )rA   r   r   r   objectr   r}   r   r   r   r   )rF   r   r   r   r   r   cur_idxend_idxr   r   r{   r|   	timestampry   r   r   r   s                    r!   rO   zKmsg_3_5_to_3_11.run"  st     ll55i@ll55mDDLL;;OLM4<<::>JK335<'"G!G$w.J,,%%/*%UCww!| &59__S5I2%F //6	#55h? ..s3 KD&	9fdJJK //4 KD&	9fdJJK 377"' s   E E%#E%)r   r   r   r   r   r   rK   r   r   r   r   r   r   r   r	   rO   r   r    r!   r   r      s     
t 
 
9 9)Ic4o$> )
'YsD$%? '.#XeCc3$;<= .#r    r   c                   ,    e Zd ZdZedefd       Zd Zy)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.
    rH   c                 $    |j                  d      S N
printk_log)r   rY   s     r!   rK   zKmsg_3_11_to_5_10.symtab_checksY  s    --r    c                      yr   r   rV   s    r!   r   z&Kmsg_3_11_to_5_10._get_log_struct_name]  s    r    N)r   r   r   r   r   r   rK   r   r   r    r!   r   r   S  s'    
 .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y)	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.
    rH   c                 $    |j                  d      S )Nprb)r   rY   s     r!   rK   zKmsg_5_10_to_.symtab_checks  s    !!%((r    c                 8   |j                   }d|z  }|j                  j                  |z  }|j                  j                  |z  }|dz  ry||kD  rd}| j                  }||z   }	|j
                  |	z   }
t        |j                  ||z
        }| j                  |
|      S )Nr    r   )		size_bitstext_blk_lposbeginnextrE   dataminr   re   )rF   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 3;E 22\)
$$z1 t}}cEk2vx00r    Nc              #   f   K   | j                  |||      }|j                         E d {    y 7 wrj   )r   r   )rF   r   r   r+   r   s        r!   r   zKmsg_5_10_to_.get_log_lines  s*     ++ND$G??$$$s   '1/1c              #      K   t        j                  |j                  j                        }|rd|  t        j                  |j                  j                        }|rd|  y y w)Nz SUBSYSTEM=z DEVICE=)r   array_to_stringdev_info	subsystemdevice)rF   r+   	dict_texts      r!   r   zKmsg_5_10_to_.get_dict_lines  s_     ++DMM,C,CD		{++++DMM,@,@A	YK(( s   A'A)c              #     K   | j                   j                  d      j                         }|j                  }|j                  }d|j
                  z  }| j                   j                  t        j                  z   dz   }| j                  j                  ||j                  | j                   j                  d      || j                        }| j                  j                  ||j                  | j                   j                  d      || j                        }| j                  }|dz  }	|	dz
  }
d	|
z  }| }|j                   j"                  }d }||k7  r|j$                  j"                  }|||z     }|||z     }t'        |j(                  j"                  |
z	  d	z        }|t&        j*                  t&        j,                  fv rx| j/                  |      \  }}}}| j1                  |      }| j3                  |      }| j5                  |||      D ]  }|||||f  | j7                  |      D ]  }|||||f  |dz  }||z  }||k7  ry y w)
Nr   r   arrayprb_desc)r   subtyper   rB   printk_info   r   r   )rA   r   dereference	desc_ringr   
count_bitssymbol_table_namer   BANGr>   r   descsrC   rB   infosrE   tail_idcounterhead_idr   	state_varr   r   r}   r   r   r   r   )rF   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_stater{   r|   r   ry   r   r   r   s                            r!   rO   zKmsg_5_10_to_.run  s_    ll55e<HHJ))	$33)...
\\33innDwN
==''??LL))*5 ( 
 ==''??LL))-8 ( 
 #'"="=!81!<1A5//''""**&&..FFZ/0DFZ/0D&(>(>BR(RVW'WXJ,,,,  6:__T5J2%F //6	#55h? ..~tTJ KD&	9fdJJK //5 KD&	9fdJJK aKFl"F' s   II	I	)r   r   r   r   r   r   rK   r   r   r   r   r   r   r	   rO   r   r    r!   r   r   a  s    *X )t ) )1S 14%9S$PT_;U %)iT4&@ )6#XeCc3$;<= 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y)	Kmsgr$   )r      r   )r   r   r   rH   c                 8    t        j                  ddg d      gS )Nr<   zLinux kernel)Intel32Intel64AArch64)namedescriptionarchitectures)r   ModuleRequirement)rQ   s    r!   get_requirementszKmsg.get_requirements  s%     ***?
 	
r    c              #   x   K   t         j                  | j                  | j                        D ]  }d|f 
 y w)NrJ   r   )r#   rT   r9   r:   )rF   valuess     r!   
_generatorzKmsg._generator  s4     oodll4;;oO 	Ff+	s   8:c                    | j                   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| j                               S )	N
dwarf2jsonc                     |  xs | dkD  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.1r{   r|   r   ry   r   )	r9   symbol_spaceverify_table_versionsr   SymbolSpaceErrorr   TreeGridr   r  rV   s    r!   rO   zKmsg.run  s    ||((>>Q
 --  !!S!#c"3 OO	
 		
r    N)r   r   r   r   _required_framework_version_versionr   r   r   r   RequirementInterfacer  r   r	   r   r   r  rO   r   r    r!   r  r    sj    ""+H
j&>&>&S&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   rL   r   r#   r   r   r   r   pluginsPluginInterfacer  r   r    r!   <module>r6     s    
  #  3 3  = 1			8	$D d!c d!N1G7 1GhV#w V#r( N#G N#b&
:-- &
r    