o
    jO                     @   sb   d dl mZmZ d dlmZ d dlmZ d dlmZ G dd dZ	G dd dZ
G d	d
 d
ZdS )    )ABCabstractmethod)logger)hexdump)RTL_AVL_TABLEc                   @   s&   e Zd Zdd Zdd Zd	ddZdS )
Loggerc                 C   s   || _ || _|| _t| _d S N)package_namemodule_namesysinfor   )selfr
   r	   r    r   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/pypykatz/lsadecryptor/package_commons.py__init__   s   
zLogger.__init__c                 C   s
   | j  S r   )r   getEffectiveLevel)r   r   r   r   	get_level   s   
zLogger.get_level   c                 C   s^   d}| dD ]%}|dkr| j|d| j| j|f  d}q| j|d| j| j|f  qd S )NT
z[%s] [%s] %sFz[%s] [%s]    %s)splitr   logr	   r
   )r   msgloglevelfirstliner   r   r   r      s   z
Logger.logN)r   )__name__
__module____qualname__r   r   r   r   r   r   r   r      s    r   c                   @   s:   e Zd ZdddZdddZdddZeed	d
 ZdS )PackageTemplateNc                 C   s   t d||| _|| _|| _d S )Ntemplate)r   r   r	   r   )r   r	   r   r   r   r   r       s   
zPackageTemplate.__init__   c                 C   s   | j |d|  d S Nz%sr   r   r   r   r   r   r   r   r   %      zPackageTemplate.logc                 C   s   | j d||jf | dS )zW"
		Generic logging function to show which template was selected for which structure
		zSelecting template for %s: %sN)r   r   r   )r   struct_var_namestruct_template_objr   r   r   r   log_template(   s   zPackageTemplate.log_templatec                 C   s   d S r   r   )r   r   r   r   get_template/   s   zPackageTemplate.get_templater   r   )	r   r   r   r   r   r&   staticmethodr   r'   r   r   r   r   r      s    


r   c                   @   sN   e Zd Zdd ZdddZdddZdd	d
ZdddZdd ZdddZ	dS )PackageDecryptorc                 C   s*   t d||| _|| _|| _|| _|| _d S )N	decryptor)r   r   r	   lsa_decryptorr   reader)r   r	   r,   r   r-   r   r   r   r   6   s
   
zPackageDecryptor.__init__r   c                 C   s   | j d| | d S r    r!   r"   r   r   r   r   =   r#   zPackageDecryptor.logNc                 C   sT   |  d |du r| jj}| jj||dd}t|dkr&td|| f |d S )zN
		Searches for a sequence of bytes in the module identified by module_name
		z"Searching for key struct signatureNT)
find_firstr   z2Signature was not found in module %s Signature: %s)r   decryptor_template	signaturer-   find_in_modulelen	Exceptionhex)r   r
   r0   flr   r   r   find_signature@   s   
zPackageDecryptor.find_signaturec              
   C   s   | j  }|dks|dkrdS |s/|dkrd}|dkrd}|dkr#d	}|d
kr)d}|dkr/d}| j }z%| j| | j|}| j| | d|t|t||df  W dS  t	yw } z| d|t|f  W Y d}~dS d}~ww )z
		Reads datasize bytes from the memory region pointed by the pointer.
		ptr = the pointer to be read
		name = display name for the memory structure, usually the data structure's name the pointer is pointing at
		r   r   N                P         r   i   z	%s: %s
%s)startz"%s: Logging failed for position %s)
r   r   r-   tellmovepeekr   r4   r   r3   )r   ptrnamedatasizelevelposdataer   r   r   log_ptrL   s0   

&$zPackageDecryptor.log_ptrFT   c                 C   s   d}| j j||d}|rVt|dkrV|dkrTz|d}W n)   z|d}W n   z|d}W n   | }Y Y Y ||fS Y ||fS |dkrP|d	}||fS |}||fS )
a  
		Common decryption method for LSA encrypted passwords. Result be string or hex encoded bytes (for machine accounts).
		Also supports bad data, as orphaned credentials may contain actual password OR garbage
		
		enc_password: bytes The encrypted password bytes
		bytes_expected: bool :indication that the result of decryption is bytes, no need for encoding
		trim_zeroes: bool: if a text is expected then this variable tells wether we should trim the trailing zeroes after decryption
		N)segment_sizer   Fz	utf-16-lezutf-8asciiT )r,   decryptr2   decoder4   rstrip)r   enc_passwordbytes_expectedtrim_zeroesrL   dec_passwordtempr   r   r   decrypt_passwordk   s.   


z!PackageDecryptor.decrypt_passwordc                 C   s   |j | jtd}|du r| d dS |jjdkr@||jj |jjjdkr/| 	|jj| |jj
jdkrB| 	|jj
| dS dS dS )z
		Walks the AVL tree, extracts all OrderedPointer values and returns them in a list
		node_ptr: POINTER : the Parent->RightChild pointer in the AVL tree
		result_ptr_list: list: the list to store the results in
		)override_finaltypeNzAVL walker found empty treer   )readr-   r   r   OrderedPointervalueappendBalancedRoot	LeftChildwalk_avl
RightChild)r   node_ptrresult_ptr_listnoder   r   r   r_      s   
zPackageDecryptor.walk_avl   c              
   C   sv  i }d||j < |}| |j|sd|jj n|j 	 z|r%|| j|}n|| j}W n tyF } z| d|  W Y d}~dS d}~ww |sKdS || |d8 }| d|s]|j	jjn|j|j	jf  | d|sp|j	jjn|j|j	j|vf  | d|s|j	jjn|j|f  |j	jd	kr|j	j|vr|d	krd||j	j< | |j	j|sd
|j	jj n|j |j	}ndS q)a1  
		Iterating over a linked list. Linked lists in packages are circural, so the end of the list is tested is the Flink is pointing to an address already seen.
		
		entry_ptr = pointer type object the will yiled the first entry when called read()
		callback = function that will be called when a new entry is found. callback method will be invoked with one parameter, the entry itself
		
		max_walk = limit the amount of entries to be iterating
		override_ptr = if this parameter is set the pointer will be resolved as if it would be pointing to this structure
		r   zList entry -%s-Tz&Exception while reading list entry: %sNz%s next ptr: %xz%s seen: %sz%s max_walk: %dr   zNext list entry -%s-)
locationrJ   r[   	finaltyper   rY   r-   r3   r   Flink)r   	entry_ptrcallbackmax_walkoverride_ptrentries_seenentryrI   r   r   r   	walk_list   s8   
 &*" $zPackageDecryptor.walk_listr(   r   )FTrK   )rd   N)
r   r   r   r   r   r6   rJ   rW   r_   rn   r   r   r   r   r*   5   s    



!r*   N)abcr   r   pypykatzr   pypykatz.commons.commonr   pypykatz.commons.win_datatypesr   r   r   r*   r   r   r   r   <module>   s   